commit cfa8d5302557a512ac2d4e22ae647e232836b27c Author: SirSengir Date: Fri May 2 21:31:20 2014 +0200 Initial commit for GitHub. diff --git a/CLA.txt b/CLA.txt new file mode 100755 index 000000000..bb165405b --- /dev/null +++ b/CLA.txt @@ -0,0 +1,11 @@ +FORESTRY INDIVIDUAL CONTRIBUTOR LICENSE AGREEMENT + Thank you for your interest in contributing to Forestry ("We" or "Us"). + This contributor agreement ("Agreement") documents the rights granted by contributors to Us. To make this document effective, please sign it and send it to Us by electronic submission using CLAHub (http://www.clahub.com/). This is a legally binding document, so please read it carefully before agreeing to it. The Agreement may cover more than one software project managed by Us. 1. Definitions "You" means the individual who Submits a Contribution to Us. "Contribution" means any work of authorship that is Submitted by You to Us in which You own or assert ownership of the Copyright. "Copyright" means all rights protecting works of authorship owned or controlled by You, including copyright, moral and neighboring rights, as appropriate, for the full term of their existence including any extensions by You. "Material" means the work of authorship which is made available by Us to third parties. When this Agreement covers more than one software project, the Material means the work of authorship to which the Contribution was Submitted. After You Submit the Contribution, it may be included in the Material. "Submit" means any form of electronic, verbal, or written communication sent to Us or our representatives, including but not limited to electronic mailing lists, source code control systems, and issue tracking systems that are managed by, or on behalf of, Us for the purpose of discussing and improving the Material, but excluding communication that is conspicuously marked or otherwise designated in writing by You as "Not a Contribution." "Submission Date" means the date on which You Submit a Contribution to Us. "Effective Date" means the date You execute this Agreement or the date You first Submit a Contribution to Us, whichever is earlier. "Media" means any portion of a Contribution which is not software. 2. Grant of Rights 2.1 Copyright License (a) You retain ownership of the Copyright in Your Contribution and have the same rights to use or license the Contribution which You would have had without entering into the Agreement. (b) To the maximum extent permitted by the relevant law, You grant to Us a perpetual, worldwide, non-exclusive, transferable, royalty-free, irrevocable license under the Copyright covering the Contribution, with the right to sublicense such rights through multiple tiers of sublicensees, to reproduce, modify, display, perform and distribute the Contribution as part of the Material; provided that this license is conditioned upon compliance with Section 2.3. 2.2 Patent License For patent claims including, without limitation, method, process, and apparatus claims which You own, control or have the right to grant, now or in the future, You grant to Us a perpetual, worldwide, non-exclusive, transferable, royalty-free, irrevocable patent license, with the right to sublicense these rights to multiple tiers of sublicensees, to make, have made, use, sell, offer for sale, import and otherwise transfer the Contribution and the Contribution in combination with the Material (and portions of such combination). This license is granted only to the extent that the exercise of the licensed rights infringes such patent claims; and provided that this license is conditioned upon compliance with Section 2.3. 2.3 Outbound License Based on the grant of rights in Sections 2.1 and 2.2, if We include Your Contribution in a Material, We may license the Contribution under any license, including copyleft, permissive, commercial, or proprietary licenses. + 2.4 Moral Rights. + +If moral rights apply to the Contribution, to the maximum extent permitted by law, You waive and agree not to assert such moral rights against Us or our successors in interest, or any of our licensees, either direct or indirect. 2.5 Our Rights. + +You acknowledge that We are not obligated to use Your Contribution as part of the Material and may decide to include any Contribution We consider appropriate. 2.6 Reservation of Rights. + +Any rights not expressly assigned or licensed under this section are expressly reserved by You. 3. Agreement You confirm that: (a) You have the legal authority to enter into this Agreement. (b) You own the Copyright and patent claims covering the Contribution which are required to grant the rights under Section 2. (c) The grant of rights under Section 2 does not violate any grant of rights which You have made to third parties, including Your employer. If You are an employee, You have had Your employer approve this Agreement. If You are less than eighteen years old, please have Your parents or guardian sign the Agreement. 4. Disclaimer EXCEPT FOR THE EXPRESS WARRANTIES IN SECTION 3, THE CONTRIBUTION IS PROVIDED "AS IS". MORE PARTICULARLY, ALL EXPRESS OR IMPLIED WARRANTIES INCLUDING, WITHOUT LIMITATION, ANY IMPLIED WARRANTY OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT ARE EXPRESSLY DISCLAIMED BY YOU TO US AND BY US TO YOU. TO THE EXTENT THAT ANY SUCH WARRANTIES CANNOT BE DISCLAIMED, SUCH WARRANTY IS LIMITED IN DURATION TO THE MINIMUM PERIOD PERMITTED BY LAW. + 5. Consequential Damage Waiver TO THE MAXIMUM EXTENT PERMITTED BY APPLICABLE LAW, IN NO EVENT WILL YOU OR US BE LIABLE FOR ANY LOSS OF PROFITS, LOSS OF ANTICIPATED SAVINGS, LOSS OF DATA, INDIRECT, SPECIAL, INCIDENTAL, CONSEQUENTIAL AND EXEMPLARY DAMAGES ARISING OUT OF THIS AGREEMENT REGARDLESS OF THE LEGAL OR EQUITABLE THEORY (CONTRACT, TORT OR OTHERWISE) UPON WHICH THE CLAIM IS BASED. 6. Miscellaneous 6.1 This Agreement will be governed by and construed in accordance with the laws of Germany excluding its conflicts of law provisions. Under certain circumstances, the governing law in this section might be superseded by the United Nations Convention on Contracts for the International Sale of Goods ("UN Convention") and the parties intend to avoid the application of the UN Convention to this Agreement and, thus, exclude the application of the UN Convention in its entirety to this Agreement. 6.2 This Agreement sets out the entire agreement between You and Us for Your Contributions to Us and overrides all other agreements or understandings. 6.3 If You or We assign the rights or obligations received through this Agreement to a third party, as a condition of the assignment, that third party must agree in writing to abide by all the rights and obligations in the Agreement. 6.4 The failure of either party to require performance by the other party of any provision of this Agreement in one situation shall not affect the right of a party to require such performance at any time in the future. A waiver of performance under a provision in one situation shall not be considered a waiver of the performance of the provision in the future or a waiver of the provision in its entirety. 6.5 If any provision of this Agreement is found void and unenforceable, such provision will be replaced to the extent possible with a provision that comes closest to the meaning of the original provision and which is enforceable. The terms and conditions set forth in this Agreement shall apply notwithstanding any failure of essential purpose of this Agreement or any limited remedy to the maximum extent possible under law. \ No newline at end of file diff --git a/CONTRIBUTING.md.txt b/CONTRIBUTING.md.txt new file mode 100755 index 000000000..a0ba3a665 --- /dev/null +++ b/CONTRIBUTING.md.txt @@ -0,0 +1,16 @@ +How to contribute to Forestry +==================================== + +### Contributor License Agreement + +Before pull requests can be accepted, the contributor needs to sign a contributor license agreement. (Essentially giving a license for using his code and/or media and for re-licensing it, for details read the agreement linked below.) + +### How do I sign? + +To keep the hassle for everyone involved to a minimum, Forestry uses CLAHub to manage the agreements. To get started, sign the Contributor License Agreement. + +### Why is this needed? + +Without CLAs it at some point becomes essentially impossible to change the license of a project which accepts contributions from third parties. Without an explicit agreement every contributor would still own the copyright to his code. So as long as it (or parts of it) remain in the code base, he would have to agree to every license change. If enough time has passed, there may be dozens, perhaps even hundreds of contributors involved and it will be very hard to track down each and every one of them and get them to agree on a new license. + +This would make it impossible to change the license to a more permissive one at a later date, so the code would be locked into CC BY-NC-ND 3.0 until it passes into the public domain about a hundred years from now. This situation is to be avoided and that’s why you are being bothered with this CLA. \ No newline at end of file diff --git a/LICENSE.txt b/LICENSE.txt new file mode 100755 index 000000000..f0bea231f --- /dev/null +++ b/LICENSE.txt @@ -0,0 +1,64 @@ +License (CC BY-NC-ND 3.0) + +THE WORK (AS DEFINED BELOW) IS PROVIDED UNDER THE TERMS OF THIS CREATIVE COMMONS PUBLIC LICENSE ("CCPL" OR "LICENSE"). THE WORK IS PROTECTED BY COPYRIGHT AND/OR OTHER APPLICABLE LAW. ANY USE OF THE WORK OTHER THAN AS AUTHORIZED UNDER THIS LICENSE OR COPYRIGHT LAW IS PROHIBITED. + +BY EXERCISING ANY RIGHTS TO THE WORK PROVIDED HERE, YOU ACCEPT AND AGREE TO BE BOUND BY THE TERMS OF THIS LICENSE. TO THE EXTENT THIS LICENSE MAY BE CONSIDERED TO BE A CONTRACT, THE LICENSOR GRANTS YOU THE RIGHTS CONTAINED HERE IN CONSIDERATION OF YOUR ACCEPTANCE OF SUCH TERMS AND CONDITIONS. + +1. Definitions + +"Adaptation" means a work based upon the Work, or upon the Work and other pre-existing works, such as a translation, adaptation, derivative work, arrangement of music or other alterations of a literary or artistic work, or phonogram or performance and includes cinematographic adaptations or any other form in which the Work may be recast, transformed, or adapted including in any form recognizably derived from the original, except that a work that constitutes a Collection will not be considered an Adaptation for the purpose of this License. For the avoidance of doubt, where the Work is a musical work, performance or phonogram, the synchronization of the Work in timed-relation with a moving image ("synching") will be considered an Adaptation for the purpose of this License. +"Collection" means a collection of literary or artistic works, such as encyclopedias and anthologies, or performances, phonograms or broadcasts, or other works or subject matter other than works listed in Section 1(f) below, which, by reason of the selection and arrangement of their contents, constitute intellectual creations, in which the Work is included in its entirety in unmodified form along with one or more other contributions, each constituting separate and independent works in themselves, which together are assembled into a collective whole. A work that constitutes a Collection will not be considered an Adaptation (as defined above) for the purposes of this License. +"Distribute" means to make available to the public the original and copies of the Work through sale or other transfer of ownership. +"Licensor" means the individual, individuals, entity or entities that offer(s) the Work under the terms of this License. +"Original Author" means, in the case of a literary or artistic work, the individual, individuals, entity or entities who created the Work or if no individual or entity can be identified, the publisher; and in addition (i) in the case of a performance the actors, singers, musicians, dancers, and other persons who act, sing, deliver, declaim, play in, interpret or otherwise perform literary or artistic works or expressions of folklore; (ii) in the case of a phonogram the producer being the person or legal entity who first fixes the sounds of a performance or other sounds; and, (iii) in the case of broadcasts, the organization that transmits the broadcast. +"Work" means the literary and/or artistic work offered under the terms of this License including without limitation any production in the literary, scientific and artistic domain, whatever may be the mode or form of its expression including digital form, such as a book, pamphlet and other writing; a lecture, address, sermon or other work of the same nature; a dramatic or dramatico-musical work; a choreographic work or entertainment in dumb show; a musical composition with or without words; a cinematographic work to which are assimilated works expressed by a process analogous to cinematography; a work of drawing, painting, architecture, sculpture, engraving or lithography; a photographic work to which are assimilated works expressed by a process analogous to photography; a work of applied art; an illustration, map, plan, sketch or three-dimensional work relative to geography, topography, architecture or science; a performance; a broadcast; a phonogram; a compilation of data to the extent it is protected as a copyrightable work; or a work performed by a variety or circus performer to the extent it is not otherwise considered a literary or artistic work. +"You" means an individual or entity exercising rights under this License who has not previously violated the terms of this License with respect to the Work, or who has received express permission from the Licensor to exercise rights under this License despite a previous violation. +"Publicly Perform" means to perform public recitations of the Work and to communicate to the public those public recitations, by any means or process, including by wire or wireless means or public digital performances; to make available to the public Works in such a way that members of the public may access these Works from a place and at a place individually chosen by them; to perform the Work to the public by any means or process and the communication to the public of the performances of the Work, including by public digital performance; to broadcast and rebroadcast the Work by any means including signs, sounds or images. +"Reproduce" means to make copies of the Work by any means including without limitation by sound or visual recordings and the right of fixation and reproducing fixations of the Work, including storage of a protected performance or phonogram in digital form or other electronic medium. + +2. Fair Dealing Rights. + +Nothing in this License is intended to reduce, limit, or restrict any uses free from copyright or rights arising from limitations or exceptions that are provided for in connection with the copyright protection under copyright law or other applicable laws. + +3. License Grant. + +Subject to the terms and conditions of this License, Licensor hereby grants You a worldwide, royalty-free, non-exclusive, perpetual (for the duration of the applicable copyright) license to exercise the rights in the Work as stated below: + +to Reproduce the Work, to incorporate the Work into one or more Collections, and to Reproduce the Work as incorporated in the Collections; and, +to Distribute and Publicly Perform the Work including as incorporated in Collections. +The above rights may be exercised in all media and formats whether now known or hereafter devised. The above rights include the right to make such modifications as are technically necessary to exercise the rights in other media and formats, but otherwise you have no rights to make Adaptations. Subject to 8(f), all rights not expressly granted by Licensor are hereby reserved, including but not limited to the rights set forth in Section 4(d). + +4. Restrictions. + +The license granted in Section 3 above is expressly made subject to and limited by the following restrictions: + +You may Distribute or Publicly Perform the Work only under the terms of this License. You must include a copy of, or the Uniform Resource Identifier (URI) for, this License with every copy of the Work You Distribute or Publicly Perform. You may not offer or impose any terms on the Work that restrict the terms of this License or the ability of the recipient of the Work to exercise the rights granted to that recipient under the terms of the License. You may not sublicense the Work. You must keep intact all notices that refer to this License and to the disclaimer of warranties with every copy of the Work You Distribute or Publicly Perform. When You Distribute or Publicly Perform the Work, You may not impose any effective technological measures on the Work that restrict the ability of a recipient of the Work from You to exercise the rights granted to that recipient under the terms of the License. This Section 4(a) applies to the Work as incorporated in a Collection, but this does not require the Collection apart from the Work itself to be made subject to the terms of this License. If You create a Collection, upon notice from any Licensor You must, to the extent practicable, remove from the Collection any credit as required by Section 4(c), as requested. +You may not exercise any of the rights granted to You in Section 3 above in any manner that is primarily intended for or directed toward commercial advantage or private monetary compensation. The exchange of the Work for other copyrighted works by means of digital file-sharing or otherwise shall not be considered to be intended for or directed toward commercial advantage or private monetary compensation, provided there is no payment of any monetary compensation in connection with the exchange of copyrighted works. +If You Distribute, or Publicly Perform the Work or Collections, You must, unless a request has been made pursuant to Section 4(a), keep intact all copyright notices for the Work and provide, reasonable to the medium or means You are utilizing: (i) the name of the Original Author (or pseudonym, if applicable) if supplied, and/or if the Original Author and/or Licensor designate another party or parties (e.g., a sponsor institute, publishing entity, journal) for attribution ("Attribution Parties") in Licensor's copyright notice, terms of service or by other reasonable means, the name of such party or parties; (ii) the title of the Work if supplied; (iii) to the extent reasonably practicable, the URI, if any, that Licensor specifies to be associated with the Work, unless such URI does not refer to the copyright notice or licensing information for the Work. The credit required by this Section 4(c) may be implemented in any reasonable manner; provided, however, that in the case of a Collection, at a minimum such credit will appear, if a credit for all contributing authors of Collection appears, then as part of these credits and in a manner at least as prominent as the credits for the other contributing authors. For the avoidance of doubt, You may only use the credit required by this Section for the purpose of attribution in the manner set out above and, by exercising Your rights under this License, You may not implicitly or explicitly assert or imply any connection with, sponsorship or endorsement by the Original Author, Licensor and/or Attribution Parties, as appropriate, of You or Your use of the Work, without the separate, express prior written permission of the Original Author, Licensor and/or Attribution Parties. +For the avoidance of doubt: + +Non-waivable Compulsory License Schemes. In those jurisdictions in which the right to collect royalties through any statutory or compulsory licensing scheme cannot be waived, the Licensor reserves the exclusive right to collect such royalties for any exercise by You of the rights granted under this License; +Waivable Compulsory License Schemes. In those jurisdictions in which the right to collect royalties through any statutory or compulsory licensing scheme can be waived, the Licensor reserves the exclusive right to collect such royalties for any exercise by You of the rights granted under this License if Your exercise of such rights is for a purpose or use which is otherwise than noncommercial as permitted under Section 4(b) and otherwise waives the right to collect royalties through any statutory or compulsory licensing scheme; and, +Voluntary License Schemes. The Licensor reserves the right to collect royalties, whether individually or, in the event that the Licensor is a member of a collecting society that administers voluntary licensing schemes, via that society, from any exercise by You of the rights granted under this License that is for a purpose or use which is otherwise than noncommercial as permitted under Section 4(b). +Except as otherwise agreed in writing by the Licensor or as may be otherwise permitted by applicable law, if You Reproduce, Distribute or Publicly Perform the Work either by itself or as part of any Collections, You must not distort, mutilate, modify or take other derogatory action in relation to the Work which would be prejudicial to the Original Author's honor or reputation. + +5. Representations, Warranties and Disclaimer + +UNLESS OTHERWISE MUTUALLY AGREED BY THE PARTIES IN WRITING, LICENSOR OFFERS THE WORK AS-IS AND MAKES NO REPRESENTATIONS OR WARRANTIES OF ANY KIND CONCERNING THE WORK, EXPRESS, IMPLIED, STATUTORY OR OTHERWISE, INCLUDING, WITHOUT LIMITATION, WARRANTIES OF TITLE, MERCHANTIBILITY, FITNESS FOR A PARTICULAR PURPOSE, NONINFRINGEMENT, OR THE ABSENCE OF LATENT OR OTHER DEFECTS, ACCURACY, OR THE PRESENCE OF ABSENCE OF ERRORS, WHETHER OR NOT DISCOVERABLE. SOME JURISDICTIONS DO NOT ALLOW THE EXCLUSION OF IMPLIED WARRANTIES, SO SUCH EXCLUSION MAY NOT APPLY TO YOU. + +6. Limitation on Liability. + +EXCEPT TO THE EXTENT REQUIRED BY APPLICABLE LAW, IN NO EVENT WILL LICENSOR BE LIABLE TO YOU ON ANY LEGAL THEORY FOR ANY SPECIAL, INCIDENTAL, CONSEQUENTIAL, PUNITIVE OR EXEMPLARY DAMAGES ARISING OUT OF THIS LICENSE OR THE USE OF THE WORK, EVEN IF LICENSOR HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGES. + +7. Termination + +This License and the rights granted hereunder will terminate automatically upon any breach by You of the terms of this License. Individuals or entities who have received Collections from You under this License, however, will not have their licenses terminated provided such individuals or entities remain in full compliance with those licenses. Sections 1, 2, 5, 6, 7, and 8 will survive any termination of this License. +Subject to the above terms and conditions, the license granted here is perpetual (for the duration of the applicable copyright in the Work). Notwithstanding the above, Licensor reserves the right to release the Work under different license terms or to stop distributing the Work at any time; provided, however that any such election will not serve to withdraw this License (or any other license that has been, or is required to be, granted under the terms of this License), and this License will continue in full force and effect unless terminated as stated above. + +8. Miscellaneous + +Each time You Distribute or Publicly Perform the Work or a Collection, the Licensor offers to the recipient a license to the Work on the same terms and conditions as the license granted to You under this License. +If any provision of this License is invalid or unenforceable under applicable law, it shall not affect the validity or enforceability of the remainder of the terms of this License, and without further action by the parties to this agreement, such provision shall be reformed to the minimum extent necessary to make such provision valid and enforceable. +No term or provision of this License shall be deemed waived and no breach consented to unless such waiver or consent shall be in writing and signed by the party to be charged with such waiver or consent. +This License constitutes the entire agreement between the parties with respect to the Work licensed here. There are no understandings, agreements or representations with respect to the Work not specified here. Licensor shall not be bound by any additional provisions that may appear in any communication from You. This License may not be modified without the mutual written agreement of the Licensor and You. +The rights granted under, and the subject matter referenced, in this License were drafted utilizing the terminology of the Berne Convention for the Protection of Literary and Artistic Works (as amended on September 28, 1979), the Rome Convention of 1961, the WIPO Copyright Treaty of 1996, the WIPO Performances and Phonograms Treaty of 1996 and the Universal Copyright Convention (as revised on July 24, 1971). These rights and subject matter take effect in the relevant jurisdiction in which the License terms are sought to be enforced according to the corresponding provisions of the implementation of those treaty provisions in the applicable national law. If the standard suite of rights granted under applicable copyright law includes additional rights not granted under this License, such additional rights are deemed to be included in the License; this License is not intended to restrict the license of any rights under applicable law. \ No newline at end of file diff --git a/README.md.txt b/README.md.txt new file mode 100755 index 000000000..4d818692f --- /dev/null +++ b/README.md.txt @@ -0,0 +1,28 @@ +Forestry +==================================== + +### What is it? + +Forestry is a modification for the game Minecraft and known primarily for its farms and bees. + +### Homepage + +[Wiki](http://forestry.sengir.net/) + +[Forums](http://forestry.sengir.net/forum/) + +[IRC #forestry on esper.net](http://webchat.esper.net/?nick=ForestryWiki...&channels=forestry&prompt=1) + +### Notes + +Beware of ugly code. + +The API resides in its own repository. You will need it to compile this code. + +Bugfixes are generally welcome. If you want to contribute something which changes game mechanics, please talk to someone with commit privileges first. Nothing is more frustrating than putting a lot of work and effort into a new game mechanic and then having the PR rejected because it doesn’t fit gameplay-wise. + +If you submit a PR you must accept the Contributor License Agreement. There is no way around that, since otherwise changing the license later - even to something more permissive! - , becomes close to impossible. + +### License & Copyright + +Forestry is (c) 2011 - 2014 SirSengir and licensed under CC BY-NC-ND 3.0. See the LICENSE.txt for all the gory details or go to http://creativecommons.org/licenses/by-nc-nd/3.0/ for more information. Forestry also contains code contributed by CovertJaguar, Player, MysteriousAges, Binnie, RichardG, cpw and others. \ No newline at end of file diff --git a/build.gradle b/build.gradle new file mode 100755 index 000000000..f503efbf7 --- /dev/null +++ b/build.gradle @@ -0,0 +1,123 @@ +buildscript { + repositories { + mavenCentral() + maven { + name = "forge" + url = "http://files.minecraftforge.net/maven" + } + maven { + name = "sonatype" + url = "https://oss.sonatype.org/content/repositories/snapshots/" + } + } + dependencies { + classpath 'net.minecraftforge.gradle:ForgeGradle:1.1-SNAPSHOT' + } +} + +apply plugin: 'forge' + +ext.buildnumber = createBuildNumber() +version = "2.4.0.0-" + buildnumber +group= "net.sengir.forestry" // http://maven.apache.org/guides/mini/guide-naming-conventions.html +archivesBaseName = "forestry" + +ext.langDir = "../Forestry-Localization" +ext.srcbcDir = "../BuildCraft/common" +ext.srcIc2Dir = "../IC2/src" +ext.srcCraftguideDir = "../CraftGuide/src" + +minecraft { + version = "1.7.2-10.12.0.1032" + assetDir = "eclipse/assets" + + replace '@VERSION@', project.version + replace '@BUILD_NUMBER@', project.buildnumber + replace '$___$', rndString() + replace '$____$', rndString() + replace '$_____$', rndString() + replace '$______$', rndString() + replace '$_______$', rndString() + replace '$________$', rndString() + replace '$_________$', rndString() + replace '$__________$', rndString() +} + +sourceSets { + api { + java { + srcDir project.srcCraftguideDir + include '**/CraftGuide/api/**' + } + } + + main { + java { + srcDirs file('forestry_common').listFiles() + include 'forestry/**' + + srcDir project.srcbcDir + include 'buildcraft/api/**' + + srcDir project.srcIc2Dir + include 'api/**' + } + resources { + srcDir 'forestry_resources' + srcDir project.langDir + } + } +} + +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 + from(sourceSets.main.resources.srcDirs) { + exclude 'mcmod.info' + exclude '**/*.md' + } +} + +task apiZip(type: Jar) { + from sourceSets.main.allSource + include 'forestry/api/**' + classifier = 'api' + extension = 'zip' +} + +task deobfJar(type: Jar) { + from sourceSets.main.output + classifier = 'dev' +} + +build.dependsOn apiZip, deobfJar + +def rndString() { + String AB = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz" + Random rnd = new Random() + String ret = "" + int max = rnd.nextInt(18) + 3 + + for (int i = 0; i < max; i++) { + ret += AB.charAt(rnd.nextInt(AB.length())) + } + + int rndStart = rnd.nextInt(6) + 2 + rndStart = rndStart >= ret.length() - 4 ? 3 : rndStart; + + return ret.substring(0, rndStart).toLowerCase(Locale.ENGLISH) + ret.substring(rndStart) +} + +def createBuildNumber() { + ant.buildnumber() + + return ant.antProject.properties['build.number'] +} + diff --git a/build.number b/build.number new file mode 100755 index 000000000..7103f44b6 --- /dev/null +++ b/build.number @@ -0,0 +1,3 @@ +#Build Number for ANT. Do not edit! +#Mon Mar 31 06:46:14 CEST 2014 +build.number=712 diff --git a/build.xml b/build.xml new file mode 100755 index 000000000..eda558604 --- /dev/null +++ b/build.xml @@ -0,0 +1,352 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/forestry_common/apiculture/forestry/apiculture/BeekeepingLogic.java b/forestry_common/apiculture/forestry/apiculture/BeekeepingLogic.java new file mode 100755 index 000000000..98f9bca69 --- /dev/null +++ b/forestry_common/apiculture/forestry/apiculture/BeekeepingLogic.java @@ -0,0 +1,325 @@ +/******************************************************************************* + * Copyright 2011-2014 by SirSengir + * + * This work is licensed under a Creative Commons Attribution-NonCommercial-NoDerivs 3.0 Unported License. + * + * To view a copy of this license, visit http://creativecommons.org/licenses/by-nc-nd/3.0/. + ******************************************************************************/ +package forestry.apiculture; + +import java.util.Stack; + +import net.minecraft.item.ItemStack; +import net.minecraft.nbt.NBTTagCompound; +import net.minecraft.nbt.NBTTagList; + +import forestry.api.apiculture.EnumBeeType; +import forestry.api.apiculture.IApiaristTracker; +import forestry.api.apiculture.IBee; +import forestry.api.apiculture.IBeeHousing; +import forestry.api.apiculture.IBeekeepingLogic; +import forestry.api.genetics.IEffectData; +import forestry.api.genetics.IIndividual; +import forestry.core.EnumErrorCode; +import forestry.core.config.Defaults; +import forestry.core.config.ForestryItem; +import forestry.core.proxy.Proxies; +import forestry.plugins.PluginApiculture; + +public class BeekeepingLogic implements IBeekeepingLogic { + + private static final int MAX_POLLINATION_ATTEMPTS = 20; + IBeeHousing housing; + // Breeding + private int breedingTime; + private final int totalBreedingTime = Defaults.APIARY_BREEDING_TIME; + private int throttle; + private IEffectData effectData[] = new IEffectData[2]; + private IBee queen; + private IIndividual pollen; + private int attemptedPollinations = 0; + private final Stack spawn = new Stack(); + + public BeekeepingLogic(IBeeHousing housing) { + this.housing = housing; + } + + // / SAVING & LOADING + @Override + public void readFromNBT(NBTTagCompound nbttagcompound) { + breedingTime = nbttagcompound.getInteger("BreedingTime"); + throttle = nbttagcompound.getInteger("Throttle"); + + NBTTagList nbttaglist = new NBTTagList(); + while (!spawn.isEmpty()) { + NBTTagCompound nbttagcompound1 = new NBTTagCompound(); + spawn.pop().writeToNBT(nbttagcompound1); + nbttaglist.appendTag(nbttagcompound1); + } + nbttagcompound.setTag("Offspring", nbttaglist); + + } + + @Override + public void writeToNBT(NBTTagCompound nbttagcompound) { + nbttagcompound.setInteger("BreedingTime", breedingTime); + nbttagcompound.setInteger("Throttle", throttle); + + NBTTagList nbttaglist = nbttagcompound.getTagList("Offspring", 10); + for (int i = 0; i < nbttaglist.tagCount(); i++) { + spawn.add(ItemStack.loadItemStackFromNBT(nbttaglist.getCompoundTagAt(i))); + } + + } + + // / STATE INFORMATION + @Override + public int getBreedingTime() { + return this.breedingTime; + } + + @Override + public int getTotalBreedingTime() { + return this.totalBreedingTime; + } + + @Override + public IBee getQueen() { + return this.queen; + } + + @Override + public IBeeHousing getHousing() { + return this.housing; + } + + @Override + public IEffectData[] getEffectData() { + return this.effectData; + } + + /* UPDATING */ + @Override + public void update() { + + resetQueen(null); + + // Still something to spawn, try it + while (!spawn.isEmpty()) { + ItemStack next = spawn.peek(); + if (housing.addProduct(next, true)) { + spawn.pop(); + housing.setErrorState(EnumErrorCode.OK.ordinal()); + } else + housing.setErrorState(EnumErrorCode.NOSPACE.ordinal()); + return; + } + + // No queen? And no princess? + if (housing.getQueen() == null) { + housing.setErrorState(EnumErrorCode.NOQUEEN.ordinal()); + return; + } + + // Princess available? Try to breed! + if (ForestryItem.beePrincessGE.isItemEqual(housing.getQueen())) { + if (ForestryItem.beeDroneGE.isItemEqual(housing.getDrone())) + housing.setErrorState(EnumErrorCode.NODRONE.ordinal()); + else + housing.setErrorState(EnumErrorCode.OK.ordinal()); + tickBreed(); + return; + } + + // Can't continue if an item of the wrong type is in the queen slot. + if (!ForestryItem.beeQueenGE.isItemEqual(housing.getQueen())) { + housing.setErrorState(EnumErrorCode.NOQUEEN.ordinal()); + return; + } + + IBee queen = PluginApiculture.beeInterface.getMember(housing.getQueen()); + // Kill dying queens + if (!queen.isAlive()) { + killQueen(queen); + housing.setErrorState(EnumErrorCode.OK.ordinal()); + return; + } + + resetQueen(queen); + + // Not while raining, at night or without light + EnumErrorCode state = EnumErrorCode.values()[queen.isWorking(housing)]; + if (state != EnumErrorCode.OK) { + housing.setErrorState(state.ordinal()); + return; + } else if (housing.getErrorOrdinal() != EnumErrorCode.NOFLOWER.ordinal()) + housing.setErrorState(EnumErrorCode.OK.ordinal()); + + // Effects only fire when queen can work. + effectData = queen.doEffect(effectData, housing); + + // We have a queen, work! + throttle++; + + if (throttle >= PluginApiculture.beeCycleTicks) + throttle = 0; + else + return; + + // Need a flower + if (!queen.hasFlower(housing)) { + housing.setErrorState(EnumErrorCode.NOFLOWER.ordinal()); + return; + } else + housing.setErrorState(EnumErrorCode.OK.ordinal()); + + // Produce and add stacks + ItemStack[] products = queen.produceStacks(housing); + housing.wearOutEquipment(1); + for (ItemStack stack : products) { + housing.addProduct(stack, false); + } + + // Plant a flower + queen.plantFlowerRandom(housing); + // Get pollen if none available yet + if (pollen == null) { + pollen = queen.retrievePollen(housing); + attemptedPollinations = 0; + if (pollen != null) { + if (housing.onPollenRetrieved(queen, pollen, false)) + pollen = null; + } + } + if (pollen != null) { + attemptedPollinations++; + if (queen.pollinateRandom(housing, pollen) + || attemptedPollinations >= MAX_POLLINATION_ATTEMPTS) { + pollen = null; + } + } + + // Age the queen + queen.age(housing.getWorld(), housing.getLifespanModifier(queen.getGenome(), queen.getMate(), 0f)); + + // Write the changed queen back into the item stack. + NBTTagCompound nbttagcompound = new NBTTagCompound(); + queen.writeToNBT(nbttagcompound); + housing.getQueen().setTagCompound(nbttagcompound); + + return; + } + + private void resetQueen(IBee bee) { + this.queen = bee; + } + + // / BREEDING + private void tickBreed() { + if (!tryBreed()) { + breedingTime = 0; + return; + } + + if (breedingTime < totalBreedingTime) + breedingTime++; + if (breedingTime < totalBreedingTime) + return; + + // Breeding done, create new queen if slot available + if (!ForestryItem.beePrincessGE.isItemEqual(housing.getQueen())) + return; + + // Replace + IBee princess = PluginApiculture.beeInterface.getMember(housing.getQueen()); + IBee drone = PluginApiculture.beeInterface.getMember(housing.getDrone()); + princess.mate(drone); + + NBTTagCompound nbttagcompound = new NBTTagCompound(); + princess.writeToNBT(nbttagcompound); + ItemStack queen = ForestryItem.beeQueenGE.getItemStack(); + queen.setTagCompound(nbttagcompound); + + housing.setQueen(queen); + housing.onQueenChange(housing.getQueen()); + + // Register the new queen with the breeding tracker + PluginApiculture.beeInterface.getBreedingTracker(housing.getWorld(), housing.getOwnerName()).registerQueen(princess); + + // Remove drone + housing.getDrone().stackSize--; + if (housing.getDrone().stackSize <= 0) + housing.setDrone(null); + + // Reset breeding time + breedingTime = 0; + } + + private boolean tryBreed() { + if (housing.getDrone() == null || housing.getQueen() == null) + return false; + + if (!ForestryItem.beeDroneGE.isItemEqual(housing.getDrone()) || !ForestryItem.beePrincessGE.isItemEqual(housing.getQueen())) + return false; + + if (!housing.canBreed()) + return false; + + return true; + } + + private void killQueen(IBee queen) { + if (queen.canSpawn()) { + spawnOffspring(queen); + housing.getQueen().stackSize = 0; + housing.setQueen(null); + } else { + Proxies.log.warning("Tried to spawn offspring off an unmated queen. Devolving her to a princess."); + + ItemStack convert = ForestryItem.beePrincessGE.getItemStack(); + NBTTagCompound nbttagcompound = new NBTTagCompound(); + queen.writeToNBT(nbttagcompound); + convert.setTagCompound(nbttagcompound); + + spawn.add(convert); + housing.setQueen(null); + } + housing.onQueenChange(housing.getQueen()); + } + + /** + * Creates the succeeding princess and between one and three drones. + */ + private void spawnOffspring(IBee queen) { + + Stack offspring = new Stack(); + IApiaristTracker breedingTracker = PluginApiculture.beeInterface.getBreedingTracker(housing.getWorld(), housing.getOwnerName()); + + housing.onQueenDeath(getQueen()); + + // Princess + IBee heiress = queen.spawnPrincess(housing); + if (heiress != null) { + ItemStack princess = PluginApiculture.beeInterface.getMemberStack(heiress, EnumBeeType.PRINCESS.ordinal()); + breedingTracker.registerPrincess(heiress); + offspring.push(princess); + } + + // Drones + IBee[] larvae = queen.spawnDrones(housing); + for (IBee larva : larvae) { + ItemStack drone = PluginApiculture.beeInterface.getMemberStack(larva, EnumBeeType.DRONE.ordinal()); + breedingTracker.registerDrone(larva); + offspring.push(drone); + } + + while (!offspring.isEmpty()) { + ItemStack spawned = offspring.pop(); + if (!housing.addProduct(spawned, true)) + spawn.add(spawned); + } + + housing.onPostQueenDeath(getQueen()); + + } +} diff --git a/forestry_common/apiculture/forestry/apiculture/CommandBeekeepingMode.java b/forestry_common/apiculture/forestry/apiculture/CommandBeekeepingMode.java new file mode 100755 index 000000000..755efb32e --- /dev/null +++ b/forestry_common/apiculture/forestry/apiculture/CommandBeekeepingMode.java @@ -0,0 +1,245 @@ +/******************************************************************************* + * Copyright 2011-2014 by SirSengir + * + * This work is licensed under a Creative Commons Attribution-NonCommercial-NoDerivs 3.0 Unported License. + * + * To view a copy of this license, visit http://creativecommons.org/licenses/by-nc-nd/3.0/. + ******************************************************************************/ +package forestry.apiculture; + +import java.io.BufferedWriter; +import java.io.File; +import java.io.FileOutputStream; +import java.io.OutputStreamWriter; +import java.text.DateFormat; +import java.util.ArrayList; +import java.util.Collection; +import java.util.Date; +import java.util.List; +import java.util.Locale; + +import net.minecraft.command.CommandException; +import net.minecraft.command.ICommand; +import net.minecraft.command.ICommandSender; +import net.minecraft.command.WrongUsageException; +import net.minecraft.entity.player.EntityPlayer; +import net.minecraft.world.World; + +import forestry.api.apiculture.IAlleleBeeSpecies; +import forestry.api.apiculture.IApiaristTracker; +import forestry.api.apiculture.IBeekeepingMode; +import forestry.api.genetics.AlleleManager; +import forestry.api.genetics.IAllele; +import forestry.core.config.Defaults; +import forestry.core.config.Version; +import forestry.core.proxy.Proxies; +import forestry.core.utils.CommandMC; +import forestry.core.utils.StringUtil; +import forestry.plugins.PluginApiculture; + +public class CommandBeekeepingMode extends CommandMC { + + String[] modeStrings; + + public CommandBeekeepingMode() { + modeStrings = new String[PluginApiculture.beeInterface.getBeekeepingModes().size()]; + for (int i = 0; i < PluginApiculture.beeInterface.getBeekeepingModes().size(); i++) + modeStrings[i] = PluginApiculture.beeInterface.getBeekeepingModes().get(i).getName(); + } + + @Override + public int compareTo(Object arg0) { + return this.getCommandName().compareTo(((ICommand) arg0).getCommandName()); + } + + @Override + public String getCommandName() { + return "beekeeping"; + } + + @Override + public String getCommandUsage(ICommandSender var1) { + return "/" + this.getCommandName() + " help"; + } + + @SuppressWarnings("rawtypes") + @Override + public List getCommandAliases() { + return null; + } + + @Override + public void processCommand(ICommandSender sender, String[] arguments) { + + if (arguments.length <= 0) + throw new WrongUsageException("Type '" + this.getCommandUsage(sender) + "' for help."); + + if (arguments[0].matches("list")) + listModes(sender, arguments); + else if (arguments[0].matches("info")) + listModeInfo(sender, arguments); + else if (arguments[0].matches("set")) { + if (arguments.length <= 1) + throw new WrongUsageException("/" + this.getCommandName() + " set [] "); + + World world = getWorld(sender, arguments); + String desired = arguments[arguments.length - 1]; + + IBeekeepingMode mode = PluginApiculture.beeInterface.getBeekeepingMode(desired); + if (mode == null) + throw new CommandException("A bekeeping mode called '%s' is not available.", desired); + + PluginApiculture.beeInterface.setBeekeepingMode(world, mode.getName()); + notifyAdmins(sender, "Beekeeping mode set to %s.", mode.getName()); + + } else if (arguments[0].matches("save")) { + if (arguments.length <= 1) + throw new WrongUsageException("/" + this.getCommandName() + " save "); + + saveStatistics(sender, arguments); + } else if (arguments[0].matches("help")) { + sendChatMessage(sender, "Format: '/" + this.getCommandName() + " '"); + sendChatMessage(sender, "Available commands:"); + sendChatMessage(sender, "- list []: lists current and available beekeeping modes."); + sendChatMessage(sender, "- info : information on beekeeping mode."); + sendChatMessage(sender, "- set [] : set beekeeping mode for world."); + sendChatMessage(sender, "- save [] : save beekeeping statistics for the given player."); + } + } + + private void saveStatistics(ICommandSender sender, String[] arguments) { + + String newLine = System.getProperty("line.separator"); + World world = getWorld(sender, arguments); + + String player = arguments[1]; + Collection statistics = new ArrayList(); + + statistics.add(String.format("Beekeeping statistics for %s on %s:", player, DateFormat.getInstance().format(new Date()))); + statistics.add(""); + statistics.add("MODE: " + PluginApiculture.beeInterface.getBeekeepingMode(world).getName()); + statistics.add(""); + + IApiaristTracker tracker = PluginApiculture.beeInterface.getBreedingTracker(world, player); + if (tracker == null) + statistics.add("No statistics found."); + else { + statistics.add("BRED:"); + statistics.add("-----"); + statistics.add(""); + + statistics.add("Queens:\t\t" + tracker.getQueenCount()); + statistics.add("Princesses:\t" + tracker.getPrincessCount()); + statistics.add("Drones:\t\t" + tracker.getDroneCount()); + statistics.add(""); + + Collection species = new ArrayList(); + for (IAllele allele : AlleleManager.alleleRegistry.getRegisteredAlleles().values()) + if (allele instanceof IAlleleBeeSpecies) + species.add((IAlleleBeeSpecies) allele); + + statistics.add(String.format("SPECIES (%s):", species.size())); + statistics.add("-------------"); + statistics.add(""); + + for (IAlleleBeeSpecies allele : species) + statistics.add(generateSpeciesListEntry(allele, tracker)); + } + + File file = new File(Proxies.common.getForestryRoot(), "config/" + Defaults.MOD.toLowerCase(Locale.ENGLISH) + "/stats/" + player + ".log"); + try { + + if (file.getParentFile() != null) + file.getParentFile().mkdirs(); + + if (!file.exists() && !file.createNewFile()) { + sendChatMessage(sender, "Log file could not be created. Failed to save statistics."); + return; + } + + if (!file.canWrite()) { + sendChatMessage(sender, "Cannot write to log file. Failed to save statistics."); + return; + } + + FileOutputStream fileout = new FileOutputStream(file); + BufferedWriter writer = new BufferedWriter(new OutputStreamWriter(fileout, "UTF-8")); + + writer.write("# " + Defaults.MOD + newLine + "# " + Version.getVersion() + newLine); + + for (String line : statistics) + writer.write(line + newLine); + + writer.close(); + + } catch (Exception ex) { + sendChatMessage(sender, "Write operation threw an exception. Failed to save statistics."); + ex.printStackTrace(); + } + + sendChatMessage(sender, "Saved statistics for player " + player); + } + + private String generateSpeciesListEntry(IAlleleBeeSpecies species, IApiaristTracker tracker) { + String discovered = "[ ]"; + if (tracker.isDiscovered(species)) + discovered = "[ X ]"; + String blacklisted = "[ ]"; + if (AlleleManager.alleleRegistry.isBlacklisted(species.getUID())) + blacklisted = "[ BL ]"; + String notcounted = "[ ]"; + if (!species.isCounted()) + notcounted = "[ NC ]"; + + return String.format("%s %s %s\t%-40s %-20s %-20s", discovered, blacklisted, notcounted, species.getUID(), species.getName(), species.getAuthority()); + } + + private void listModes(ICommandSender sender, String[] arguments) { + World world = getWorld(sender, arguments); + + sendChatMessage(sender, "Current: " + PluginApiculture.beeInterface.getBeekeepingMode(world).getName() + " (#" + world.getWorldInfo().getSaveVersion() + ")"); + + String help = ""; + for (IBeekeepingMode mode : PluginApiculture.beeInterface.getBeekeepingModes()) { + if (!help.isEmpty()) + help += ", "; + help += mode.getName(); + } + sendChatMessage(sender, "Available modes: " + help); + return; + } + + private void listModeInfo(ICommandSender sender, String[] arguments) { + if (arguments.length <= 1) + throw new WrongUsageException("/" + this.getCommandName() + " info "); + + IBeekeepingMode found = null; + for (IBeekeepingMode mode : PluginApiculture.beeInterface.getBeekeepingModes()) + if (mode.getName().equalsIgnoreCase(arguments[1])) { + found = mode; + break; + } + + if (found == null) + throw new CommandException("No beekeeping mode called '%s' is available.", arguments[1]); + + sendChatMessage(sender, "\u00A7aMode: " + found.getName()); + for (String desc : found.getDescription()) + sendChatMessage(sender, StringUtil.localize(desc)); + } + + @Override + public boolean canCommandSenderUseCommand(ICommandSender sender) { + if (sender instanceof EntityPlayer) + return Proxies.common.isOp((EntityPlayer) sender); + else + return sender.canCommandSenderUseCommand(4, getCommandName()); + } + + @SuppressWarnings("rawtypes") + @Override + public List addTabCompletionOptions(ICommandSender sender, String[] incomplete) { + return getListOfStringsMatchingLastWord(incomplete, modeStrings); + } + +} diff --git a/forestry_common/apiculture/forestry/apiculture/CommandGiveBee.java b/forestry_common/apiculture/forestry/apiculture/CommandGiveBee.java new file mode 100755 index 000000000..4f32808c2 --- /dev/null +++ b/forestry_common/apiculture/forestry/apiculture/CommandGiveBee.java @@ -0,0 +1,117 @@ +/******************************************************************************* + * Copyright 2011-2014 by SirSengir + * + * This work is licensed under a Creative Commons Attribution-NonCommercial-NoDerivs 3.0 Unported License. + * + * To view a copy of this license, visit http://creativecommons.org/licenses/by-nc-nd/3.0/. + ******************************************************************************/ +package forestry.apiculture; + +import java.util.ArrayList; +import java.util.List; + +import net.minecraft.command.ICommandSender; +import net.minecraft.command.WrongUsageException; +import net.minecraft.entity.player.EntityPlayer; +import net.minecraft.item.ItemStack; + +import forestry.api.apiculture.EnumBeeType; +import forestry.api.apiculture.IAlleleBeeSpecies; +import forestry.api.apiculture.IBee; +import forestry.api.apiculture.IBeeGenome; +import forestry.api.genetics.AlleleManager; +import forestry.api.genetics.IAllele; +import forestry.api.genetics.IAlleleSpecies; +import forestry.core.utils.CommandMC; +import forestry.plugins.PluginApiculture; + +public class CommandGiveBee extends CommandMC { + + EnumBeeType type; + + public CommandGiveBee(EnumBeeType type) { + this.type = type; + } + + @Override + public String getCommandName() { + return "give" + type.toString().toLowerCase(); + } + + @Override + public String getCommandUsage(ICommandSender par1ICommandSender) { + return "/" + getCommandName() + " "; + } + + @Override + public void processCommand(ICommandSender sender, String[] arguments) { + if (arguments.length >= 2) { + + EntityPlayer player = getPlayerFromName(arguments[0]); + + String parameter = arguments[1]; + + IAlleleBeeSpecies species = null; + + search: for (String uid : AlleleManager.alleleRegistry.getRegisteredAlleles().keySet()) { + + if (!uid.equals(parameter)) + continue; + + if (AlleleManager.alleleRegistry.getAllele(uid) instanceof IAlleleBeeSpecies) { + species = (IAlleleBeeSpecies) AlleleManager.alleleRegistry.getAllele(uid); + break search; + } + } + + search: if (species == null) + for (IAllele allele : AlleleManager.alleleRegistry.getRegisteredAlleles().values()) + if (allele instanceof IAlleleBeeSpecies) + if (((IAlleleBeeSpecies) allele).getName().equals(parameter)) { + species = (IAlleleBeeSpecies) allele; + break search; + } + + if (species == null) + throw new SpeciesNotFoundException(parameter); + + IAllele[] template = PluginApiculture.beeInterface.getTemplate(species.getUID()); + + if (template == null) + throw new TemplateNotFoundException(species); + + IBeeGenome genome = PluginApiculture.beeInterface.templateAsGenome(template); + + IBee bee = PluginApiculture.beeInterface.getBee(player.worldObj, genome); + + ItemStack beestack = PluginApiculture.beeInterface.getMemberStack(bee, type.ordinal()); + player.dropPlayerItemWithRandomChoice(beestack, true); + notifyAdmins(sender, "Player %s was given a %s bee.", player.getCommandSenderName(), ((IAlleleSpecies) template[0]).getName()); + } else + throw new WrongUsageException("/" + getCommandName() + " "); + } + + /** + * Adds the strings available in this command to the given list of tab completion options. + */ + @SuppressWarnings("rawtypes") + @Override + public List addTabCompletionOptions(ICommandSender sender, String[] parameters) { + if (parameters.length == 1) + return getListOfStringsMatchingLastWord(parameters, this.getPlayers()); + else if (parameters.length == 2) + return getListOfStringsMatchingLastWord(parameters, this.getSpecies()); + else + return null; + } + + protected String[] getSpecies() { + List species = new ArrayList(); + + for (IAllele allele : AlleleManager.alleleRegistry.getRegisteredAlleles().values()) + if (allele instanceof IAlleleBeeSpecies) + species.add(((IAlleleSpecies) allele).getName()); + + return species.toArray(new String[] {}); + } +} diff --git a/forestry_common/apiculture/forestry/apiculture/FlowerProviderCacti.java b/forestry_common/apiculture/forestry/apiculture/FlowerProviderCacti.java new file mode 100755 index 000000000..16cf11943 --- /dev/null +++ b/forestry_common/apiculture/forestry/apiculture/FlowerProviderCacti.java @@ -0,0 +1,81 @@ +/******************************************************************************* + * Copyright 2011-2014 by SirSengir + * + * This work is licensed under a Creative Commons Attribution-NonCommercial-NoDerivs 3.0 Unported License. + * + * To view a copy of this license, visit http://creativecommons.org/licenses/by-nc-nd/3.0/. + ******************************************************************************/ +package forestry.apiculture; + +import net.minecraft.block.Block; +import net.minecraft.init.Blocks; +import net.minecraft.item.ItemStack; +import net.minecraft.world.World; + +import net.minecraftforge.common.EnumPlantType; + +import forestry.api.genetics.IFlowerProvider; +import forestry.api.genetics.IIndividual; +import forestry.api.genetics.IPollinatable; +import forestry.core.config.Defaults; +import forestry.core.utils.StringUtil; + +public class FlowerProviderCacti implements IFlowerProvider { + + @Override + public boolean isAcceptedFlower(World world, IIndividual individual, int x, int y, int z) { + Block block = world.getBlock(x, y, z); + + // Specific check for flower pots. + if (block == Blocks.flower_pot) + return checkFlowerPot(world.getBlockMetadata(x, y, z)); + + return block == Blocks.cactus; + } + + @Override + public boolean isAcceptedPollinatable(World world, IPollinatable pollinatable) { + return pollinatable.getPlantType().contains(EnumPlantType.Desert); + } + + private boolean checkFlowerPot(int meta) { + if (meta == 9) + return true; + else + return false; + } + + @Override + public boolean growFlower(World world, IIndividual individual, int x, int y, int z) { + Block block = world.getBlock(x, y, z); + + if (block == Blocks.flower_pot && world.getBlockMetadata(x, y, z) == 0) + return growInPot(world, x, y, z); + + return false; + } + + private boolean growInPot(World world, int x, int y, int z) { + if (world.rand.nextBoolean()) + world.setBlock(x, y, z, Blocks.flower_pot, 9, Defaults.FLAG_BLOCK_SYNCH); + else + world.setBlock(x, y, z, Blocks.flower_pot, 10, Defaults.FLAG_BLOCK_SYNCH); + return true; + } + + @Override + public String getDescription() { + return StringUtil.localize("flowers.cacti"); + } + + @Override + public ItemStack[] affectProducts(World world, IIndividual individual, int x, int y, int z, ItemStack[] products) { + return products; + } + + @Override + public ItemStack[] getItemStacks() { + return new ItemStack[] { new ItemStack(Blocks.cactus) }; + } + +} diff --git a/forestry_common/apiculture/forestry/apiculture/FlowerProviderEnd.java b/forestry_common/apiculture/forestry/apiculture/FlowerProviderEnd.java new file mode 100755 index 000000000..41646aa09 --- /dev/null +++ b/forestry_common/apiculture/forestry/apiculture/FlowerProviderEnd.java @@ -0,0 +1,58 @@ +/******************************************************************************* + * Copyright 2011-2014 by SirSengir + * + * This work is licensed under a Creative Commons Attribution-NonCommercial-NoDerivs 3.0 Unported License. + * + * To view a copy of this license, visit http://creativecommons.org/licenses/by-nc-nd/3.0/. + ******************************************************************************/ +package forestry.apiculture; + +import java.util.EnumSet; + +import net.minecraft.block.Block; +import net.minecraft.init.Blocks; +import net.minecraft.item.ItemStack; +import net.minecraft.world.World; + +import net.minecraftforge.common.EnumPlantType; + +import forestry.api.genetics.IFlowerProvider; +import forestry.api.genetics.IIndividual; +import forestry.api.genetics.IPollinatable; +import forestry.core.utils.StringUtil; + +public class FlowerProviderEnd implements IFlowerProvider { + + @Override + public boolean isAcceptedFlower(World world, IIndividual individual, int x, int y, int z) { + Block block = world.getBlock(x, y, z); + return block == Blocks.dragon_egg; + } + + @Override + public boolean isAcceptedPollinatable(World world, IPollinatable pollinatable) { + EnumSet types = pollinatable.getPlantType(); + return types.size() > 1 || !types.contains(EnumPlantType.Nether); + } + + @Override + public boolean growFlower(World world, IIndividual individual, int x, int y, int z) { + return true; + } + + @Override + public String getDescription() { + return StringUtil.localize("flowers.end"); + } + + @Override + public ItemStack[] affectProducts(World world, IIndividual individual, int x, int y, int z, ItemStack[] products) { + return products; + } + + @Override + public ItemStack[] getItemStacks() { + return new ItemStack[] { new ItemStack(Blocks.dragon_egg) }; + } + +} diff --git a/forestry_common/apiculture/forestry/apiculture/FlowerProviderGourd.java b/forestry_common/apiculture/forestry/apiculture/FlowerProviderGourd.java new file mode 100755 index 000000000..fe8e68201 --- /dev/null +++ b/forestry_common/apiculture/forestry/apiculture/FlowerProviderGourd.java @@ -0,0 +1,76 @@ +/******************************************************************************* + * Copyright 2011-2014 by SirSengir + * + * This work is licensed under a Creative Commons Attribution-NonCommercial-NoDerivs 3.0 Unported License. + * + * To view a copy of this license, visit http://creativecommons.org/licenses/by-nc-nd/3.0/. + ******************************************************************************/ +package forestry.apiculture; + +import java.util.EnumSet; + +import net.minecraft.block.Block; +import net.minecraft.init.Blocks; +import net.minecraft.item.ItemStack; +import net.minecraft.world.World; + +import net.minecraftforge.common.EnumPlantType; + +import forestry.api.genetics.IFlowerProvider; +import forestry.api.genetics.IIndividual; +import forestry.api.genetics.IPollinatable; +import forestry.core.config.Defaults; +import forestry.core.utils.StringUtil; + +public class FlowerProviderGourd implements IFlowerProvider { + + @Override + public boolean isAcceptedFlower(World world, IIndividual individual, int x, int y, int z) { + Block block = world.getBlock(x, y, z); + return block == Blocks.pumpkin_stem || block == Blocks.melon_stem; + } + + @Override + public boolean isAcceptedPollinatable(World world, IPollinatable pollinatable) { + EnumSet types = pollinatable.getPlantType(); + return types.size() > 1 || !types.contains(EnumPlantType.Nether); + } + + @Override + public boolean growFlower(World world, IIndividual individual, int x, int y, int z) { + + Block block = world.getBlock(x, y, z); + + // We only grow wheat, we don't plant it + if (block != Blocks.pumpkin_stem && block != Blocks.melon_stem) + return false; + + int meta = world.getBlockMetadata(x, y, z); + if (meta > 6) + return false; + + if (meta < 6) + meta += 2; + else + meta = 7; + + world.setBlockMetadataWithNotify(x, y, z, meta, Defaults.FLAG_BLOCK_SYNCH); + return true; + } + + @Override + public String getDescription() { + return StringUtil.localize("flowers.gourd"); + } + + @Override + public ItemStack[] affectProducts(World world, IIndividual individual, int x, int y, int z, ItemStack[] products) { + return products; + } + + @Override + public ItemStack[] getItemStacks() { + return new ItemStack[] { new ItemStack(Blocks.wheat, 1, 8) }; + } + +} diff --git a/forestry_common/apiculture/forestry/apiculture/FlowerProviderJungle.java b/forestry_common/apiculture/forestry/apiculture/FlowerProviderJungle.java new file mode 100755 index 000000000..1161fb1dd --- /dev/null +++ b/forestry_common/apiculture/forestry/apiculture/FlowerProviderJungle.java @@ -0,0 +1,82 @@ +/******************************************************************************* + * Copyright 2011-2014 by SirSengir + * + * This work is licensed under a Creative Commons Attribution-NonCommercial-NoDerivs 3.0 Unported License. + * + * To view a copy of this license, visit http://creativecommons.org/licenses/by-nc-nd/3.0/. + ******************************************************************************/ +package forestry.apiculture; + +import java.util.EnumSet; + +import net.minecraft.block.Block; +import net.minecraft.init.Blocks; +import net.minecraft.item.ItemStack; +import net.minecraft.world.World; + +import net.minecraftforge.common.EnumPlantType; + +import forestry.api.genetics.IFlowerProvider; +import forestry.api.genetics.IIndividual; +import forestry.api.genetics.IPollinatable; +import forestry.core.config.Defaults; +import forestry.core.utils.StringUtil; + +public class FlowerProviderJungle implements IFlowerProvider { + + @Override + public boolean isAcceptedFlower(World world, IIndividual individual, int x, int y, int z) { + Block block = world.getBlock(x, y, z); + int meta = world.getBlockMetadata(x, y, z); + + // Specific check for flower pots. + if (block == Blocks.flower_pot) + return checkFlowerPot(meta); + + return block == Blocks.vine || (block == Blocks.tallgrass && meta == 2); + } + + @Override + public boolean isAcceptedPollinatable(World world, IPollinatable pollinatable) { + EnumSet types = pollinatable.getPlantType(); + return types.size() > 1 || !types.contains(EnumPlantType.Nether); + } + + private boolean checkFlowerPot(int meta) { + if (meta == 11) + return true; + else + return false; + } + + @Override + public boolean growFlower(World world, IIndividual individual, int x, int y, int z) { + Block block = world.getBlock(x, y, z); + + if (block == Blocks.flower_pot) + return growInPot(world, x, y, z); + + return false; + } + + private boolean growInPot(World world, int x, int y, int z) { + world.setBlock(x, y, z, Blocks.flower_pot, 11, Defaults.FLAG_BLOCK_SYNCH); + return true; + } + + @Override + public String getDescription() { + return StringUtil.localize("flowers.jungle"); + } + + @Override + public ItemStack[] affectProducts(World world, IIndividual individual, int x, int y, int z, ItemStack[] products) { + return products; + } + + @Override + public ItemStack[] getItemStacks() { + return new ItemStack[] { new ItemStack(Blocks.vine), new ItemStack(Blocks.tallgrass, 1, 2) }; + } + +} diff --git a/forestry_common/apiculture/forestry/apiculture/FlowerProviderMushroom.java b/forestry_common/apiculture/forestry/apiculture/FlowerProviderMushroom.java new file mode 100755 index 000000000..221dc72b9 --- /dev/null +++ b/forestry_common/apiculture/forestry/apiculture/FlowerProviderMushroom.java @@ -0,0 +1,100 @@ +/******************************************************************************* + * Copyright 2011-2014 by SirSengir + * + * This work is licensed under a Creative Commons Attribution-NonCommercial-NoDerivs 3.0 Unported License. + * + * To view a copy of this license, visit http://creativecommons.org/licenses/by-nc-nd/3.0/. + ******************************************************************************/ +package forestry.apiculture; + +import java.util.EnumSet; + +import net.minecraft.block.Block; +import net.minecraft.init.Blocks; +import net.minecraft.item.ItemStack; +import net.minecraft.world.World; + +import net.minecraftforge.common.EnumPlantType; + +import forestry.api.genetics.IFlowerProvider; +import forestry.api.genetics.IIndividual; +import forestry.api.genetics.IPollinatable; +import forestry.core.config.Defaults; +import forestry.core.utils.StringUtil; + +public class FlowerProviderMushroom implements IFlowerProvider { + + @Override + public boolean isAcceptedFlower(World world, IIndividual individual, int x, int y, int z) { + Block block = world.getBlock(x, y, z); + + // Specific check for flower pots. + if (block == Blocks.flower_pot) + return checkFlowerPot(world.getBlockMetadata(x, y, z)); + + return block == Blocks.brown_mushroom || block == Blocks.red_mushroom; + } + + @Override + public boolean isAcceptedPollinatable(World world, IPollinatable pollinatable) { + EnumSet types = pollinatable.getPlantType(); + return types.size() > 1 || !types.contains(EnumPlantType.Nether); + } + + private boolean checkFlowerPot(int meta) { + if (meta == 7 || meta == 8) + return true; + else + return false; + } + + @Override + public boolean growFlower(World world, IIndividual individual, int x, int y, int z) { + Block block = world.getBlock(x, y, z); + + if (!block.isAir(world, x, y, z)) + if (block == Blocks.flower_pot) + return growInPot(world, x, y, z); + else + return false; + + // Check ground + Block ground = world.getBlock(x, y - 1, z); + + if (ground != Blocks.mycelium) + return false; + + Block mushroom; + if (world.rand.nextBoolean()) + mushroom = Blocks.brown_mushroom; + else + mushroom = Blocks.red_mushroom; + + world.setBlock(x, y, z, mushroom, 0, Defaults.FLAG_BLOCK_SYNCH); + return true; + } + + private boolean growInPot(World world, int x, int y, int z) { + if (world.rand.nextBoolean()) + world.setBlock(x, y, z, Blocks.flower_pot, 7, Defaults.FLAG_BLOCK_SYNCH); + else + world.setBlock(x, y, z, Blocks.flower_pot, 8, Defaults.FLAG_BLOCK_SYNCH); + return true; + } + + @Override + public String getDescription() { + return StringUtil.localize("flowers.mushroom"); + } + + @Override + public ItemStack[] affectProducts(World world, IIndividual individual, int x, int y, int z, ItemStack[] products) { + return products; + } + + @Override + public ItemStack[] getItemStacks() { + return new ItemStack[] { new ItemStack(Blocks.brown_mushroom), new ItemStack(Blocks.red_mushroom) }; + } + +} diff --git a/forestry_common/apiculture/forestry/apiculture/FlowerProviderNetherwart.java b/forestry_common/apiculture/forestry/apiculture/FlowerProviderNetherwart.java new file mode 100755 index 000000000..50771fcd7 --- /dev/null +++ b/forestry_common/apiculture/forestry/apiculture/FlowerProviderNetherwart.java @@ -0,0 +1,73 @@ +/******************************************************************************* + * Copyright 2011-2014 by SirSengir + * + * This work is licensed under a Creative Commons Attribution-NonCommercial-NoDerivs 3.0 Unported License. + * + * To view a copy of this license, visit http://creativecommons.org/licenses/by-nc-nd/3.0/. + ******************************************************************************/ +package forestry.apiculture; + +import net.minecraft.block.Block; +import net.minecraft.init.Blocks; +import net.minecraft.item.ItemStack; +import net.minecraft.world.World; + +import net.minecraftforge.common.EnumPlantType; + +import forestry.api.genetics.IFlowerProvider; +import forestry.api.genetics.IIndividual; +import forestry.api.genetics.IPollinatable; +import forestry.core.config.Defaults; +import forestry.core.utils.StringUtil; + +public class FlowerProviderNetherwart implements IFlowerProvider { + + @Override + public boolean isAcceptedFlower(World world, IIndividual individual, int x, int y, int z) { + Block block = world.getBlock(x, y, z); + return block == Blocks.nether_wart; + } + + @Override + public boolean isAcceptedPollinatable(World world, IPollinatable pollinatable) { + return pollinatable.getPlantType().contains(EnumPlantType.Nether); + } + + @Override + public boolean growFlower(World world, IIndividual individual, int x, int y, int z) { + + Block block = world.getBlock(x, y, z); + + // We only grow netherwart, we don't plant it + if (block != Blocks.nether_wart) + return false; + + int meta = world.getBlockMetadata(x, y, z); + if (meta >= 3) + return false; + + if (meta == 2) + meta = 3; + else + meta = 2; + + world.setBlockMetadataWithNotify(x, y, z, meta, Defaults.FLAG_BLOCK_SYNCH); + return true; + } + + @Override + public String getDescription() { + return StringUtil.localize("flowers.nether"); + } + + @Override + public ItemStack[] affectProducts(World world, IIndividual individual, int x, int y, int z, ItemStack[] products) { + return products; + } + + @Override + public ItemStack[] getItemStacks() { + return new ItemStack[] { new ItemStack(Blocks.nether_wart) }; + } + +} diff --git a/forestry_common/apiculture/forestry/apiculture/FlowerProviderVanilla.java b/forestry_common/apiculture/forestry/apiculture/FlowerProviderVanilla.java new file mode 100755 index 000000000..52d7a66f6 --- /dev/null +++ b/forestry_common/apiculture/forestry/apiculture/FlowerProviderVanilla.java @@ -0,0 +1,109 @@ +/******************************************************************************* + * Copyright 2011-2014 by SirSengir + * + * This work is licensed under a Creative Commons Attribution-NonCommercial-NoDerivs 3.0 Unported License. + * + * To view a copy of this license, visit http://creativecommons.org/licenses/by-nc-nd/3.0/. + ******************************************************************************/ +package forestry.apiculture; + +import java.util.Collections; +import java.util.EnumSet; + +import net.minecraft.block.Block; +import net.minecraft.init.Blocks; +import net.minecraft.item.ItemStack; +import net.minecraft.world.World; + +import net.minecraftforge.common.EnumPlantType; + +import forestry.api.apiculture.FlowerManager; +import forestry.api.genetics.IFlowerProvider; +import forestry.api.genetics.IIndividual; +import forestry.api.genetics.IPollinatable; +import forestry.core.config.Defaults; +import forestry.core.utils.StackUtils; +import forestry.core.utils.StringUtil; + +public class FlowerProviderVanilla implements IFlowerProvider { + + @Override + public boolean isAcceptedFlower(World world, IIndividual individual, int x, int y, int z) { + + Block block = world.getBlock(x, y, z); + int meta = world.getBlockMetadata(x, y, z); + + // Specific check for flower pots. + if (block == Blocks.flower_pot) + return checkFlowerPot(meta); + + ItemStack flower = new ItemStack(block, 1, meta); + + for (ItemStack stack : FlowerManager.plainFlowers) + if (flower.isItemEqual(stack)) + return true; + + return false; + } + + @Override + public boolean isAcceptedPollinatable(World world, IPollinatable pollinatable) { + EnumSet types = pollinatable.getPlantType(); + return types.size() > 1 || !types.contains(EnumPlantType.Nether); + } + + private boolean checkFlowerPot(int meta) { + if (meta == 1 || meta == 2) + return true; + else + return false; + } + + @Override + public boolean growFlower(World world, IIndividual individual, int x, int y, int z) { + + Block block = world.getBlock(x, y, z); + + if (!block.isAir(world, x, y, z)) + if (block == Blocks.flower_pot && world.getBlockMetadata(x, y, z) == 0) + return growInPot(world, x, y, z); + else + return false; + + // Check ground + Block ground = world.getBlock(x, y - 1, z); + + if (ground != Blocks.dirt && ground != Blocks.grass) + return false; + + // Determine flower to plant + Collections.shuffle(FlowerManager.plainFlowers); + ItemStack flower = FlowerManager.plainFlowers.get(world.rand.nextInt(FlowerManager.plainFlowers.size() - 1)); + world.setBlock(x, y, z, StackUtils.getBlock(flower), flower.getItemDamage(), Defaults.FLAG_BLOCK_SYNCH); + return true; + } + + private boolean growInPot(World world, int x, int y, int z) { + if (world.rand.nextBoolean()) + world.setBlock(x, y, z, Blocks.flower_pot, 1, Defaults.FLAG_BLOCK_SYNCH); + else + world.setBlock(x, y, z, Blocks.flower_pot, 2, Defaults.FLAG_BLOCK_SYNCH); + return true; + } + + @Override + public String getDescription() { + return StringUtil.localize("flowers.vanilla"); + } + + @Override + public ItemStack[] affectProducts(World world, IIndividual individual, int x, int y, int z, ItemStack[] products) { + return products; + } + + @Override + public ItemStack[] getItemStacks() { + return FlowerManager.plainFlowers.toArray(new ItemStack[0]); + } + +} diff --git a/forestry_common/apiculture/forestry/apiculture/FlowerProviderWheat.java b/forestry_common/apiculture/forestry/apiculture/FlowerProviderWheat.java new file mode 100755 index 000000000..95d4d2bce --- /dev/null +++ b/forestry_common/apiculture/forestry/apiculture/FlowerProviderWheat.java @@ -0,0 +1,76 @@ +/******************************************************************************* + * Copyright 2011-2014 by SirSengir + * + * This work is licensed under a Creative Commons Attribution-NonCommercial-NoDerivs 3.0 Unported License. + * + * To view a copy of this license, visit http://creativecommons.org/licenses/by-nc-nd/3.0/. + ******************************************************************************/ +package forestry.apiculture; + +import java.util.EnumSet; + +import net.minecraft.block.Block; +import net.minecraft.init.Blocks; +import net.minecraft.item.ItemStack; +import net.minecraft.world.World; + +import net.minecraftforge.common.EnumPlantType; + +import forestry.api.genetics.IFlowerProvider; +import forestry.api.genetics.IIndividual; +import forestry.api.genetics.IPollinatable; +import forestry.core.config.Defaults; +import forestry.core.utils.StringUtil; + +public class FlowerProviderWheat implements IFlowerProvider { + + @Override + public boolean isAcceptedFlower(World world, IIndividual individual, int x, int y, int z) { + Block block = world.getBlock(x, y, z); + return block == Blocks.wheat; + } + + @Override + public boolean isAcceptedPollinatable(World world, IPollinatable pollinatable) { + EnumSet types = pollinatable.getPlantType(); + return types.size() > 1 || !types.contains(EnumPlantType.Nether); + } + + @Override + public boolean growFlower(World world, IIndividual individual, int x, int y, int z) { + + Block block = world.getBlock(x, y, z); + + // We only grow wheat, we don't plant it + if (block != Blocks.wheat) + return false; + + int meta = world.getBlockMetadata(x, y, z); + if (meta > 6) + return false; + + if (meta < 6) + meta += 2; + else + meta = 7; + + world.setBlockMetadataWithNotify(x, y, z, meta, Defaults.FLAG_BLOCK_SYNCH); + return true; + } + + @Override + public String getDescription() { + return StringUtil.localize("flowers.wheat"); + } + + @Override + public ItemStack[] affectProducts(World world, IIndividual individual, int x, int y, int z, ItemStack[] products) { + return products; + } + + @Override + public ItemStack[] getItemStacks() { + return new ItemStack[] { new ItemStack(Blocks.wheat, 1, 8) }; + } + +} diff --git a/forestry_common/apiculture/forestry/apiculture/GuiHandlerApiculture.java b/forestry_common/apiculture/forestry/apiculture/GuiHandlerApiculture.java new file mode 100755 index 000000000..d2ba46b9f --- /dev/null +++ b/forestry_common/apiculture/forestry/apiculture/GuiHandlerApiculture.java @@ -0,0 +1,164 @@ +/******************************************************************************* + * Copyright 2011-2014 by SirSengir + * + * This work is licensed under a Creative Commons Attribution-NonCommercial-NoDerivs 3.0 Unported License. + * + * To view a copy of this license, visit http://creativecommons.org/licenses/by-nc-nd/3.0/. + ******************************************************************************/ +package forestry.apiculture; + +import net.minecraft.entity.player.EntityPlayer; +import net.minecraft.item.ItemStack; +import net.minecraft.world.World; + +import forestry.apiculture.gadgets.TileAlvearyHygroregulator; +import forestry.apiculture.gadgets.TileAlvearyPlain; +import forestry.apiculture.gadgets.TileAlvearySieve; +import forestry.apiculture.gadgets.TileAlvearySwarmer; +import forestry.apiculture.gadgets.TileApiary; +import forestry.apiculture.gadgets.TileBeehouse; +import forestry.apiculture.genetics.BeeHelper; +import forestry.apiculture.gui.ContainerAlveary; +import forestry.apiculture.gui.ContainerAlvearyHygroregulator; +import forestry.apiculture.gui.ContainerAlvearySieve; +import forestry.apiculture.gui.ContainerAlvearySwarmer; +import forestry.apiculture.gui.ContainerApiary; +import forestry.apiculture.gui.ContainerBeealyzer; +import forestry.apiculture.gui.ContainerHabitatLocator; +import forestry.apiculture.gui.ContainerImprinter; +import forestry.apiculture.gui.GuiAlveary; +import forestry.apiculture.gui.GuiAlvearyHygroregulator; +import forestry.apiculture.gui.GuiAlvearySieve; +import forestry.apiculture.gui.GuiAlvearySwarmer; +import forestry.apiculture.gui.GuiApiary; +import forestry.apiculture.gui.GuiBeealyzer; +import forestry.apiculture.gui.GuiHabitatLocator; +import forestry.apiculture.gui.GuiImprinter; +import forestry.apiculture.items.ItemBeealyzer.BeealyzerInventory; +import forestry.apiculture.items.ItemBiomefinder.BiomefinderInventory; +import forestry.apiculture.items.ItemImprinter.ImprinterInventory; +import forestry.core.GuiHandlerBase; +import forestry.core.network.GuiId; +import forestry.plugins.PluginApiculture; + +public class GuiHandlerApiculture extends GuiHandlerBase { + + @Override + public Object getClientGuiElement(int id, EntityPlayer player, World world, int x, int y, int z) { + int cleanId = decodeGuiID(id); + int guiData = decodeGuiData(id); + + if (cleanId >= GuiId.values().length) + return null; + + ItemStack equipped; + switch (GuiId.values()[cleanId]) { + + case AlvearyGUI: + return new GuiAlveary(player.inventory, (TileAlvearyPlain) getTileForestry(world, x, y, z)); + + case AlvearySieveGUI: + return new GuiAlvearySieve(player.inventory, (TileAlvearySieve) getTileForestry(world, x, y, z)); + + case AlvearySwarmerGUI: + return new GuiAlvearySwarmer(player.inventory, (TileAlvearySwarmer) getTileForestry(world, x, y, z)); + + case ApiaristChestGUI: + return getNaturalistChestGui(BeeHelper.UID, player, world, x, y, z, guiData); + + case ApiaryGUI: + return new GuiApiary(player.inventory, (TileApiary) getTileForestry(world, x, y, z)); + + case BeealyzerGUI: + equipped = getEquippedItem(player); + if (equipped == null) + return null; + + return new GuiBeealyzer(player, new BeealyzerInventory(player, equipped)); + + case BeehouseGUI: + return new GuiApiary(player.inventory, (TileBeehouse) getTileForestry(world, x, y, z)); + + case HabitatLocatorGUI: + equipped = getEquippedItem(player); + if (equipped == null) + return null; + + return new GuiHabitatLocator(player.inventory, new BiomefinderInventory(equipped)); + + case HygroregulatorGUI: + return new GuiAlvearyHygroregulator(player.inventory, (TileAlvearyHygroregulator) getTileForestry(world, x, y, z)); + + case ImprinterGUI: + return new GuiImprinter(player.inventory, new ImprinterInventory(player)); + + default: + return null; + + } + } + + @Override + public Object getServerGuiElement(int id, EntityPlayer player, World world, int x, int y, int z) { + int cleanId = decodeGuiID(id); + int guiData = decodeGuiData(id); + + if (cleanId >= GuiId.values().length) + return null; + + ItemStack equipped; + switch (GuiId.values()[cleanId]) { + + case AlvearyGUI: + synchApiaristTracker(world, player); + return new ContainerAlveary(player.inventory, (TileAlvearyPlain) getTileForestry(world, x, y, z)); + + case AlvearySieveGUI: + return new ContainerAlvearySieve(player.inventory, (TileAlvearySieve) getTileForestry(world, x, y, z)); + + case AlvearySwarmerGUI: + return new ContainerAlvearySwarmer(player.inventory, (TileAlvearySwarmer) getTileForestry(world, x, y, z)); + + case ApiaristChestGUI: + return getNaturalistChestContainer(BeeHelper.UID, player, world, x, y, z, guiData); + + case ApiaryGUI: + synchApiaristTracker(world, player); + return new ContainerApiary(player.inventory, (TileApiary) getTileForestry(world, x, y, z), true); + + case BeealyzerGUI: + equipped = getEquippedItem(player); + if (equipped == null) + return null; + + synchApiaristTracker(world, player); + return new ContainerBeealyzer(player.inventory, new BeealyzerInventory(player, equipped)); + + case BeehouseGUI: + synchApiaristTracker(world, player); + return new ContainerApiary(player.inventory, (TileBeehouse) getTileForestry(world, x, y, z), false); + + case HabitatLocatorGUI: + equipped = getEquippedItem(player); + if (equipped == null) + return null; + + return new ContainerHabitatLocator(player.inventory, new BiomefinderInventory(equipped)); + + case HygroregulatorGUI: + return new ContainerAlvearyHygroregulator(player.inventory, (TileAlvearyHygroregulator) getTileForestry(world, x, y, z)); + + case ImprinterGUI: + synchApiaristTracker(world, player); + return new ContainerImprinter(player.inventory, new ImprinterInventory(player)); + + default: + return null; + + } + } + + private void synchApiaristTracker(World world, EntityPlayer player) { + PluginApiculture.beeInterface.getBreedingTracker(world, player.getGameProfile().getId()).synchToPlayer(player); + } +} diff --git a/forestry_common/apiculture/forestry/apiculture/MaterialBeehive.java b/forestry_common/apiculture/forestry/apiculture/MaterialBeehive.java new file mode 100755 index 000000000..2f2e911aa --- /dev/null +++ b/forestry_common/apiculture/forestry/apiculture/MaterialBeehive.java @@ -0,0 +1,22 @@ +/******************************************************************************* + * Copyright 2011-2014 by SirSengir + * + * This work is licensed under a Creative Commons Attribution-NonCommercial-NoDerivs 3.0 Unported License. + * + * To view a copy of this license, visit http://creativecommons.org/licenses/by-nc-nd/3.0/. + ******************************************************************************/ +package forestry.apiculture; + +import net.minecraft.block.material.MapColor; +import net.minecraft.block.material.Material; + +public class MaterialBeehive extends Material { + + public MaterialBeehive(boolean noHarvest) { + super(MapColor.stoneColor); + if (noHarvest) + this.setRequiresTool(); + setImmovableMobility(); + } + +} diff --git a/forestry_common/apiculture/forestry/apiculture/PacketHandlerApiculture.java b/forestry_common/apiculture/forestry/apiculture/PacketHandlerApiculture.java new file mode 100755 index 000000000..8b3ea1cac --- /dev/null +++ b/forestry_common/apiculture/forestry/apiculture/PacketHandlerApiculture.java @@ -0,0 +1,51 @@ +/******************************************************************************* + * Copyright 2011-2014 by SirSengir + * + * This work is licensed under a Creative Commons Attribution-NonCommercial-NoDerivs 3.0 Unported License. + * + * To view a copy of this license, visit http://creativecommons.org/licenses/by-nc-nd/3.0/. + ******************************************************************************/ +package forestry.apiculture; + +import java.io.DataInputStream; + +import net.minecraft.entity.player.EntityPlayer; + +import forestry.apiculture.gui.ContainerImprinter; +import forestry.core.interfaces.IPacketHandler; +import forestry.core.network.PacketCoordinates; +import forestry.core.network.PacketIds; +import forestry.core.proxy.Proxies; + +public class PacketHandlerApiculture implements IPacketHandler { + + @Override + public void onPacketData(int packetID, DataInputStream data, EntityPlayer player) { + + try { + + switch (packetID) { + case PacketIds.HABITAT_BIOME_POINTER: + PacketCoordinates packetC = new PacketCoordinates(); + packetC.readData(data); + Proxies.common.setBiomefinderCoordinates(player, packetC.getCoordinates()); + break; + case PacketIds.IMPRINT_SELECTION_GET: + onImprintSelectionGet(player); + break; + } + } catch (Exception ex) { + ex.printStackTrace(); + } + } + + private void onImprintSelectionGet(EntityPlayer playerEntity) { + + if (!(playerEntity.openContainer instanceof ContainerImprinter)) + return; + + ((ContainerImprinter) playerEntity.openContainer).sendSelection(playerEntity); + + } + +} diff --git a/forestry_common/apiculture/forestry/apiculture/SaveEventHandlerApiculture.java b/forestry_common/apiculture/forestry/apiculture/SaveEventHandlerApiculture.java new file mode 100755 index 000000000..13daf87ad --- /dev/null +++ b/forestry_common/apiculture/forestry/apiculture/SaveEventHandlerApiculture.java @@ -0,0 +1,30 @@ +/******************************************************************************* + * Copyright 2011-2014 by SirSengir + * + * This work is licensed under a Creative Commons Attribution-NonCommercial-NoDerivs 3.0 Unported License. + * + * To view a copy of this license, visit http://creativecommons.org/licenses/by-nc-nd/3.0/. + ******************************************************************************/ +package forestry.apiculture; + +import net.minecraft.world.World; + +import forestry.core.interfaces.ISaveEventHandler; +import forestry.plugins.PluginApiculture; + +public class SaveEventHandlerApiculture implements ISaveEventHandler { + + @Override + public void onWorldLoad(World world) { + PluginApiculture.beeInterface.resetBeekeepingMode(); + } + + @Override + public void onWorldSave(World world) { + } + + @Override + public void onWorldUnload(World world) { + } + +} diff --git a/forestry_common/apiculture/forestry/apiculture/SpeciesNotFoundException.java b/forestry_common/apiculture/forestry/apiculture/SpeciesNotFoundException.java new file mode 100755 index 000000000..99d47b8a3 --- /dev/null +++ b/forestry_common/apiculture/forestry/apiculture/SpeciesNotFoundException.java @@ -0,0 +1,20 @@ +/******************************************************************************* + * Copyright 2011-2014 by SirSengir + * + * This work is licensed under a Creative Commons Attribution-NonCommercial-NoDerivs 3.0 Unported License. + * + * To view a copy of this license, visit http://creativecommons.org/licenses/by-nc-nd/3.0/. + ******************************************************************************/ +package forestry.apiculture; + +import net.minecraft.command.CommandException; + +public class SpeciesNotFoundException extends CommandException { + + private static final long serialVersionUID = 1L; + + public SpeciesNotFoundException(String title) { + super("Could not find bee species with Name or UID %s", title); + } + +} diff --git a/forestry_common/apiculture/forestry/apiculture/TemplateNotFoundException.java b/forestry_common/apiculture/forestry/apiculture/TemplateNotFoundException.java new file mode 100755 index 000000000..6f05e7401 --- /dev/null +++ b/forestry_common/apiculture/forestry/apiculture/TemplateNotFoundException.java @@ -0,0 +1,22 @@ +/******************************************************************************* + * Copyright 2011-2014 by SirSengir + * + * This work is licensed under a Creative Commons Attribution-NonCommercial-NoDerivs 3.0 Unported License. + * + * To view a copy of this license, visit http://creativecommons.org/licenses/by-nc-nd/3.0/. + ******************************************************************************/ +package forestry.apiculture; + +import net.minecraft.command.CommandException; + +import forestry.api.genetics.IAlleleSpecies; + +public class TemplateNotFoundException extends CommandException { + + private static final long serialVersionUID = 1L; + + public TemplateNotFoundException(IAlleleSpecies species) { + super("Could not find template for species %s with UID %s", species.getName(), species.getUID()); + } + +} diff --git a/forestry_common/apiculture/forestry/apiculture/VillageHandlerApiculture.java b/forestry_common/apiculture/forestry/apiculture/VillageHandlerApiculture.java new file mode 100755 index 000000000..c5f711fb8 --- /dev/null +++ b/forestry_common/apiculture/forestry/apiculture/VillageHandlerApiculture.java @@ -0,0 +1,74 @@ +/******************************************************************************* + * Copyright 2011-2014 by SirSengir + * + * This work is licensed under a Creative Commons Attribution-NonCommercial-NoDerivs 3.0 Unported License. + * + * To view a copy of this license, visit http://creativecommons.org/licenses/by-nc-nd/3.0/. + ******************************************************************************/ +package forestry.apiculture; + +import java.util.List; +import java.util.Random; + +import net.minecraft.entity.passive.EntityVillager; +import net.minecraft.init.Blocks; +import net.minecraft.init.Items; +import net.minecraft.item.ItemStack; +import net.minecraft.util.MathHelper; +import net.minecraft.village.MerchantRecipe; +import net.minecraft.village.MerchantRecipeList; +import net.minecraft.world.gen.structure.MapGenStructureIO; +import net.minecraft.world.gen.structure.StructureVillagePieces; + +import cpw.mods.fml.common.registry.VillagerRegistry.IVillageCreationHandler; +import cpw.mods.fml.common.registry.VillagerRegistry.IVillageTradeHandler; + +import forestry.api.apiculture.EnumBeeType; +import forestry.apiculture.genetics.BeeTemplates; +import forestry.apiculture.items.ItemHoneycomb; +import forestry.apiculture.worldgen.ComponentVillageBeeHouse; +import forestry.core.config.Defaults; +import forestry.core.config.ForestryBlock; +import forestry.core.config.ForestryItem; +import forestry.plugins.PluginApiculture; + +public class VillageHandlerApiculture implements IVillageCreationHandler, IVillageTradeHandler { + + public static void registerVillageComponents() { + try { + MapGenStructureIO.func_143031_a(ComponentVillageBeeHouse.class, "Forestry:BeeHouse"); + } catch (Throwable e) { + } + } + + @SuppressWarnings("unchecked") + @Override + public void manipulateTradesForVillager(EntityVillager villager, MerchantRecipeList recipeList, Random random) { + recipeList.add(new MerchantRecipe(ForestryItem.beePrincessGE.getItemStack(1, Defaults.WILDCARD), new ItemStack(Items.emerald, 1))); + recipeList.add(new MerchantRecipe(new ItemStack(Items.wheat, 2), ItemHoneycomb.getRandomComb(1, random, false))); + recipeList.add(new MerchantRecipe(new ItemStack(Blocks.log, 24, Defaults.WILDCARD), new ItemStack(ForestryBlock.apiculture, 1, + Defaults.DEFINITION_APIARY_META))); + recipeList.add(new MerchantRecipe(new ItemStack(Items.emerald, 1), ForestryItem.frameProven.getItemStack(6))); + recipeList.add(new MerchantRecipe(new ItemStack(Items.emerald, 12), ForestryItem.beePrincessGE.getItemStack(1, Defaults.WILDCARD), + PluginApiculture.beeInterface.getMemberStack( + PluginApiculture.beeInterface.getBee(villager.worldObj, PluginApiculture.beeInterface.templateAsGenome(BeeTemplates.getMonasticTemplate())), + EnumBeeType.DRONE.ordinal()))); + } + + @Override + public StructureVillagePieces.PieceWeight getVillagePieceWeight(Random random, int size) { + return new StructureVillagePieces.PieceWeight(ComponentVillageBeeHouse.class, 15, MathHelper.getRandomIntegerInRange(random, 0 + size, 1 + size)); + } + + @Override + public Class getComponentClass() { + return ComponentVillageBeeHouse.class; + } + + @SuppressWarnings("rawtypes") + @Override + public Object buildComponent(StructureVillagePieces.PieceWeight villagePiece, StructureVillagePieces.Start startPiece, List pieces, Random random, int p1, int p2, + int p3, int p4, int p5) { + return ComponentVillageBeeHouse.buildComponent(startPiece, pieces, random, p1, p2, p3, p4, p5); + } +} diff --git a/forestry_common/apiculture/forestry/apiculture/entities/EntityBee.java b/forestry_common/apiculture/forestry/apiculture/entities/EntityBee.java new file mode 100755 index 000000000..8e765e4e7 --- /dev/null +++ b/forestry_common/apiculture/forestry/apiculture/entities/EntityBee.java @@ -0,0 +1,88 @@ +/******************************************************************************* + * Copyright 2011-2014 by SirSengir + * + * This work is licensed under a Creative Commons Attribution-NonCommercial-NoDerivs 3.0 Unported License. + * + * To view a copy of this license, visit http://creativecommons.org/licenses/by-nc-nd/3.0/. + ******************************************************************************/ +package forestry.apiculture.entities; + +import net.minecraft.entity.EntityCreature; +import net.minecraft.entity.passive.IAnimals; +import net.minecraft.util.ResourceLocation; +import net.minecraft.world.World; + +import cpw.mods.fml.relauncher.Side; +import cpw.mods.fml.relauncher.SideOnly; + +import forestry.api.apiculture.EnumBeeType; +import forestry.api.apiculture.IAlleleBeeSpecies; +import forestry.api.apiculture.IBee; +import forestry.core.config.Defaults; +import forestry.core.utils.ForestryResource; +import forestry.plugins.PluginApiculture; + +public class EntityBee extends EntityCreature implements IAnimals { + + private static final String DEFAULT_TEXTURE = Defaults.TEXTURE_PATH_ENTITIES + "/bees/honeyBee.png"; + + IBee contained; + IAlleleBeeSpecies species; + EnumBeeType type = EnumBeeType.DRONE; + + private String beeTexture = DEFAULT_TEXTURE; + private long lastUpdate; + + public EntityBee(World world) { + super(world); + } + + private void resetAppearance() { + beeTexture = species.getEntityTexture(); + } + + public EntityBee setIndividual(IBee bee) { + if(bee != null) + contained = bee; + else + contained = PluginApiculture.beeInterface.templateAsIndividual(PluginApiculture.beeInterface.getDefaultTemplate()); + + //isImmuneToFire = contained.getGenome().getFireResist(); + setSpecies(contained.getGenome().getPrimary()); + //dataWatcher.updateObject(DATAWATCHER_ID_SPECIES, species.getUID()); + //dataWatcher.updateObject(DATAWATCHER_ID_SCALE, (int)(contained.getSize() * 100)); + return this; + } + + public IBee getBee() { + return contained; + } + + public EntityBee setType(EnumBeeType type) { + this.type = type; + return this; + } + + public EnumBeeType getType() { + return type; + } + + public EntityBee setSpecies(IAlleleBeeSpecies species) { + this.species = species; + resetAppearance(); + lastUpdate = worldObj.getTotalWorldTime(); + return this; + } + + @SideOnly(Side.CLIENT) + private ResourceLocation textureResource; + private long lastTextureUpdate; + @SideOnly(Side.CLIENT) + public ResourceLocation getTexture() { + if(textureResource == null || lastTextureUpdate != lastUpdate) + textureResource = new ForestryResource(beeTexture); + + return textureResource; + } + +} diff --git a/forestry_common/apiculture/forestry/apiculture/gadgets/BlockAlveary.java b/forestry_common/apiculture/forestry/apiculture/gadgets/BlockAlveary.java new file mode 100755 index 000000000..00b42a0b4 --- /dev/null +++ b/forestry_common/apiculture/forestry/apiculture/gadgets/BlockAlveary.java @@ -0,0 +1,229 @@ +/******************************************************************************* + * Copyright 2011-2014 by SirSengir + * + * This work is licensed under a Creative Commons Attribution-NonCommercial-NoDerivs 3.0 Unported License. + * + * To view a copy of this license, visit http://creativecommons.org/licenses/by-nc-nd/3.0/. + ******************************************************************************/ +package forestry.apiculture.gadgets; + +import java.util.ArrayList; +import java.util.List; + +import net.minecraft.block.Block; +import net.minecraft.client.renderer.texture.IIconRegister; +import net.minecraft.creativetab.CreativeTabs; +import net.minecraft.item.Item; +import net.minecraft.item.ItemStack; +import net.minecraft.tileentity.TileEntity; +import net.minecraft.util.IIcon; +import net.minecraft.world.IBlockAccess; +import net.minecraft.world.World; + +import cpw.mods.fml.relauncher.Side; +import cpw.mods.fml.relauncher.SideOnly; + +import forestry.api.core.Tabs; +import forestry.apiculture.MaterialBeehive; +import forestry.core.gadgets.BlockStructure; +import forestry.core.render.TextureManager; + +public class BlockAlveary extends BlockStructure { + + public BlockAlveary() { + super(new MaterialBeehive(false)); + setHardness(1.0f); + setCreativeTab(Tabs.tabApiculture); + } + + @SuppressWarnings({ "rawtypes", "unchecked" }) + @Override + @SideOnly(Side.CLIENT) + public void getSubBlocks(Item item, CreativeTabs tab, List list) { + for (int i = 0; i < 8; i++) { + if (i == 1) + continue; + list.add(new ItemStack(item, 1, i)); + } + } + + @Override + public int getRenderType() { + return 0; + } + + @Override + public boolean renderAsNormalBlock() { + return true; + } + + @Override + public ArrayList getDrops(World world, int x, int y, int z, int metadata, int fortune) { + ArrayList drop = new ArrayList(); + drop.add(new ItemStack(this, 1, metadata != 1 ? metadata : 0)); + return drop; + } + + @Override + public int getDamageValue(World world, int x, int y, int z) { + int meta = world.getBlockMetadata(x, y, z); + return meta != 1 ? meta : 0; + } + + /* TILE ENTITY CREATION */ + @Override + public TileEntity createTileEntity(World world, int metadata) { + switch (metadata) { + case TileAlvearySwarmer.BLOCK_META: + return new TileAlvearySwarmer(); + case TileAlvearyFan.BLOCK_META: + return new TileAlvearyFan(); + case TileAlvearyHeater.BLOCK_META: + return new TileAlvearyHeater(); + case TileAlvearyHygroregulator.BLOCK_META: + return new TileAlvearyHygroregulator(); + case TileAlvearyStabiliser.BLOCK_META: + return new TileAlvearyStabiliser(); + case TileAlvearySieve.BLOCK_META: + return new TileAlvearySieve(); + default: + return new TileAlvearyPlain(); + } + } + + @Override + public TileEntity createNewTileEntity(World world, int meta) { + return createTileEntity(world, meta); + } + + /* ICONS */ + public static final int PLAIN = 0; + public static final int ENTRANCE = 1; + public static final int BOTTOM = 2; + public static final int LEFT = 3; + public static final int RIGHT = 4; + public static final int TX_55_SWOF = 5; + public static final int TX_56_SWON = 6; + public static final int TX_57_HTOF = 7; + public static final int TX_58_HTON = 8; + public static final int TX_71_FNOF = 9; + public static final int TX_72_FNON = 10; + public static final int TX_73_VLVE = 11; + public static final int STABILISER = 12; + public static final int SIEVE = 13; + + @SideOnly(Side.CLIENT) + private IIcon[] icons; + + @SideOnly(Side.CLIENT) + @Override + public void registerBlockIcons(IIconRegister register) { + icons = new IIcon[14]; + icons[0] = TextureManager.getInstance().registerTex(register, "apiculture/alveary.plain"); + icons[1] = TextureManager.getInstance().registerTex(register, "apiculture/alveary.entrance"); + icons[2] = TextureManager.getInstance().registerTex(register, "apiculture/alveary.bottom"); + icons[3] = TextureManager.getInstance().registerTex(register, "apiculture/alveary.left"); + icons[4] = TextureManager.getInstance().registerTex(register, "apiculture/alveary.right"); + icons[5] = TextureManager.getInstance().registerTex(register, "apiculture/alveary.swarmer.off"); + icons[6] = TextureManager.getInstance().registerTex(register, "apiculture/alveary.swarmer.on"); + icons[7] = TextureManager.getInstance().registerTex(register, "apiculture/alveary.heater.off"); + icons[8] = TextureManager.getInstance().registerTex(register, "apiculture/alveary.heater.on"); + icons[9] = TextureManager.getInstance().registerTex(register, "apiculture/alveary.fan.off"); + icons[10] = TextureManager.getInstance().registerTex(register, "apiculture/alveary.fan.on"); + icons[11] = TextureManager.getInstance().registerTex(register, "apiculture/alveary.valve"); + icons[12] = TextureManager.getInstance().registerTex(register, "apiculture/alveary.stabiliser"); + icons[13] = TextureManager.getInstance().registerTex(register, "apiculture/alveary.sieve"); + } + + @SideOnly(Side.CLIENT) + @Override + public IIcon getIcon(int side, int metadata) { + if ((metadata <= 1 + || metadata == TileAlvearySieve.BLOCK_META || metadata == TileAlvearySwarmer.BLOCK_META || metadata == TileAlvearyStabiliser.BLOCK_META) + && (side == 1 || side == 0)) + return icons[BOTTOM]; + + switch (metadata) { + case 1: + return icons[ENTRANCE]; + case TileAlvearySwarmer.BLOCK_META: + return icons[TX_55_SWOF]; + case TileAlvearyFan.BLOCK_META: + return icons[TX_71_FNOF]; + case TileAlvearyHeater.BLOCK_META: + return icons[TX_57_HTOF]; + case TileAlvearyHygroregulator.BLOCK_META: + return icons[TX_73_VLVE]; + case TileAlvearyStabiliser.BLOCK_META: + return icons[STABILISER]; + case TileAlvearySieve.BLOCK_META: + return icons[SIEVE]; + default: + return icons[PLAIN]; + } + + } + + @SideOnly(Side.CLIENT) + @Override + public IIcon getIcon(IBlockAccess world, int x, int y, int z, int side) { + int meta = world.getBlockMetadata(x, y, z); + + if (meta == 1) + return this.getIcon(side, meta); + else if (meta > 1) + return getBlockTextureFromSideAndTile(world, x, y, z, side); + + Block blockXP = world.getBlock(x + 1, y, z); + Block blockXM = world.getBlock(x - 1, y, z); + + if (blockXP == this && blockXM != this) { + + if (world.getBlockMetadata(x + 1, y, z) == 1) { + + if (world.getBlock(x, y, z + 1) != this) + return switchForSide(42, side); + else + return switchForSide(41, side); + + } else + return this.getIcon(side, meta); + + } else if (blockXP != this && blockXM == this) + if (world.getBlockMetadata(x - 1, y, z) == 1) { + + if (world.getBlock(x, y, z + 1) != this) + return switchForSide(41, side); + else + return switchForSide(42, side); + + } else + return this.getIcon(side, meta); + + return this.getIcon(side, meta); + } + + @SideOnly(Side.CLIENT) + private IIcon getBlockTextureFromSideAndTile(IBlockAccess world, int x, int y, int z, int side) { + TileEntity tile = world.getTileEntity(x, y, z); + if (tile == null || !(tile instanceof TileAlveary)) + return getIcon(side, 0); + + return icons[((TileAlveary) tile).getIcon(side, world.getBlockMetadata(x, y, z))]; + } + + @SideOnly(Side.CLIENT) + private IIcon switchForSide(int textureId, int side) { + + if (side == 4 || side == 5) { + if (textureId == 41) + return icons[LEFT]; + else + return icons[RIGHT]; + } else if (textureId == 41) + return icons[RIGHT]; + else + return icons[LEFT]; + + } +} diff --git a/forestry_common/apiculture/forestry/apiculture/gadgets/BlockBeehives.java b/forestry_common/apiculture/forestry/apiculture/gadgets/BlockBeehives.java new file mode 100755 index 000000000..97c4fce26 --- /dev/null +++ b/forestry_common/apiculture/forestry/apiculture/gadgets/BlockBeehives.java @@ -0,0 +1,166 @@ +/******************************************************************************* + * Copyright 2011-2014 by SirSengir + * + * This work is licensed under a Creative Commons Attribution-NonCommercial-NoDerivs 3.0 Unported License. + * + * To view a copy of this license, visit http://creativecommons.org/licenses/by-nc-nd/3.0/. + ******************************************************************************/ +package forestry.apiculture.gadgets; + +import java.util.ArrayList; +import java.util.Collections; +import java.util.List; + +import net.minecraft.block.BlockContainer; +import net.minecraft.client.renderer.texture.IIconRegister; +import net.minecraft.creativetab.CreativeTabs; +import net.minecraft.entity.Entity; +import net.minecraft.entity.player.EntityPlayer; +import net.minecraft.item.Item; +import net.minecraft.item.ItemStack; +import net.minecraft.tileentity.TileEntity; +import net.minecraft.util.IIcon; +import net.minecraft.world.IBlockAccess; +import net.minecraft.world.World; + +import cpw.mods.fml.relauncher.Side; +import cpw.mods.fml.relauncher.SideOnly; + +import forestry.api.apiculture.BeeManager; +import forestry.api.apiculture.IHiveDrop; +import forestry.api.core.Tabs; +import forestry.apiculture.MaterialBeehive; +import forestry.core.config.Config; +import forestry.core.render.TextureManager; +import forestry.core.utils.StackUtils; + +public class BlockBeehives extends BlockContainer { + + public BlockBeehives() { + super(new MaterialBeehive(true)); + setLightLevel(0.8f); + setHardness(1.0f); + setCreativeTab(Tabs.tabApiculture); + } + + @Override + public TileEntity createNewTileEntity(World world, int meta) { + return new TileSwarm(); + } + + @Override + public boolean canEntityDestroy(IBlockAccess world, int x, int y, int z, Entity entity) { + return false; + } + + @Override + public boolean removedByPlayer(World world, EntityPlayer player, int x, int y, int z) { + if (canHarvestBlock(player, world.getBlockMetadata(x, y, z))) { + // Handle TE'd beehives + TileEntity tile = world.getTileEntity(x, y, z); + + if (tile instanceof TileSwarm) { + TileSwarm swarm = (TileSwarm) tile; + if (swarm.containsBees()) + for (ItemStack beeStack : swarm.contained.getStacks()) + if (beeStack != null) + StackUtils.dropItemStackAsEntity(beeStack, world, x, y, z); + } + } + + return world.setBlockToAir(x, y, z); + } + + @Override + public ArrayList getDrops(World world, int x, int y, int z, int metadata, int fortune) { + ArrayList ret = new ArrayList(); + + // Handle legacy block + if (metadata == 0) { + ret.add(new ItemStack(this)); + return ret; + } + + ArrayList dropList = BeeManager.hiveDrops[metadata - 1]; + + Collections.shuffle(dropList); + // Grab a princess + int tries = 0; + boolean hasPrincess = false; + while (tries <= 10 && !hasPrincess) { + tries++; + + for (IHiveDrop drop : dropList) + if (world.rand.nextInt(100) < drop.getChance(world, x, y, z)) { + ret.add(drop.getPrincess(world, x, y, z, fortune)); + hasPrincess = true; + break; + } + } + + // Grab drones + for (IHiveDrop drop : dropList) + if (world.rand.nextInt(100) < drop.getChance(world, x, y, z)) { + ret.addAll(drop.getDrones(world, x, y, z, fortune)); + break; + } + // Grab anything else on offer + for (IHiveDrop drop : dropList) + if (world.rand.nextInt(100) < drop.getChance(world, x, y, z)) { + ret.addAll(drop.getAdditional(world, x, y, z, fortune)); + break; + } + + return ret; + } + + // / CREATIVE INVENTORY + @Override + public int damageDropped(int meta) { + return meta; + } + + @SuppressWarnings({ "rawtypes", "unchecked" }) + @Override + public void getSubBlocks(Item item, CreativeTabs par2CreativeTabs, List itemList) { + itemList.add(new ItemStack(this, 1, 1)); + itemList.add(new ItemStack(this, 1, 2)); + itemList.add(new ItemStack(this, 1, 3)); + itemList.add(new ItemStack(this, 1, 4)); + if (Config.isDebug) { + itemList.add(new ItemStack(this, 1 ,5)); + } + itemList.add(new ItemStack(this, 1, 6)); + itemList.add(new ItemStack(this, 1, 7)); + // Swarm hive not added + } + + /* ICONS */ + @SideOnly(Side.CLIENT) + private IIcon[] icons; + + @Override + @SideOnly(Side.CLIENT) + public void registerBlockIcons(IIconRegister register) { + icons = new IIcon[18]; + for (int i = 1; i < 9; i++) { + icons[i * 2] = TextureManager.getInstance().registerTex(register, "beehives/beehive." + i + ".top"); + icons[(i * 2) + 1] = TextureManager.getInstance().registerTex(register, "beehives/beehive." + i + ".side"); + } + } + + @Override + @SideOnly(Side.CLIENT) + public IIcon getIcon(int i, int j) { + if (i == 0 || i == 1) { + if (j * 2 < icons.length && icons[j * 2] != null) + return icons[j * 2]; + else + return icons[2]; + } else if (j * 2 + 1 < icons.length && icons[j * 2 + 1] != null) + return icons[j * 2 + 1]; + else + return icons[3]; + } + +} diff --git a/forestry_common/apiculture/forestry/apiculture/gadgets/BlockCandle.java b/forestry_common/apiculture/forestry/apiculture/gadgets/BlockCandle.java new file mode 100755 index 000000000..899eae65b --- /dev/null +++ b/forestry_common/apiculture/forestry/apiculture/gadgets/BlockCandle.java @@ -0,0 +1,416 @@ +/******************************************************************************* + * Copyright 2011-2014 by SirSengir + * + * This work is licensed under a Creative Commons Attribution-NonCommercial-NoDerivs 3.0 Unported License. + * + * To view a copy of this license, visit http://creativecommons.org/licenses/by-nc-nd/3.0/. + ******************************************************************************/ +package forestry.apiculture.gadgets; + +import java.util.ArrayList; +import java.util.List; +import java.util.Random; + +import net.minecraft.block.Block; +import net.minecraft.block.BlockTorch; +import net.minecraft.client.renderer.texture.IIconRegister; +import net.minecraft.creativetab.CreativeTabs; +import net.minecraft.entity.EntityLivingBase; +import net.minecraft.entity.player.EntityPlayer; +import net.minecraft.init.Blocks; +import net.minecraft.init.Items; +import net.minecraft.item.Item; +import net.minecraft.item.ItemStack; +import net.minecraft.nbt.NBTTagCompound; +import net.minecraft.tileentity.TileEntity; +import net.minecraft.util.IIcon; +import net.minecraft.world.IBlockAccess; +import net.minecraft.world.World; + +import cpw.mods.fml.relauncher.Side; +import cpw.mods.fml.relauncher.SideOnly; + +import net.minecraftforge.common.util.ForgeDirection; +import net.minecraftforge.oredict.OreDictionary; + +import forestry.api.core.Tabs; +import forestry.core.ForestryClient; +import forestry.core.config.Defaults; +import forestry.core.render.TextureManager; +import forestry.core.utils.StackUtils; + +public class BlockCandle extends BlockTorch { + + private final ArrayList lightingItems = new ArrayList(); + + @SideOnly(Side.CLIENT) + private IIcon litStump; + @SideOnly(Side.CLIENT) + private IIcon litTip; + @SideOnly(Side.CLIENT) + private IIcon unlitStump; + @SideOnly(Side.CLIENT) + private IIcon unlitTip; + + public BlockCandle() { + super(); + this.setHardness(0.0F); + this.setStepSound(soundTypeWood); + setCreativeTab(Tabs.tabApiculture); + + lightingItems.add(Items.flint_and_steel); + lightingItems.add(Items.flint); + lightingItems.add(Item.getItemFromBlock(Blocks.torch)); + } + + @Override + public boolean hasTileEntity(int metadata) { + return true; + } + + @Override + public TileEntity createTileEntity(World world, int metadata) { + return new TileCandle(); + } + + @Override + public int getRenderType() { + return ForestryClient.candleRenderId; + } + + @SideOnly(Side.CLIENT) + @Override + public void registerBlockIcons(IIconRegister register) { + String fileBase = this.getUnlocalizedName().replace("tile.", ""); + this.blockIcon = TextureManager.getInstance().registerTex(register, "stump"); + this.litStump = TextureManager.getInstance().registerTex(register, fileBase + "StumpLit"); + this.litTip = TextureManager.getInstance().registerTex(register, fileBase + "TipLit"); + this.unlitStump = TextureManager.getInstance().registerTex(register, fileBase + "StumpUnlit"); + this.unlitTip = TextureManager.getInstance().registerTex(register, fileBase + "TipUnlit"); + } + + @Override + public int getLightValue(IBlockAccess world, int x, int y, int z) { + int meta = world.getBlockMetadata(x, y, z); + return (isLit(meta))? 14 : 0; + } + + /*@SideOnly(Side.CLIENT) + @Override + public IIcon getIcon(IBlockAccess world, int x, int y, int z, int side) { + IIcon i = this.unlitStump; + if (this.isLit(world.getBlockMetadata(x, y, z))) { + i = this.litStump; + } + return i; + }*/ + + @SideOnly(Side.CLIENT) + public IIcon getTextureFromPassAndMeta(int meta, int pass) { + IIcon i = this.unlitStump; + if (pass == 0) { + if (isLit(meta)) { + i = this.litTip; + } + else { + i = this.unlitTip; + } + } + else { + if (isLit(meta)) { + i = this.litStump; + } + else { + i = this.unlitStump; + } + } + return i; + } + + public int getColourFromItemStack(ItemStack stack) { + int colour = 0xffffff; + if (stack.hasTagCompound()) { + NBTTagCompound tag = stack.getTagCompound(); + colour = (tag.getByte("red") << 16) | (tag.getByte("green") << 8) | tag.getByte("blue"); + } + return colour; + } + + @SuppressWarnings({ "rawtypes", "unchecked" }) + @Override + public void getSubBlocks(Item item, CreativeTabs par2CreativeTabs, List itemList) { + itemList.add(new ItemStack(this, 1, 0)); + } + + // Dye names correspond to colour values as below. + private static final String[] dyes = { "dyeWhite", "dyeOrange", "dyeMagenta", "dyeLightBlue", + "dyeYellow", "dyeLime", "dyePink", "dyeGray", + "dyeLightGray", "dyeCyan", "dyePurple", "dyeBlue", + "dyeBrown", "dyeGreen", "dyeRed", "dyeBlack" }; + + private static final int[][] colours = { { 255, 255, 255 } , { 219, 125, 62 } , { 255, 20, 255 } , { 107, 138, 201 } , + { 255, 255, 20 } , { 20, 255, 20 } , { 208, 132, 153 } , { 74, 74, 74 } , + { 154, 161, 161 } , { 20, 255, 255 } , { 126, 61, 181 } , { 20, 20, 255 } , + { 79, 50, 31 } , { 53, 70, 27 } , { 150, 52, 48 } , { 20, 20, 20 } }; + + public static final String colourTagName = "colour"; + + @Override + public boolean onBlockActivated(World world, int x, int y, int z, EntityPlayer player, int facing, float facingX, float facingY, float facingZ) { + boolean flag = false; + int meta = world.getBlockMetadata(x, y, z); + boolean toggleLitState = true; + ItemStack held = player.getCurrentEquippedItem(); + + if (!isLit(meta)) { + if (held == null || !lightingItems.contains(held.getItem())) { + toggleLitState = false; + } + else if (StackUtils.equals(this, held) && isLit(held)) { + toggleLitState = true; + } + } + + if (held != null) { + // Ensure a TileEntity exists. May be able to remove this in future versions. + TileCandle te = (TileCandle)world.getTileEntity(x, y, z); + if (te == null) { + world.setTileEntity(x, y, z, this.createTileEntity(world, meta)); + } + + if (StackUtils.equals(this, held)) { + if (!isLit(held)) { + // Copy the colour of an unlit, coloured candle. + if (held.hasTagCompound() && held.getTagCompound().hasKey(colourTagName)) { + te.setColour(held.getTagCompound().getInteger(colourTagName)); + } + else { + // Reset to white if item has no + te.setColour(0xffffff); + } + } + else { + toggleLitState = true; + } + flag = true; + } + else { + // Check for dye-able ness. + boolean matched = false; + for (int i = 0; i < dyes.length; ++i) { + for (ItemStack stack : OreDictionary.getOres(dyes[i])) { + if (OreDictionary.itemMatches(stack, held, true)) { + if (isLit(meta)) { + te.setColour(colours[i][0], colours[i][1], colours[i][2]); + } + else { + te.addColour(colours[i][0], colours[i][1], colours[i][2]); + } + world.markBlockForUpdate(x, y, z); + matched = true; + toggleLitState = false; + flag = true; + break; + } + } + if (matched) { + break; + } + } + } + } + + if (toggleLitState) { + meta = this.toggleLitStatus(meta); + world.setBlockMetadataWithNotify(x, y, z, meta, Defaults.FLAG_BLOCK_SYNCH | Defaults.FLAG_BLOCK_UPDATE); + flag = true; + } + return flag; + } + + @Override + public void breakBlock(World world, int x, int y, int z, Block block, int meta) { + if (!world.isRemote) { + TileCandle tc = (TileCandle)world.getTileEntity(x, y, z); + int newMeta = isLit(meta) ? 1 : 0; + ItemStack stack = new ItemStack(this, 1, newMeta); + if (tc != null && tc.getColour() != 0xffffff) { + // When dropped, tag new item stack with colour. Unless it's white, then do no such thing for maximum stacking. + NBTTagCompound tag = new NBTTagCompound(); + tag.setInteger(colourTagName, tc.getColour()); + stack.setTagCompound(tag); + } + this.dropBlockAsItem(world, x, y, z, stack); + } + super.breakBlock(world, x, y, z, block, meta); + } + + @Override + public void onBlockPlacedBy(World world, int x, int y, int z, EntityLivingBase player, ItemStack itemStack) { + TileCandle tc = (TileCandle)(world.getTileEntity(x, y, z)); + tc.setColour(this.getColourValueFromItemStack(itemStack)); + if (isLit(itemStack)) { + int meta = world.getBlockMetadata(x, y, z); + world.setBlockMetadataWithNotify(x, y, z, this.toggleLitStatus(meta), Defaults.FLAG_BLOCK_SYNCH | Defaults.FLAG_BLOCK_UPDATE); + } + } + + @Override + public void dropBlockAsItemWithChance(World par1World, int par2, int par3, int par4, int par5, float par6, int par7) { + // Does nothing to prevent extra candles from falling. + } + + @Override + public void onBlockHarvested(World par1World, int par2, int par3, int par4, int par5, EntityPlayer par6EntityPlayer) { + // Does nothing to prevent extra candles from falling. + } + + @Override + protected boolean func_150109_e(World world, int x, int y, int z) { + // Slightly tweaked version of BlockTorch's version to account for TE nonsense. + if (!this.canPlaceBlockAt(world, x, y, z)) { + if (world.getBlock(x, y, z) == this) { + world.setBlockToAir(x, y, z); + } + return false; + } + else { + return true; + } + } + + @Override + @SideOnly(Side.CLIENT) + public void randomDisplayTick(World world, int x, int y, int z, Random random) { + if (isLit(world.getBlockMetadata(x, y, z))) { + int l = world.getBlockMetadata(x, y, z) & 0x07; + double d0 = x + 0.5F; + double d1 = y + 0.7F; + double d2 = z + 0.5F; + double d3 = 0.2199999988079071D; + double d4 = 0.27000001072883606D; + + if (l == 1) + { + world.spawnParticle("smoke", d0 - d4, d1 + d3, d2, 0.0D, 0.0D, 0.0D); + world.spawnParticle("flame", d0 - d4, d1 + d3, d2, 0.0D, 0.0D, 0.0D); + } + else if (l == 2) + { + world.spawnParticle("smoke", d0 + d4, d1 + d3, d2, 0.0D, 0.0D, 0.0D); + world.spawnParticle("flame", d0 + d4, d1 + d3, d2, 0.0D, 0.0D, 0.0D); + } + else if (l == 3) + { + world.spawnParticle("smoke", d0, d1 + d3, d2 - d4, 0.0D, 0.0D, 0.0D); + world.spawnParticle("flame", d0, d1 + d3, d2 - d4, 0.0D, 0.0D, 0.0D); + } + else if (l == 4) + { + world.spawnParticle("smoke", d0, d1 + d3, d2 + d4, 0.0D, 0.0D, 0.0D); + world.spawnParticle("flame", d0, d1 + d3, d2 + d4, 0.0D, 0.0D, 0.0D); + } + else + { + world.spawnParticle("smoke", d0, d1, d2, 0.0D, 0.0D, 0.0D); + world.spawnParticle("flame", d0, d1, d2, 0.0D, 0.0D, 0.0D); + } + } + } + + @Override + protected boolean func_150108_b(World par1World, int par2, int par3, int par4, Block block) + { + if (this.func_150109_e(par1World, par2, par3, par4)) + { + int i1 = par1World.getBlockMetadata(par2, par3, par4) & 0x07; + boolean flag = false; + + if (!par1World.isSideSolid(par2 - 1, par3, par4, ForgeDirection.EAST, true) && i1 == 1) + { + flag = true; + } + + if (!par1World.isSideSolid(par2 + 1, par3, par4, ForgeDirection.WEST, true) && i1 == 2) + { + flag = true; + } + + if (!par1World.isSideSolid(par2, par3, par4 - 1, ForgeDirection.SOUTH, true) && i1 == 3) + { + flag = true; + } + + if (!par1World.isSideSolid(par2, par3, par4 + 1, ForgeDirection.NORTH, true) && i1 == 4) + { + flag = true; + } + + if (!this.canPlaceTorchOn(par1World, par2, par3 - 1, par4) && i1 == 5) + { + flag = true; + } + + if (flag) + { + this.dropBlockAsItem(par1World, par2, par3, par4, par1World.getBlockMetadata(par2, par3, par4), 0); + par1World.setBlockToAir(par2, par3, par4); + return true; + } + else + { + return false; + } + } + else + { + return true; + } + } + + // Yes, function hiding. Go away. + public boolean canPlaceTorchOn(World par1World, int par2, int par3, int par4) + { + if (World.doesBlockHaveSolidTopSurface(par1World, par2, par3, par4)) + { + return true; + } + else + { + Block block = par1World.getBlock(par2, par3, par4); + return block.canPlaceTorchOnTop(par1World, par2, par3, par4); + } + } + + protected int getColourValueFromItemStack(ItemStack itemStack) { + int value = 0xffffff; // default to white. + if (itemStack.hasTagCompound()) { + NBTTagCompound tag = itemStack.getTagCompound(); + if (tag.hasKey(colourTagName)) { + value = tag.getInteger(colourTagName); + } + } + return value; + } + + public static boolean isLit(int meta) { + return (meta & 0x08) > 0; + } + + public static boolean isLit(ItemStack itemStack) { + return itemStack.getItemDamage() > 0; + } + + protected int toggleLitStatus(int meta) { + return meta ^ 0x08; + } + + public void addItemToLightingList(Item item) { + if (item == null) throw new NullPointerException(); + + if (!this.lightingItems.contains(item)) { + this.lightingItems.add(item); + } + } + +} diff --git a/forestry_common/apiculture/forestry/apiculture/gadgets/BlockStump.java b/forestry_common/apiculture/forestry/apiculture/gadgets/BlockStump.java new file mode 100755 index 000000000..298c9c9a9 --- /dev/null +++ b/forestry_common/apiculture/forestry/apiculture/gadgets/BlockStump.java @@ -0,0 +1,80 @@ +/******************************************************************************* + * Copyright 2011-2014 by SirSengir + * + * This work is licensed under a Creative Commons Attribution-NonCommercial-NoDerivs 3.0 Unported License. + * + * To view a copy of this license, visit http://creativecommons.org/licenses/by-nc-nd/3.0/. + ******************************************************************************/ +package forestry.apiculture.gadgets; + +import java.util.List; +import java.util.Random; + +import net.minecraft.block.BlockTorch; +import net.minecraft.client.renderer.texture.IIconRegister; +import net.minecraft.creativetab.CreativeTabs; +import net.minecraft.entity.player.EntityPlayer; +import net.minecraft.init.Blocks; +import net.minecraft.init.Items; +import net.minecraft.item.Item; +import net.minecraft.item.ItemStack; +import net.minecraft.world.World; + +import cpw.mods.fml.relauncher.Side; +import cpw.mods.fml.relauncher.SideOnly; + +import forestry.api.core.Tabs; +import forestry.core.config.Defaults; +import forestry.core.config.ForestryBlock; +import forestry.core.render.TextureManager; +import forestry.core.utils.StackUtils; + +public class BlockStump extends BlockTorch { + + public BlockStump() { + super(); + this.setHardness(0.0F); + this.setStepSound(soundTypeWood); + setCreativeTab(Tabs.tabApiculture); + } + + @SideOnly(Side.CLIENT) + @Override + public void registerBlockIcons(IIconRegister register) { + this.blockIcon = TextureManager.getInstance().registerTex(register, this.getUnlocalizedName().replace("tile.", "")); + } + + @SuppressWarnings({ "rawtypes", "unchecked" }) + @Override + public void getSubBlocks(Item item, CreativeTabs par2CreativeTabs, List itemList) { + itemList.add(new ItemStack(this, 1, 0)); + } + + @Override + public boolean onBlockActivated(World world, int x, int y, int z, EntityPlayer player, int facing, float facingX, float facingY, float facingZ) { + + ItemStack held = player.getCurrentEquippedItem(); + if (held != null && + (held.getItem() == Items.flint_and_steel || + held.getItem() == Items.flint || + StackUtils.equals(Blocks.torch, held))) { + world.setBlock(x, y, z, ForestryBlock.candle, world.getBlockMetadata(x, y, z) | 0x08, Defaults.FLAG_BLOCK_SYNCH); + TileCandle tc = new TileCandle(); + tc.setColour(0); // default to white + world.setTileEntity(x, y, z, tc); + return true; + } + + return false; + } + + @Override + @SideOnly(Side.CLIENT) + public int getRenderColor(int par1) { + return 0xee0000; + } + + @Override + public void randomDisplayTick(World par1World, int par2, int par3, int par4, Random par5Random) { + } +} diff --git a/forestry_common/apiculture/forestry/apiculture/gadgets/StructureLogicAlveary.java b/forestry_common/apiculture/forestry/apiculture/gadgets/StructureLogicAlveary.java new file mode 100755 index 000000000..53b7e2b90 --- /dev/null +++ b/forestry_common/apiculture/forestry/apiculture/gadgets/StructureLogicAlveary.java @@ -0,0 +1,116 @@ +/******************************************************************************* + * Copyright 2011-2014 by SirSengir + * + * This work is licensed under a Creative Commons Attribution-NonCommercial-NoDerivs 3.0 Unported License. + * + * To view a copy of this license, visit http://creativecommons.org/licenses/by-nc-nd/3.0/. + ******************************************************************************/ +package forestry.apiculture.gadgets; + +import java.util.HashSet; + +import net.minecraft.block.Block; +import net.minecraft.init.Blocks; +import net.minecraft.tileentity.TileEntity; + +import forestry.api.apiculture.IAlvearyComponent; +import forestry.api.core.ITileStructure; +import forestry.core.config.ForestryBlock; +import forestry.core.gadgets.BlockStructure.EnumStructureState; +import forestry.core.gadgets.StructureLogic; +import forestry.core.utils.Schemata; +import forestry.core.utils.Schemata.EnumStructureBlock; +import forestry.core.utils.Vect; + +public class StructureLogicAlveary extends StructureLogic { + + /* CONSTANTS */ + public static final String UID_ALVEARY = "alveary"; + public static final Schemata SCHEMATA_ALVEARY = new Schemata("alveary3x3", 5, 6, 5, "FFFFF", "FFFFF", "FFFFF", "FFFFF", "FFFFF", "FFFFF", "FFFFF", "FAAAF", + "FAAAF", "FABAF", "FCCCF", "FFFFF", "FFFFF", "FAAAF", "FAAAF", "FBMBF", "FCCCF", "FFFFF", "FFFFF", "FAAAF", "FAAAF", "FABAF", "FCCCF", "FFFFF", + "FFFFF", "FFFFF", "FFFFF", "FFFFF", "FFFFF", "FFFFF").setOffsets(-2, -3, -2); + + public static HashSet slabBlocks = new HashSet(); + static { + slabBlocks.add(Blocks.stone_slab); + slabBlocks.add(Blocks.wooden_slab); + slabBlocks.add(ForestryBlock.slabs1); + slabBlocks.add(ForestryBlock.slabs2); + slabBlocks.add(ForestryBlock.slabs3); + if (ForestryBlock.slabs4 != null) + slabBlocks.add(ForestryBlock.slabs4); + } + + public StructureLogicAlveary(ITileStructure structure) { + super(UID_ALVEARY, structure); + schematas = new Schemata[] { SCHEMATA_ALVEARY }; + metaOnValid.put(EnumStructureBlock.BLOCK_B, 1); + } + + @Override + protected EnumStructureState determineMasterState(Schemata schemata, boolean rotate) { + + Vect dimensions = schemata.getDimensions(rotate); + int offsetX = schemata.getxOffset(); + int offsetZ = schemata.getzOffset(); + if (rotate) { + offsetX = schemata.getzOffset(); + offsetZ = schemata.getxOffset(); + } + + for (int i = 0; i < dimensions.x; i++) + for (int j = 0; j < schemata.getHeight(); j++) + for (int k = 0; k < dimensions.z; k++) { + int x = structureTile.xCoord + i + offsetX; + int y = structureTile.yCoord + j + schemata.getyOffset(); + int z = structureTile.zCoord + k + offsetZ; + + if (!structureTile.getWorldObj().blockExists(x, y, z)) + return EnumStructureState.INDETERMINATE; + + EnumStructureBlock required = schemata.getAt(i, j, k, rotate); + if (required == EnumStructureBlock.ANY) + continue; + + TileEntity tile = structureTile.getWorldObj().getTileEntity(x, y, z); + Block block = structureTile.getWorldObj().getBlock(x, y, z); + + switch (required) { + case AIR: + if (!block.isAir(structureTile.getWorldObj(), x, y, z)) + return EnumStructureState.INVALID; + break; + case BLOCK_A: + if (tile == null || !(tile instanceof IAlvearyComponent)) + return EnumStructureState.INVALID; + if (!((ITileStructure) tile).getTypeUID().equals(UID_ALVEARY)) + return EnumStructureState.INVALID; + break; + case MASTER: + case BLOCK_B: + if (tile == null || !(tile instanceof TileAlvearyPlain)) + return EnumStructureState.INVALID; + break; + case BLOCK_C: + if (!slabBlocks.contains(block)) + return EnumStructureState.INVALID; + if ((structureTile.getWorldObj().getBlockMetadata(x, y, z) & 8) != 0) + return EnumStructureState.INVALID; + break; + case BLOCK_D: + if (block != Blocks.spruce_stairs) + return EnumStructureState.INVALID; + break; + case FOREIGN: + if (tile instanceof ITileStructure) + return EnumStructureState.INVALID; + break; + default: + return EnumStructureState.INDETERMINATE; + } + } + + return EnumStructureState.VALID; + } + +} diff --git a/forestry_common/apiculture/forestry/apiculture/gadgets/TileAlveary.java b/forestry_common/apiculture/forestry/apiculture/gadgets/TileAlveary.java new file mode 100755 index 000000000..360cf557a --- /dev/null +++ b/forestry_common/apiculture/forestry/apiculture/gadgets/TileAlveary.java @@ -0,0 +1,262 @@ +/******************************************************************************* + * Copyright 2011-2014 by SirSengir + * + * This work is licensed under a Creative Commons Attribution-NonCommercial-NoDerivs 3.0 Unported License. + * + * To view a copy of this license, visit http://creativecommons.org/licenses/by-nc-nd/3.0/. + ******************************************************************************/ +package forestry.apiculture.gadgets; + +import java.util.LinkedList; + +import net.minecraft.block.Block; +import net.minecraft.entity.player.EntityPlayer; +import net.minecraft.inventory.IInventory; +import net.minecraft.nbt.NBTTagCompound; +import net.minecraft.tileentity.TileEntity; + +import buildcraft.api.gates.ITrigger; + +import forestry.api.apiculture.IAlvearyComponent; +import forestry.api.apiculture.IBeeListener; +import forestry.api.apiculture.IBeeModifier; +import forestry.api.core.IStructureLogic; +import forestry.api.core.ITileStructure; +import forestry.core.config.Defaults; +import forestry.core.config.ForestryBlock; +import forestry.core.gadgets.TileForestry; +import forestry.core.network.PacketPayload; +import forestry.core.proxy.Proxies; +import forestry.core.triggers.ForestryTrigger; +import forestry.core.utils.TileInventoryAdapter; +import forestry.core.utils.Utils; + +public abstract class TileAlveary extends TileForestry implements IAlvearyComponent { + + protected TileInventoryAdapter inventory; + protected final int componentBlockMeta; + + public TileAlveary(int componentBlockMeta) { + this.structureLogic = new StructureLogicAlveary(this); + this.componentBlockMeta = componentBlockMeta; + } + + /* UPDATING */ + @Override + public void initialize() { + Block block = worldObj.getBlock(xCoord, yCoord, zCoord); + if (block != ForestryBlock.alveary) { + Proxies.log.info("Updating alveary block at %s/%s/%s.", xCoord, yCoord, zCoord); + worldObj.setBlock(xCoord, yCoord, zCoord, ForestryBlock.alveary, componentBlockMeta, Defaults.FLAG_BLOCK_SYNCH); + validate(); + worldObj.setTileEntity(xCoord, yCoord, zCoord, this); + } + } + + @Override + public void updateEntity() { + if (!Proxies.common.isSimulating(worldObj)) + updateClientSide(); + else { + if (!isInited) { + initialize(); + isInited = true; + } + + // Periodic validation if needed + if (worldObj.getTotalWorldTime() % 200 == 0 && (!isIntegratedIntoStructure() || isMaster())) + validateStructure(); + + updateServerSide(); + } + } + + protected void updateServerSide() { + } + + protected void updateClientSide() { + } + + /* TEXTURES */ + public int getIcon(int side, int metadata) { + return BlockAlveary.PLAIN; + } + + /* LOADING & SAVING */ + @Override + public void readFromNBT(NBTTagCompound nbttagcompound) { + super.readFromNBT(nbttagcompound); + + this.isMaster = nbttagcompound.getBoolean("IsMaster"); + this.masterX = nbttagcompound.getInteger("MasterX"); + this.masterY = nbttagcompound.getInteger("MasterY"); + this.masterZ = nbttagcompound.getInteger("MasterZ"); + + // Init for master state + if (isMaster) + makeMaster(); + + structureLogic.readFromNBT(nbttagcompound); + } + + @Override + public void writeToNBT(NBTTagCompound nbttagcompound) { + super.writeToNBT(nbttagcompound); + + nbttagcompound.setBoolean("IsMaster", isMaster); + nbttagcompound.setInteger("MasterX", masterX); + nbttagcompound.setInteger("MasterY", masterY); + nbttagcompound.setInteger("MasterZ", masterZ); + + structureLogic.writeToNBT(nbttagcompound); + } + + protected void createInventory() {} + + @Override + public void fromPacketPayload(PacketPayload payload) { + } + + @Override + public PacketPayload getPacketPayload() { + return null; + } + + /* ITILESTRUCTURE */ + IStructureLogic structureLogic; + + private boolean isMaster; + protected int masterX, masterZ; + protected int masterY = -99; + + @Override + public String getTypeUID() { + return structureLogic.getTypeUID(); + } + + @Override + public void validateStructure() { + structureLogic.validateStructure(); + } + + @Override + public void makeMaster() { + setCentralTE(null); + isMaster = true; + + if (inventory == null) + createInventory(); + } + + @Override + public void onStructureReset() { + setCentralTE(null); + if (worldObj.getBlockMetadata(xCoord, yCoord, zCoord) == 1) + worldObj.setBlockMetadataWithNotify(xCoord, yCoord, zCoord, 0, 0); + isMaster = false; + worldObj.markBlockForUpdate(xCoord, yCoord, zCoord); + } + + @Override + public ITileStructure getCentralTE() { + + if (!isIntegratedIntoStructure()) + return null; + + if (!isMaster()) { + TileEntity tile = worldObj.getTileEntity(masterX, masterY, masterZ); + if (tile instanceof ITileStructure) { + ITileStructure master = (ITileStructure) worldObj.getTileEntity(masterX, masterY, masterZ); + if (master.isMaster()) + return master; + else + return null; + } else + return null; + } else + return this; + + } + + private boolean isSameTile(TileEntity tile) { + return tile.xCoord == xCoord && tile.yCoord == yCoord && tile.zCoord == zCoord; + } + + @Override + public void setCentralTE(TileEntity tile) { + if (tile == null || tile == this || isSameTile(tile)) { + this.masterX = this.masterZ = 0; + this.masterY = -99; + return; + } + + this.isMaster = false; + this.masterX = tile.xCoord; + this.masterY = tile.yCoord; + this.masterZ = tile.zCoord; + } + + @Override + public boolean isMaster() { + return isMaster; + } + + protected boolean hasMaster() { + return masterY >= 0; + } + + @Override + public boolean isIntegratedIntoStructure() { + return isMaster || masterY >= 0; + } + + @Override + public IInventory getInventory() { + return inventory; + } + + /* IALVEARY COMPONENT */ + @Override + public boolean hasFunction() { + return false; + } + + @Override + public void addTemperatureChange(float change, float boundaryDown, float boundaryUp) { + } + + @Override + public void addHumidityChange(float change, float boundaryDown, float boundaryUp) { + } + + @Override + public void registerBeeModifier(IBeeModifier modifier) { + } + + @Override + public void removeBeeModifier(IBeeModifier modifier) { + } + + @Override + public void registerBeeListener(IBeeListener event) { + } + + @Override + public void removeBeeListener(IBeeListener event) { + } + + // / ITRIGGERPROVIDER + @Override + public LinkedList getCustomTriggers() { + LinkedList res = new LinkedList(); + res.add(ForestryTrigger.missingQueen); + res.add(ForestryTrigger.missingDrone); + return res; + } + + @Override + public boolean isUseableByPlayer(EntityPlayer player) { + return Utils.isUseableByPlayer(player, this, worldObj, xCoord, yCoord, zCoord); + } + +} diff --git a/forestry_common/apiculture/forestry/apiculture/gadgets/TileAlvearyClimatiser.java b/forestry_common/apiculture/forestry/apiculture/gadgets/TileAlvearyClimatiser.java new file mode 100755 index 000000000..84bd6d4e1 --- /dev/null +++ b/forestry_common/apiculture/forestry/apiculture/gadgets/TileAlvearyClimatiser.java @@ -0,0 +1,157 @@ +/******************************************************************************* + * Copyright 2011-2014 by SirSengir + * + * This work is licensed under a Creative Commons Attribution-NonCommercial-NoDerivs 3.0 Unported License. + * + * To view a copy of this license, visit http://creativecommons.org/licenses/by-nc-nd/3.0/. + ******************************************************************************/ +package forestry.apiculture.gadgets; + +import net.minecraft.entity.player.EntityPlayer; +import net.minecraft.nbt.NBTTagCompound; + +import net.minecraftforge.common.util.ForgeDirection; + +import buildcraft.api.power.IPowerReceptor; +import buildcraft.api.power.PowerHandler; +import buildcraft.api.power.PowerHandler.PowerReceiver; +import buildcraft.api.power.PowerHandler.Type; + +import forestry.api.apiculture.IAlvearyComponent; +import forestry.core.network.PacketPayload; + +public abstract class TileAlvearyClimatiser extends TileAlveary implements IPowerReceptor { + + public static class ClimateControl { + + final float changePerTransfer; + final float boundaryUp; + final float boundaryDown; + + public ClimateControl(float changePerTransfer, float boundaryDown, float boundaryUp) { + this.changePerTransfer = changePerTransfer; + this.boundaryDown = boundaryDown; + this.boundaryUp = boundaryUp; + } + } + PowerHandler powerProvider; + ClimateControl climateControl; + private int transferTime = 0; + private int animationDelay = 0; + private final int textureOff; + private final int textureOn; + + public TileAlvearyClimatiser(ClimateControl control, int textureOff, int textureOn, int componentBlockMeta) { + super(componentBlockMeta); + this.climateControl = control; + powerProvider = new PowerHandler(this, Type.MACHINE); + powerProvider.configure(10, 100, 25, 200); + this.textureOff = textureOff; + this.textureOn = textureOn; + } + + @Override + public void openGui(EntityPlayer player) { + } + + /* UPDATING */ + @Override + protected void updateServerSide() { + super.updateServerSide(); + + // BC Power + if (powerProvider != null) { + powerProvider.update(); + } + + if (!this.hasMaster()) + return; + + if (transferTime > 0) { + transferTime--; + IAlvearyComponent component = (IAlvearyComponent) this.getCentralTE(); + if (component != null) + component.addTemperatureChange(climateControl.changePerTransfer, climateControl.boundaryDown, climateControl.boundaryUp); + } + + if (animationDelay > 0) { + animationDelay--; + if (animationDelay <= 0) + sendNetworkUpdate(); + } + } + + @Override + public boolean hasFunction() { + return true; + } + + /* TEXTURES */ + @Override + public int getIcon(int side, int metadata) { + if (animationDelay > 0) + return textureOn; + else + return textureOff; + } + + /* IPOWERRECEPTOR */ + @Override + public void doWork(PowerHandler workProvider) { + if (!this.hasMaster()) + return; + + if (powerProvider.useEnergy(powerProvider.getActivationEnergy(), powerProvider.getEnergyStored(), false) < powerProvider.getActivationEnergy()) + return; + + transferTime = (int) Math.round(powerProvider.useEnergy(powerProvider.getActivationEnergy(), powerProvider.getEnergyStored(), true)); + + if (animationDelay <= 0) { + animationDelay = 100; + sendNetworkUpdate(); + } else + animationDelay = 100; + } + + @Override + public PowerReceiver getPowerReceiver(ForgeDirection side) { + return powerProvider.getPowerReceiver(); + } + + /* LOADING & SAVING */ + @Override + public void readFromNBT(NBTTagCompound nbttagcompound) { + super.readFromNBT(nbttagcompound); + powerProvider.readFromNBT(nbttagcompound); + transferTime = nbttagcompound.getInteger("Heating"); + } + + @Override + public void writeToNBT(NBTTagCompound nbttagcompound) { + super.writeToNBT(nbttagcompound); + powerProvider.writeToNBT(nbttagcompound); + nbttagcompound.setInteger("Heating", transferTime); + } + + @Override + public String getInventoryName() { + return "tile.alveary.climatiser"; + } + + /* NETWORK */ + @Override + public void fromPacketPayload(PacketPayload payload) { + short delay = payload.shortPayload[0]; + if (animationDelay != delay) { + animationDelay = delay; + worldObj.func_147479_m(xCoord, yCoord, zCoord); + } + } + + @Override + public PacketPayload getPacketPayload() { + PacketPayload payload = new PacketPayload(0, 1); + payload.shortPayload[0] = (short) animationDelay; + return payload; + } +} diff --git a/forestry_common/apiculture/forestry/apiculture/gadgets/TileAlvearyFan.java b/forestry_common/apiculture/forestry/apiculture/gadgets/TileAlvearyFan.java new file mode 100755 index 000000000..795279aab --- /dev/null +++ b/forestry_common/apiculture/forestry/apiculture/gadgets/TileAlvearyFan.java @@ -0,0 +1,19 @@ +/******************************************************************************* + * Copyright 2011-2014 by SirSengir + * + * This work is licensed under a Creative Commons Attribution-NonCommercial-NoDerivs 3.0 Unported License. + * + * To view a copy of this license, visit http://creativecommons.org/licenses/by-nc-nd/3.0/. + ******************************************************************************/ +package forestry.apiculture.gadgets; + +public class TileAlvearyFan extends TileAlvearyClimatiser { + + /* CONSTANTS */ + public static final int BLOCK_META = 3; + + public TileAlvearyFan() { + super(new ClimateControl(-0.01f, 0.05f, 2.5f), BlockAlveary.TX_71_FNOF, BlockAlveary.TX_72_FNON, BLOCK_META); + } + +} diff --git a/forestry_common/apiculture/forestry/apiculture/gadgets/TileAlvearyHeater.java b/forestry_common/apiculture/forestry/apiculture/gadgets/TileAlvearyHeater.java new file mode 100755 index 000000000..8d7c9898e --- /dev/null +++ b/forestry_common/apiculture/forestry/apiculture/gadgets/TileAlvearyHeater.java @@ -0,0 +1,22 @@ +/******************************************************************************* + * Copyright 2011-2014 by SirSengir + * + * This work is licensed under a Creative Commons Attribution-NonCommercial-NoDerivs 3.0 Unported License. + * + * To view a copy of this license, visit http://creativecommons.org/licenses/by-nc-nd/3.0/. + ******************************************************************************/ +package forestry.apiculture.gadgets; + +public class TileAlvearyHeater extends TileAlvearyClimatiser { + + public static final int TEXTURE_OFF = 57; + public static final int TEXTURE_ON = 58; + + /* CONSTANTS */ + public static final int BLOCK_META = 4; + + public TileAlvearyHeater() { + super(new ClimateControl(0.01f, 0.0f, 2.5f), BlockAlveary.TX_57_HTOF, BlockAlveary.TX_58_HTON, BLOCK_META); + } + +} diff --git a/forestry_common/apiculture/forestry/apiculture/gadgets/TileAlvearyHygroregulator.java b/forestry_common/apiculture/forestry/apiculture/gadgets/TileAlvearyHygroregulator.java new file mode 100755 index 000000000..320ccefd4 --- /dev/null +++ b/forestry_common/apiculture/forestry/apiculture/gadgets/TileAlvearyHygroregulator.java @@ -0,0 +1,294 @@ +/******************************************************************************* + * Copyright 2011-2014 by SirSengir + * + * This work is licensed under a Creative Commons Attribution-NonCommercial-NoDerivs 3.0 Unported License. + * + * To view a copy of this license, visit http://creativecommons.org/licenses/by-nc-nd/3.0/. + ******************************************************************************/ +package forestry.apiculture.gadgets; + +import net.minecraft.entity.player.EntityPlayer; +import net.minecraft.inventory.Container; +import net.minecraft.inventory.ICrafting; +import net.minecraft.inventory.IInventory; +import net.minecraft.item.ItemStack; +import net.minecraft.nbt.NBTTagCompound; + +import net.minecraftforge.common.util.ForgeDirection; +import net.minecraftforge.fluids.FluidContainerRegistry.FluidContainerData; +import net.minecraftforge.fluids.FluidRegistry; +import net.minecraftforge.fluids.FluidStack; + +import forestry.api.apiculture.IAlvearyComponent; +import forestry.api.core.ForestryAPI; +import forestry.core.config.Defaults; +import forestry.core.interfaces.ILiquidTankContainer; +import forestry.core.network.GuiId; +import forestry.core.proxy.Proxies; +import forestry.core.utils.ForestryTank; +import forestry.core.utils.InventoryAdapter; +import forestry.core.utils.LiquidHelper; +import forestry.core.utils.StackUtils; + +public class TileAlvearyHygroregulator extends TileAlveary implements IInventory, ILiquidTankContainer { + + /* CONSTANTS */ + public static final int BLOCK_META = 5; + + /* RECIPE MANAGMENT */ + private static class HygroregulatorRecipe { + public final FluidStack liquid; + public final int transferTime; + public final float humidChange; + public final float tempChange; + + public HygroregulatorRecipe(FluidStack liquid, int transferTime, float humidChange, float tempChange) { + this.liquid = liquid; + this.transferTime = transferTime; + this.humidChange = humidChange; + this.tempChange = tempChange; + } + } + + private final HygroregulatorRecipe[] recipes; + + /* MEMBERS */ + InventoryAdapter canInventory = new InventoryAdapter(1, "CanInv"); + private ForestryTank liquidTank = new ForestryTank(Defaults.PROCESSOR_TANK_CAPACITY); + + private HygroregulatorRecipe currentRecipe; + private int transferTime; + + public TileAlvearyHygroregulator() { + super(BLOCK_META); + + recipes = new HygroregulatorRecipe[] { new HygroregulatorRecipe(new FluidStack(LiquidHelper.getFluid(Defaults.LIQUID_WATER), 1), 1, 0.01f, -0.005f), + new HygroregulatorRecipe(new FluidStack(LiquidHelper.getFluid(Defaults.LIQUID_LAVA), 1), 10, -0.01f, +0.005f), + new HygroregulatorRecipe(new FluidStack(LiquidHelper.getFluid(Defaults.LIQUID_ICE), 1), 10, 0.02f, -0.01f) }; + } + + @Override + public void openGui(EntityPlayer player) { + player.openGui(ForestryAPI.instance, GuiId.HygroregulatorGUI.ordinal(), worldObj, xCoord, yCoord, zCoord); + } + + @Override + public String getInventoryName() { + return "tile.alveary.5"; + } + + /* UPDATING */ + private HygroregulatorRecipe getRecipe(FluidStack liquid) { + HygroregulatorRecipe recipe = null; + for (HygroregulatorRecipe rec : recipes) + if (rec.liquid.isFluidEqual(liquid)) { + recipe = rec; + break; + } + return recipe; + } + + @Override + protected void updateServerSide() { + super.updateServerSide(); + + if (transferTime <= 0 && liquidTank.getFluidAmount() > 0) { + currentRecipe = getRecipe(liquidTank.getFluid()); + + if (currentRecipe != null) { + liquidTank.drain(currentRecipe.liquid.amount, true); + transferTime = currentRecipe.transferTime; + } + } + + if (transferTime > 0) { + + transferTime--; + if (currentRecipe != null) { + IAlvearyComponent component = (IAlvearyComponent) this.getCentralTE(); + if (component != null) { + component.addHumidityChange(currentRecipe.humidChange, 0.0f, 1.0f); + component.addTemperatureChange(currentRecipe.tempChange, 0.0f, 2.0f); + } + } else + transferTime = 0; + } + + if (worldObj.getTotalWorldTime() % 20 * 10 != 0) + return; + + // Check if we have suitable items waiting in the item slot + if (canInventory.getStackInSlot(0) != null) { + FluidContainerData container = LiquidHelper.getLiquidContainer(canInventory.getStackInSlot(0)); + if (container != null && + (container.fluid.getFluid() == FluidRegistry.WATER || container.fluid.getFluid() == FluidRegistry.LAVA)) { + + canInventory.setInventorySlotContents(0, StackUtils.replenishByContainer(this, canInventory.getStackInSlot(0), container, liquidTank)); + if (canInventory.getStackInSlot(0).stackSize <= 0) + canInventory.setInventorySlotContents(0, null); + } + } + + } + + @Override + public boolean hasFunction() { + return true; + } + + /* SAVING & LOADING */ + @Override + public void readFromNBT(NBTTagCompound nbttagcompound) { + super.readFromNBT(nbttagcompound); + + canInventory.readFromNBT(nbttagcompound); + + liquidTank = new ForestryTank(Defaults.PROCESSOR_TANK_CAPACITY); + if (nbttagcompound.hasKey("LiquidTank")) + liquidTank.readFromNBT(nbttagcompound.getCompoundTag("LiquidTank")); + + transferTime = nbttagcompound.getInteger("TransferTime"); + + if (nbttagcompound.hasKey("CurrentLiquid")) { + FluidStack liquid = FluidStack.loadFluidStackFromNBT(nbttagcompound.getCompoundTag("CurrentLiquid")); + currentRecipe = getRecipe(liquid); + } + } + + @Override + public void writeToNBT(NBTTagCompound nbttagcompound) { + super.writeToNBT(nbttagcompound); + + canInventory.writeToNBT(nbttagcompound); + + NBTTagCompound NBTresourceSlot = new NBTTagCompound(); + liquidTank.writeToNBT(NBTresourceSlot); + nbttagcompound.setTag("LiquidTank", NBTresourceSlot); + + nbttagcompound.setInteger("TransferTime", transferTime); + if (currentRecipe != null) { + NBTTagCompound subcompound = new NBTTagCompound(); + currentRecipe.liquid.writeToNBT(subcompound); + nbttagcompound.setTag("CurrentLiquid", subcompound); + } + + } + + /* TEXTURES */ + @Override + public int getIcon(int side, int metadata) { + return BlockAlveary.TX_73_VLVE; + } + + @Override + public IInventory getInventory() { + return canInventory; + } + + /* IINVENTORY */ + @Override + public int getSizeInventory() { + if (canInventory != null) + return canInventory.getSizeInventory(); + else + return 0; + } + + @Override + public ItemStack getStackInSlot(int slotIndex) { + if (canInventory != null) + return canInventory.getStackInSlot(slotIndex); + else + return null; + } + + @Override + public ItemStack decrStackSize(int slotIndex, int amount) { + if (canInventory != null) + return canInventory.decrStackSize(slotIndex, amount); + else + return null; + } + + @Override + public ItemStack getStackInSlotOnClosing(int slotIndex) { + if (canInventory != null) + return canInventory.getStackInSlotOnClosing(slotIndex); + else + return null; + } + + @Override + public void setInventorySlotContents(int slotIndex, ItemStack itemstack) { + // Client side handling for container synch + if (canInventory == null && !Proxies.common.isSimulating(worldObj)) + createInventory(); + + if (canInventory != null) + canInventory.setInventorySlotContents(slotIndex, itemstack); + } + + @Override + public int getInventoryStackLimit() { + if (canInventory != null) + return canInventory.getInventoryStackLimit(); + else + return 0; + } + + @Override + public void openInventory() { + } + + @Override + public void closeInventory() { + } + + /** + * TODO: just a specialsource workaround + */ + @Override + public boolean isUseableByPlayer(EntityPlayer player) { + return super.isUseableByPlayer(player); + } + + /** + * TODO: just a specialsource workaround + */ + @Override + public boolean hasCustomInventoryName() { + return super.hasCustomInventoryName(); + } + + /** + * TODO: just a specialsource workaround + */ + @Override + public boolean isItemValidForSlot(int slotIndex, ItemStack itemstack) { + return super.isItemValidForSlot(slotIndex, itemstack); + } + + /* ILIQUIDTANKCONTAINER */ + @Override + public int fill(ForgeDirection from, FluidStack resource, boolean doFill) { + return liquidTank.fill(resource, doFill); + } + + @Override + public FluidStack drain(ForgeDirection from, int maxDrain, boolean doDrain) { + return liquidTank.drain(maxDrain, doDrain); + } + + @Override + public ForestryTank[] getTanks() { + return new ForestryTank[] { liquidTank }; + } + + /* SMP GUI */ + public void getGUINetworkData(int i, int j) { + } + + public void sendGUINetworkData(Container container, ICrafting iCrafting) { + } + +} diff --git a/forestry_common/apiculture/forestry/apiculture/gadgets/TileAlvearyPlain.java b/forestry_common/apiculture/forestry/apiculture/gadgets/TileAlvearyPlain.java new file mode 100755 index 000000000..7fcb7063c --- /dev/null +++ b/forestry_common/apiculture/forestry/apiculture/gadgets/TileAlvearyPlain.java @@ -0,0 +1,839 @@ +/******************************************************************************* + * Copyright 2011-2014 by SirSengir + * + * This work is licensed under a Creative Commons Attribution-NonCommercial-NoDerivs 3.0 Unported License. + * + * To view a copy of this license, visit http://creativecommons.org/licenses/by-nc-nd/3.0/. + ******************************************************************************/ +package forestry.apiculture.gadgets; + +import java.util.LinkedHashSet; +import java.util.Set; + +import net.minecraft.entity.player.EntityPlayer; +import net.minecraft.inventory.ICrafting; +import net.minecraft.inventory.IInventory; +import net.minecraft.inventory.ISidedInventory; +import net.minecraft.item.ItemStack; +import net.minecraft.nbt.NBTTagCompound; +import net.minecraft.world.World; +import net.minecraft.world.biome.BiomeGenBase; + +import net.minecraftforge.common.util.ForgeDirection; + +import buildcraft.api.inventory.ISpecialInventory; + +import forestry.api.apiculture.IBee; +import forestry.api.apiculture.IBeeGenome; +import forestry.api.apiculture.IBeeHousing; +import forestry.api.apiculture.IBeeListener; +import forestry.api.apiculture.IBeeModifier; +import forestry.api.apiculture.IBeekeepingLogic; +import forestry.api.core.EnumHumidity; +import forestry.api.core.EnumTemperature; +import forestry.api.core.ForestryAPI; +import forestry.api.core.ITileStructure; +import forestry.api.genetics.IIndividual; +import forestry.apiculture.gui.ContainerAlveary; +import forestry.core.EnumErrorCode; +import forestry.core.config.Config; +import forestry.core.config.ForestryItem; +import forestry.core.interfaces.IClimatised; +import forestry.core.interfaces.IErrorSource; +import forestry.core.interfaces.IHintSource; +import forestry.core.network.GuiId; +import forestry.core.network.PacketIds; +import forestry.core.network.PacketInventoryStack; +import forestry.core.proxy.Proxies; +import forestry.core.utils.InventoryAdapter; +import forestry.core.utils.TileInventoryAdapter; +import forestry.plugins.PluginApiculture; + +public class TileAlvearyPlain extends TileAlveary implements ISidedInventory, ISpecialInventory, IBeeHousing, IClimatised, IHintSource { + + // / CONSTANTS + public static final int SLOT_QUEEN = 0; + public static final int SLOT_DRONE = 1; + public static final int SLOT_PRODUCT_1 = 2; + public static final int SLOT_PRODUCTION_COUNT = 7; + // / MEMBERS + protected IBeekeepingLogic beekeepingLogic; + protected int biomeId; + protected float temperature; + protected float humidity; + protected float tempChange = 0.0f; + protected float humidChange = 0.0f; + private int displayHealthMax = 0; + private int displayHealth = 0; + + public TileAlvearyPlain() { + super(0); + } + + @Override + public void openGui(EntityPlayer player) { + if (isMaster()) + player.openGui(ForestryAPI.instance, GuiId.AlvearyGUI.ordinal(), worldObj, xCoord, yCoord, zCoord); + else if (this.hasMaster()) + player.openGui(ForestryAPI.instance, GuiId.AlvearyGUI.ordinal(), worldObj, masterX, masterY, masterZ); + } + + /* LOADING & SAVING */ + @Override + public void readFromNBT(NBTTagCompound nbttagcompound) { + super.readFromNBT(nbttagcompound); + + this.tempChange = nbttagcompound.getFloat("TempChange"); + this.humidChange = nbttagcompound.getFloat("HumidChange"); + + if (inventory != null) + inventory.readFromNBT(nbttagcompound); + if (beekeepingLogic != null) + beekeepingLogic.readFromNBT(nbttagcompound); + + } + + @Override + public void writeToNBT(NBTTagCompound nbttagcompound) { + super.writeToNBT(nbttagcompound); + + nbttagcompound.setFloat("TempChange", tempChange); + nbttagcompound.setFloat("HumidChange", humidChange); + + if (inventory != null) + inventory.writeToNBT(nbttagcompound); + if (beekeepingLogic != null) + beekeepingLogic.writeToNBT(nbttagcompound); + + } + + /* UPDATING */ + @Override + public void initialize() { + super.initialize(); + BiomeGenBase biome = worldObj.getBiomeGenForCoordsBody(xCoord, zCoord); + this.biomeId = biome.biomeID; + this.temperature = biome.temperature; + this.humidity = biome.rainfall; + setErrorState(EnumErrorCode.OK); + } + + @Override + protected void updateServerSide() { + + if (beekeepingLogic == null) + return; + if (!isMaster()) + return; + + beekeepingLogic.update(); + + // Equalize humidity and temperature + equalizeTemperature(); + equalizeHumidity(); + + IBee queen = beekeepingLogic.getQueen(); + if (queen == null) + return; + + // Add swarm effects + if (worldObj.getTotalWorldTime() % 200 * 10 == 0) + onQueenChange(inventory.getStackInSlot(SLOT_QUEEN)); + if (getErrorState() == EnumErrorCode.OK) + queen.doFX(beekeepingLogic.getEffectData(), this); + + if (getErrorState() == EnumErrorCode.OK && worldObj.getTotalWorldTime() % 50 == 0) { + float f = xCoord + 0.5F; + float f1 = yCoord + 0.0F + (worldObj.rand.nextFloat() * 6F) / 16F; + float f2 = zCoord + 0.5F; + float f3 = 0.52F; + float f4 = worldObj.rand.nextFloat() * 0.6F - 0.3F; + + Proxies.common.addEntitySwarmFX(worldObj, (f - f3), f1, (f2 + f4), 0F, 0F, 0F); + Proxies.common.addEntitySwarmFX(worldObj, (f + f3), f1, (f2 + f4), 0F, 0F, 0F); + Proxies.common.addEntitySwarmFX(worldObj, (f + f4), f1, (f2 - f3), 0F, 0F, 0F); + Proxies.common.addEntitySwarmFX(worldObj, (f + f4), f1, (f2 + f3), 0F, 0F, 0F); + } + + } + + @Override + protected void updateClientSide() { + + if (!isMaster()) + return; + + if (inventory == null) + return; + + // / Multiplayer FX + if (PluginApiculture.beeInterface.isMated(inventory.getStackInSlot(SLOT_QUEEN))) + if (getErrorState() == EnumErrorCode.OK && worldObj.getTotalWorldTime() % 2 == 0) { + IBee displayQueen = PluginApiculture.beeInterface.getMember(inventory.getStackInSlot(SLOT_QUEEN)); + displayQueen.doFX(beekeepingLogic.getEffectData(), this); + } + return; + + } + + private void equalizeTemperature() { + if (tempChange == 0) + return; + + tempChange -= 0.05f * tempChange; + if (tempChange <= 0.001f && tempChange >= -0.001f) + tempChange = 0; + } + + private void equalizeHumidity() { + if (humidChange == 0) + return; + + humidChange -= 0.05f * humidChange; + if (humidChange <= 0.001f && humidChange >= 0.001f) + humidChange = 0; + } + + /* STATE INFORMATION */ + private int getHealthDisplay() { + if (inventory == null || inventory.getStackInSlot(SLOT_QUEEN) == null) + return 0; + + if (PluginApiculture.beeInterface.isMated(inventory.getStackInSlot(SLOT_QUEEN))) + return PluginApiculture.beeInterface.getMember(inventory.getStackInSlot(SLOT_QUEEN)).getHealth(); + else if (!PluginApiculture.beeInterface.isDrone(inventory.getStackInSlot(SLOT_QUEEN))) + return displayHealth; + else + return 0; + } + + private int getMaxHealthDisplay() { + if (inventory == null || inventory.getStackInSlot(SLOT_QUEEN) == null) + return 0; + + if (PluginApiculture.beeInterface.isMated(inventory.getStackInSlot(SLOT_QUEEN))) + return PluginApiculture.beeInterface.getMember(inventory.getStackInSlot(SLOT_QUEEN)).getMaxHealth(); + else if (!PluginApiculture.beeInterface.isDrone(inventory.getStackInSlot(SLOT_QUEEN))) + return displayHealthMax; + else + return 0; + } + + public int getHealthScaled(int i) { + if (getMaxHealthDisplay() == 0) + return 0; + + return (getHealthDisplay() * i) / getMaxHealthDisplay(); + } + + @Override + public boolean allowsInteraction(EntityPlayer player) { + if (!super.allowsInteraction(player)) + return false; + + return this.isIntegratedIntoStructure(); + } + + /* STRUCTURE MANAGMENT */ + @Override + protected void createInventory() { + this.inventory = new TileInventoryAdapter(this, 9, "Items"); + } + + @Override + public void makeMaster() { + super.makeMaster(); + if (beekeepingLogic == null) + this.beekeepingLogic = PluginApiculture.beeInterface.createBeekeepingLogic(this); + } + + @Override + public void onStructureReset() { + super.onStructureReset(); + modifiers.clear(); + eventHandlers.clear(); + } + + /* IALVEARYCOMPONENT */ + private final Set modifiers = new LinkedHashSet(); + private final Set eventHandlers = new LinkedHashSet(); + + @Override + public void registerBeeModifier(IBeeModifier modifier) { + modifiers.add(modifier); + } + + @Override + public void removeBeeModifier(IBeeModifier modifier) { + modifiers.remove(modifier); + } + + @Override + public void registerBeeListener(IBeeListener modifier) { + eventHandlers.add(modifier); + } + + @Override + public void removeBeeListener(IBeeListener modifier) { + eventHandlers.remove(modifier); + } + + @Override + public void addTemperatureChange(float change, float boundaryDown, float boundaryUp) { + tempChange = Math.min(boundaryUp - temperature, Math.max(boundaryDown - temperature, tempChange + change)); + } + + @Override + public void addHumidityChange(float change, float boundaryDown, float boundaryUp) { + humidChange = Math.min(boundaryUp - humidity, Math.max(boundaryDown - humidity, humidChange + change)); + } + + /* IBEEHOUSING */ + @Override + public int getXCoord() { + return xCoord; + } + + @Override + public int getYCoord() { + return yCoord; + } + + @Override + public int getZCoord() { + return zCoord; + } + + @Override + public ItemStack getQueen() { + return getStackInSlot(SLOT_QUEEN); + } + + @Override + public ItemStack getDrone() { + return getStackInSlot(SLOT_DRONE); + } + + @Override + public void setQueen(ItemStack itemstack) { + setInventorySlotContents(SLOT_QUEEN, itemstack); + } + + @Override + public void setDrone(ItemStack itemstack) { + setInventorySlotContents(SLOT_DRONE, itemstack); + } + + @Override + public int getBiomeId() { + return this.biomeId; + } + + @Override + public EnumTemperature getTemperature() { + if (EnumTemperature.isBiomeHellish(biomeId) && tempChange >= 0) + return EnumTemperature.HELLISH; + + return EnumTemperature.getFromValue(getExactTemperature()); + } + + @Override + public EnumHumidity getHumidity() { + return EnumHumidity.getFromValue(getExactHumidity()); + } + + @Override + public float getTerritoryModifier(IBeeGenome genome, float currentModifier) { + float mod = 2.0f; + for (IBeeModifier modifier : modifiers) { + mod *= modifier.getTerritoryModifier(genome, mod); + } + return mod; + } + + @Override + public float getProductionModifier(IBeeGenome genome, float currentModifier) { + float mod = 1.0f; + for (IBeeModifier modifier : modifiers) { + mod *= modifier.getProductionModifier(genome, mod); + } + return mod; + } + + @Override + public float getMutationModifier(IBeeGenome genome, IBeeGenome mate, float currentModifier) { + float mod = 1.0f; + for (IBeeModifier modifier : modifiers) { + mod *= modifier.getMutationModifier(genome, mate, mod); + } + return mod; + } + + @Override + public float getLifespanModifier(IBeeGenome genome, IBeeGenome mate, float currentModifier) { + float mod = 1.0f; + for (IBeeModifier modifier : modifiers) { + mod *= modifier.getLifespanModifier(genome, mate, mod); + } + return mod; + } + + @Override + public float getFloweringModifier(IBeeGenome genome, float currentModifier) { + float mod = 1.0f; + for (IBeeModifier modifier : modifiers) { + mod *= modifier.getFloweringModifier(genome, mod); + } + return mod; + } + + @Override + public float getGeneticDecay(IBeeGenome genome, float currentModifier) { + float mod = 1.0f; + for (IBeeModifier modifier : modifiers) { + mod *= modifier.getGeneticDecay(genome, mod); + } + return mod; + } + + @Override + public World getWorld() { + return worldObj; + } + + @Override + public void setErrorState(int state) { + setErrorState(EnumErrorCode.values()[state]); + } + + @Override + public int getErrorOrdinal() { + return getErrorState().ordinal(); + } + + @Override + public boolean canBreed() { + return true; + } + + @Override + public boolean addProduct(ItemStack product, boolean all) { + if (inventory == null) + return false; + + return inventory.tryAddStack(product, SLOT_PRODUCT_1, inventory.getSizeInventory() - SLOT_PRODUCT_1, all); + } + + @Override + public void wearOutEquipment(int amount) { + for (IBeeListener eventHandler : eventHandlers) { + eventHandler.wearOutEquipment(amount); + } + } + + @Override + public void onQueenChange(ItemStack queenStack) { + if (!Proxies.common.isSimulating(worldObj)) + return; + + Proxies.net.sendNetworkPacket(new PacketInventoryStack(PacketIds.IINVENTORY_STACK, xCoord, yCoord, zCoord, SLOT_QUEEN, queenStack), xCoord, yCoord, + zCoord); + + for (IBeeListener eventHandler : eventHandlers) { + eventHandler.onQueenChange(queenStack); + } + } + + @Override + public void onQueenDeath(IBee queen) { + for (IBeeListener eventHandler : eventHandlers) { + eventHandler.onQueenDeath(queen); + } + } + + @Override + public void onPostQueenDeath(IBee queen) { + for (IBeeListener eventHandler : eventHandlers) { + eventHandler.onPostQueenDeath(queen); + } + } + + @Override + public boolean onPollenRetrieved(IBee queen, IIndividual pollen, boolean isHandled) { + + for (IBeeListener eventHandler : eventHandlers) { + if (eventHandler.onPollenRetrieved(queen, pollen, isHandled)) + isHandled = true; + } + + return isHandled; + } + + @Override + public boolean onEggLaid(IBee queen) { + for (IBeeListener eventHandler : eventHandlers) { + if (eventHandler.onEggLaid(queen)) + return true; + } + + return false; + } + + @Override + public boolean isSealed() { + for (IBeeModifier modifier : modifiers) { + if (modifier.isSealed()) + return true; + } + return false; + } + + @Override + public boolean isSelfLighted() { + for (IBeeModifier modifier : modifiers) { + if (modifier.isSelfLighted()) + return true; + } + return false; + } + + @Override + public boolean isSunlightSimulated() { + for (IBeeModifier modifier : modifiers) { + if (modifier.isSunlightSimulated()) + return true; + } + return false; + } + + @Override + public boolean isHellish() { + for (IBeeModifier modifier : modifiers) { + if (modifier.isHellish()) + return true; + } + return false; + } + + /* IINVENTORY */ + @Override + public InventoryAdapter getInternalInventory() { + return (InventoryAdapter) getStructureInventory(); + } + + private IInventory getStructureInventory() { + + if (inventory != null) { + if (isMaster() || !Proxies.common.isSimulating(worldObj)) + return inventory; + } else if (hasMaster()) { + ITileStructure central = getCentralTE(); + if (central != null) + return central.getInventory(); + } + + return null; + } + + @Override + public int getSizeInventory() { + IInventory inv = getStructureInventory(); + if (inv != null) + return inv.getSizeInventory(); + else + return 0; + } + + @Override + public ItemStack getStackInSlot(int slotIndex) { + IInventory inv = getStructureInventory(); + if (inv != null) + return inv.getStackInSlot(slotIndex); + else + return null; + } + + @Override + public ItemStack decrStackSize(int slotIndex, int amount) { + IInventory inv = getStructureInventory(); + if (inv != null) + return inv.decrStackSize(slotIndex, amount); + else + return null; + } + + @Override + public ItemStack getStackInSlotOnClosing(int slotIndex) { + IInventory inv = getStructureInventory(); + if (inv != null) + return inv.getStackInSlotOnClosing(slotIndex); + else + return null; + } + + @Override + public void setInventorySlotContents(int slotIndex, ItemStack itemstack) { + // Client side handling for container synch + if (inventory == null && !Proxies.common.isSimulating(worldObj)) + createInventory(); + + IInventory inv = getStructureInventory(); + if (inv != null) + inv.setInventorySlotContents(slotIndex, itemstack); + } + + @Override + public String getInventoryName() { + return "alveary.0"; + } + + @Override + public int getInventoryStackLimit() { + IInventory inv = getStructureInventory(); + if (inv != null) + return inv.getInventoryStackLimit(); + else + return 0; + } + + @Override + protected boolean canTakeStackFromSide(int slotIndex, ItemStack itemstack, int side) { + + if (!super.canTakeStackFromSide(slotIndex, itemstack, side)) + return false; + + if (slotIndex != SLOT_QUEEN && slotIndex != SLOT_DRONE) + return true; + + return false; + } + + @Override + protected boolean canPutStackFromSide(int slotIndex, ItemStack itemstack, int side) { + + if (!super.canPutStackFromSide(slotIndex, itemstack, side)) + return false; + + if (slotIndex == SLOT_QUEEN && PluginApiculture.beeInterface.isMember(itemstack) + && !PluginApiculture.beeInterface.isDrone(itemstack)) + return true; + if (slotIndex == SLOT_DRONE && PluginApiculture.beeInterface.isDrone(itemstack)) + return true; + + return false; + } + + @Override + public void openInventory() { + } + + @Override + public void closeInventory() { + } + + /** + * TODO: just a specialsource workaround + */ + @Override + public boolean isUseableByPlayer(EntityPlayer player) { + return super.isUseableByPlayer(player); + } + + /** + * TODO: just a specialsource workaround + */ + @Override + public boolean hasCustomInventoryName() { + return super.hasCustomInventoryName(); + } + + /** + * TODO: just a specialsource workaround + */ + @Override + public boolean isItemValidForSlot(int slotIndex, ItemStack itemstack) { + return super.isItemValidForSlot(slotIndex, itemstack); + } + + /** + * TODO: just a specialsource workaround + */ + @Override + public boolean canInsertItem(int i, ItemStack itemstack, int j) { + return super.canInsertItem(i, itemstack, j); + } + + /** + * TODO: just a specialsource workaround + */ + @Override + public boolean canExtractItem(int i, ItemStack itemstack, int j) { + return super.canExtractItem(i, itemstack, j); + } + + /** + * TODO: just a specialsource workaround + */ + @Override + public int[] getAccessibleSlotsFromSide(int side) { + return super.getAccessibleSlotsFromSide(side); + } + + /* ISPECIALINVENTORY */ + @Override + public int addItem(ItemStack stack, boolean doAdd, ForgeDirection from) { + + IInventory inv = getStructureInventory(); + if (inv == null) + return 0; + + // Princesses && Queens + if (ForestryItem.beePrincessGE.isItemEqual(stack) || ForestryItem.beeQueenGE.isItemEqual(stack)) + if (inv.getStackInSlot(SLOT_QUEEN) == null) { + if (doAdd) { + inv.setInventorySlotContents(SLOT_QUEEN, stack.copy()); + inv.getStackInSlot(SLOT_QUEEN).stackSize = 1; + } + return 1; + } + + // Drones + if (ForestryItem.beeDroneGE.isItemEqual(stack)) { + + ItemStack droneStack = inv.getStackInSlot(SLOT_DRONE); + if (droneStack == null) { + if (doAdd) + inv.setInventorySlotContents(SLOT_DRONE, stack.copy()); + return stack.stackSize; + } else { + if (!droneStack.isItemEqual(stack)) + return 0; + if (!ItemStack.areItemStackTagsEqual(droneStack, stack)) + return 0; + int space = droneStack.getMaxStackSize() - droneStack.stackSize; + if (space <= 0) + return 0; + + int added = space > stack.stackSize ? stack.stackSize : space; + if (doAdd) + droneStack.stackSize += added; + return added; + } + } + + return 0; + } + + @Override + public ItemStack[] extractItem(boolean doRemove, ForgeDirection from, int maxItemCount) { + + IInventory inv = getStructureInventory(); + if (inv == null) + return new ItemStack[0]; + + ItemStack product = null; + + for (int i = SLOT_PRODUCT_1; i < inv.getSizeInventory(); i++) { + if (inv.getStackInSlot(i) == null) + continue; + + ItemStack stack = inv.getStackInSlot(i); + + if (doRemove) + product = inv.decrStackSize(i, 1); + else { + product = stack.copy(); + product.stackSize = 1; + } + break; + } + + return new ItemStack[] { product }; + } + + /* SMP GUI */ + public void getGUINetworkData(int i, int j) { + switch (i) { + case 0: + displayHealth = j; + break; + case 1: + displayHealthMax = j; + break; + case 2: + this.temperature = (float) j / 100; + break; + case 3: + this.humidity = (float) j / 100; + break; + case 4: + this.tempChange = (float) j / 100; + break; + case 5: + this.humidChange = (float) j / 100; + break; + case 6: + this.biomeId = j; + break; + } + + } + + public void sendGUINetworkData(ContainerAlveary container, ICrafting iCrafting) { + if (beekeepingLogic == null) + return; + + iCrafting.sendProgressBarUpdate(container, 0, beekeepingLogic.getBreedingTime()); + iCrafting.sendProgressBarUpdate(container, 1, beekeepingLogic.getTotalBreedingTime()); + iCrafting.sendProgressBarUpdate(container, 2, Math.round(temperature * 100)); + iCrafting.sendProgressBarUpdate(container, 3, Math.round(humidity * 100)); + iCrafting.sendProgressBarUpdate(container, 4, Math.round(tempChange * 100)); + iCrafting.sendProgressBarUpdate(container, 5, Math.round(humidChange * 100)); + iCrafting.sendProgressBarUpdate(container, 6, biomeId); + } + + /* IERRORSOURCE */ + @Override + public EnumErrorCode getErrorState() { + if (hasMaster()) { + ITileStructure tile = this.getCentralTE(); + if (tile != null) + return ((IErrorSource) tile).getErrorState(); + } + + return errorState; + } + + /* ICLIMATISED */ + @Override + public boolean isClimatized() { + return true; + } + + @Override + public float getExactTemperature() { + return this.temperature + this.tempChange; + } + + @Override + public float getExactHumidity() { + return this.humidity + this.humidChange; + } + + /* IHINTSOURCE */ + @Override + public boolean hasHints() { + return Config.hints.get("alveary").length > 0; + } + + @Override + public String[] getHints() { + return Config.hints.get("alveary"); + } + + /* IOWNABLE */ + @Override + public boolean isOwnable() { + return true; + } +} diff --git a/forestry_common/apiculture/forestry/apiculture/gadgets/TileAlvearySieve.java b/forestry_common/apiculture/forestry/apiculture/gadgets/TileAlvearySieve.java new file mode 100755 index 000000000..8c3c378f2 --- /dev/null +++ b/forestry_common/apiculture/forestry/apiculture/gadgets/TileAlvearySieve.java @@ -0,0 +1,179 @@ +/******************************************************************************* + * Copyright 2011-2014 by SirSengir + * + * This work is licensed under a Creative Commons Attribution-NonCommercial-NoDerivs 3.0 Unported License. + * + * To view a copy of this license, visit http://creativecommons.org/licenses/by-nc-nd/3.0/. + ******************************************************************************/ +package forestry.apiculture.gadgets; + +import net.minecraft.entity.player.EntityPlayer; +import net.minecraft.item.ItemStack; +import net.minecraft.nbt.NBTTagCompound; + +import forestry.api.apiculture.IAlvearyComponent; +import forestry.api.apiculture.IBee; +import forestry.api.apiculture.IBeeListener; +import forestry.api.arboriculture.EnumGermlingType; +import forestry.api.core.ForestryAPI; +import forestry.api.genetics.AlleleManager; +import forestry.api.genetics.IIndividual; +import forestry.core.interfaces.ICrafter; +import forestry.core.network.GuiId; +import forestry.core.utils.InventoryAdapter; + +public class TileAlvearySieve extends TileAlveary implements ICrafter, IBeeListener { + + /* CONSTANTS */ + public static final int BLOCK_META = 7; + + public static final int SLOT_POLLEN_1 = 0; + public static final int SLOTS_POLLEN_COUNT = 4; + public static final int SLOT_SIEVE = 4; + + InventoryAdapter inventory = new InventoryAdapter(5, "Items", 1); + + public TileAlvearySieve() { + super(BLOCK_META); + } + + @Override + public void openGui(EntityPlayer player) { + player.openGui(ForestryAPI.instance, GuiId.AlvearySieveGUI.ordinal(), worldObj, xCoord, yCoord, zCoord); + } + + @Override + public String getInventoryName() { + return "tile.alveary.7"; + } + + @Override + public boolean hasFunction() { + return true; + } + + /* UPDATING */ + @Override + public void initialize() { + super.initialize(); + + if(!hasMaster() || !isIntegratedIntoStructure()) + return; + + ((IAlvearyComponent)getCentralTE()).registerBeeListener(this); + } + + + @Override + protected void updateServerSide() { + super.updateServerSide(); + if(worldObj.getTotalWorldTime() % 200 != 0) + return; + + if(!hasMaster() || !isIntegratedIntoStructure()) + return; + + ((IAlvearyComponent)getCentralTE()).registerBeeListener(this); + } + + /* SAVING & LOADING */ + @Override + public void readFromNBT(NBTTagCompound nbttagcompound) { + super.readFromNBT(nbttagcompound); + inventory.readFromNBT(nbttagcompound); + } + + @Override + public void writeToNBT(NBTTagCompound nbttagcompound) { + super.writeToNBT(nbttagcompound); + inventory.writeToNBT(nbttagcompound); + } + + /* TEXTURES & INTERNAL */ + @Override + public int getIcon(int side, int metadata) { + if(side == 0 || side == 1) + return BlockAlveary.BOTTOM; + return BlockAlveary.SIEVE; + } + + private void destroySieve() { + inventory.setInventorySlotContents(SLOT_SIEVE, null); + } + private void destroyPollen() { + for(int i = SLOT_POLLEN_1; i < SLOT_POLLEN_1 + SLOTS_POLLEN_COUNT; i++) { + inventory.setInventorySlotContents(i, null); + } + } + + private boolean canStorePollen() { + if(inventory.getStackInSlot(SLOT_SIEVE) == null) + return false; + + for(int i = SLOT_POLLEN_1; i < SLOT_POLLEN_1 + SLOTS_POLLEN_COUNT; i++) { + if(inventory.getStackInSlot(i) == null) + return true; + } + + return false; + } + + private void storePollenStack(ItemStack itemstack) { + for(int i = SLOT_POLLEN_1; i < SLOT_POLLEN_1 + SLOTS_POLLEN_COUNT; i++) { + if(inventory.getStackInSlot(i) == null) { + inventory.setInventorySlotContents(i, itemstack); + return; + } + } + } + + /* INVENTORY */ + public InventoryAdapter getInternalInventory() { + return inventory; + } + + /* ICRAFTER */ + @Override + public boolean canTakeStack(int slotIndex) { + return true; + } + + @Override + public ItemStack takenFromSlot(int slotIndex, boolean consumeRecipe, EntityPlayer player) { + if(slotIndex == SLOT_SIEVE) { + destroyPollen(); + return inventory.getStackInSlot(SLOT_SIEVE); + } else { + destroySieve(); + return inventory.getStackInSlot(slotIndex); + } + } + + @Override + public ItemStack getResult() { + return null; + } + + /* IBEELISTENER */ + @Override public void onQueenChange(ItemStack queen) {} + @Override public void wearOutEquipment(int amount) {} + @Override public void onQueenDeath(IBee queen) {} + @Override public void onPostQueenDeath(IBee queen) {} + + @Override + public boolean onPollenRetrieved(IBee queen, IIndividual pollen, boolean isHandled) { + + if(isHandled) + return isHandled; + if(!canStorePollen()) + return false; + + storePollenStack(AlleleManager.alleleRegistry.getSpeciesRoot(pollen.getClass()).getMemberStack(pollen, EnumGermlingType.POLLEN.ordinal())); + return true; + } + + @Override + public boolean onEggLaid(IBee queen) { + return false; + } +} diff --git a/forestry_common/apiculture/forestry/apiculture/gadgets/TileAlvearyStabiliser.java b/forestry_common/apiculture/forestry/apiculture/gadgets/TileAlvearyStabiliser.java new file mode 100755 index 000000000..300b9d79a --- /dev/null +++ b/forestry_common/apiculture/forestry/apiculture/gadgets/TileAlvearyStabiliser.java @@ -0,0 +1,115 @@ +/******************************************************************************* + * Copyright 2011-2014 by SirSengir + * + * This work is licensed under a Creative Commons Attribution-NonCommercial-NoDerivs 3.0 Unported License. + * + * To view a copy of this license, visit http://creativecommons.org/licenses/by-nc-nd/3.0/. + ******************************************************************************/ +package forestry.apiculture.gadgets; + +import forestry.api.apiculture.IAlvearyComponent; +import forestry.api.apiculture.IBeeGenome; +import forestry.api.apiculture.IBeeModifier; + +public class TileAlvearyStabiliser extends TileAlveary implements IBeeModifier { + + public static final int BLOCK_META = 6; + + public TileAlvearyStabiliser() { + super(BLOCK_META); + } + + /* UPDATING */ + @Override + public void initialize() { + super.initialize(); + + if(!hasMaster() || !isIntegratedIntoStructure()) + return; + + ((IAlvearyComponent)getCentralTE()).registerBeeModifier(this); + + } + + @Override + protected void updateServerSide() { + super.updateServerSide(); + if(worldObj.getTotalWorldTime() % 200 != 0) + return; + + if(!hasMaster() || !isIntegratedIntoStructure()) + return; + + ((IAlvearyComponent)getCentralTE()).registerBeeModifier(this); + } + + @Override + public String getInventoryName() { + return "tile.alveary.6"; + } + + @Override + public boolean hasFunction() { + return true; + } + + /* TEXTURES */ + public int getIcon(int side, int metadata) { + if(side == 0 || side == 1) + return BlockAlveary.BOTTOM; + + return BlockAlveary.STABILISER; + } + + /* IBEEMODIFIER */ + @Override + public float getMutationModifier(IBeeGenome genome, IBeeGenome mate, float currentModifier) { + return 0.0f; + } + + @Override + public float getTerritoryModifier(IBeeGenome genome, float currentModifier) { + return 1.0f; + } + + @Override + public float getLifespanModifier(IBeeGenome genome, IBeeGenome mate, float currentModifier) { + return 1.0f; + } + + @Override + public float getProductionModifier(IBeeGenome genome, float currentModifier) { + return 1.0f; + } + + @Override + public float getFloweringModifier(IBeeGenome genome, float currentModifier) { + return 1.0f; + } + + @Override + public float getGeneticDecay(IBeeGenome genome, float currentModifier) { + return 1.0f; + } + + @Override + public boolean isSealed() { + return false; + } + + @Override + public boolean isSelfLighted() { + return false; + } + + @Override + public boolean isSunlightSimulated() { + return false; + } + + @Override + public boolean isHellish() { + return false; + } + +} diff --git a/forestry_common/apiculture/forestry/apiculture/gadgets/TileAlvearySwarmer.java b/forestry_common/apiculture/forestry/apiculture/gadgets/TileAlvearySwarmer.java new file mode 100755 index 000000000..de7de05db --- /dev/null +++ b/forestry_common/apiculture/forestry/apiculture/gadgets/TileAlvearySwarmer.java @@ -0,0 +1,305 @@ +/******************************************************************************* + * Copyright 2011-2014 by SirSengir + * + * This work is licensed under a Creative Commons Attribution-NonCommercial-NoDerivs 3.0 Unported License. + * + * To view a copy of this license, visit http://creativecommons.org/licenses/by-nc-nd/3.0/. + ******************************************************************************/ +package forestry.apiculture.gadgets; + +import java.util.Map.Entry; +import java.util.Stack; + +import net.minecraft.entity.player.EntityPlayer; +import net.minecraft.inventory.IInventory; +import net.minecraft.item.ItemStack; +import net.minecraft.nbt.NBTTagCompound; +import net.minecraft.nbt.NBTTagList; + +import net.minecraftforge.common.util.ForgeDirection; + +import buildcraft.api.inventory.ISpecialInventory; + +import forestry.api.apiculture.BeeManager; +import forestry.api.apiculture.EnumBeeType; +import forestry.api.apiculture.IAlvearyComponent; +import forestry.api.apiculture.IBee; +import forestry.api.apiculture.IBeeHousing; +import forestry.api.core.ForestryAPI; +import forestry.apiculture.worldgen.WorldGenHive; +import forestry.apiculture.worldgen.WorldGenHiveSwamer; +import forestry.core.network.GuiId; +import forestry.core.proxy.Proxies; +import forestry.core.utils.TileInventoryAdapter; +import forestry.plugins.PluginApiculture; + +public class TileAlvearySwarmer extends TileAlveary implements ISpecialInventory { + + /* CONSTANTS */ + public static final int BLOCK_META = 2; + + TileInventoryAdapter swarmerInventory; + private final Stack pendingSpawns = new Stack(); + + public TileAlvearySwarmer() { + super(BLOCK_META); + } + + @Override + public void initialize() { + super.initialize(); + if (swarmerInventory == null) + createInventory(); + } + + @Override + public void openGui(EntityPlayer player) { + player.openGui(ForestryAPI.instance, GuiId.AlvearySwarmerGUI.ordinal(), worldObj, xCoord, yCoord, zCoord); + } + + /* UPDATING */ + @Override + protected void updateServerSide() { + super.updateServerSide(); + + if (worldObj.getTotalWorldTime() % 100 != 0) + if (pendingSpawns.size() > 0) + trySpawnSwarm(); + + if (worldObj.getTotalWorldTime() % 500 != 0) + return; + + if (!this.hasMaster()) + return; + + IAlvearyComponent master = (IAlvearyComponent) this.getCentralTE(); + if (!(master instanceof IBeeHousing)) + return; + + IBeeHousing housing = (IBeeHousing) master; + ItemStack queenstack = housing.getQueen(); + if (queenstack == null) + return; + if (!PluginApiculture.beeInterface.isMated(queenstack)) + return; + + // Calculate chance + int slot = getInducerSlot(); + if (slot < 0) + return; + int chance = getChanceFor(swarmerInventory.getStackInSlot(slot)); + + // Remove resource + swarmerInventory.decrStackSize(slot, 1); + + // Try to spawn princess + if (worldObj.rand.nextInt(1000) >= chance) + return; + + // Queue swarm spawn + IBee spawn = PluginApiculture.beeInterface.getMember(queenstack); + spawn.setIsNatural(false); + pendingSpawns.push(PluginApiculture.beeInterface.getMemberStack(spawn, EnumBeeType.PRINCESS.ordinal())); + + } + + private int getChanceFor(ItemStack stack) { + for (Entry entry : BeeManager.inducers.entrySet()) { + if (entry.getKey().isItemEqual(stack)) + return entry.getValue(); + } + + return 0; + } + + private int getInducerSlot() { + for (int i = 0; i < swarmerInventory.getSizeInventory(); i++) { + if (swarmerInventory.getStackInSlot(i) == null) + continue; + for (Entry entry : BeeManager.inducers.entrySet()) { + if (entry.getKey().isItemEqual(swarmerInventory.getStackInSlot(i))) + return i; + } + } + + return -1; + } + + private void trySpawnSwarm() { + + ItemStack toSpawn = pendingSpawns.peek(); + WorldGenHive generator = new WorldGenHiveSwamer(new ItemStack[] { toSpawn }); + + int i = 0; + while (i < 10) { + i++; + int spawnX = xCoord + worldObj.rand.nextInt(40 * 2) - 40; + int spawnY = yCoord + worldObj.rand.nextInt(40); + int spawnZ = zCoord + worldObj.rand.nextInt(40 * 2) - 40; + if (generator.generate(worldObj, worldObj.rand, spawnX, spawnY, spawnZ)) { + pendingSpawns.pop(); + break; + } + } + + } + + @Override + public boolean hasFunction() { + return true; + } + + /* TEXTURES */ + @Override + public int getIcon(int side, int metadata) { + if(side == 0 || side == 1) + return BlockAlveary.BOTTOM; + + if (pendingSpawns.size() > 0) + return BlockAlveary.TX_56_SWON; + else + return BlockAlveary.TX_55_SWOF; + } + + /* SAVING & LOADING */ + @Override + public void readFromNBT(NBTTagCompound nbttagcompound) { + super.readFromNBT(nbttagcompound); + if (swarmerInventory == null) + createInventory(); + swarmerInventory.readFromNBT(nbttagcompound); + + NBTTagList nbttaglist = nbttagcompound.getTagList("PendingSpawns", 10); + for (int i = 0; i < nbttaglist.tagCount(); i++) { + NBTTagCompound nbttagcompound1 = nbttaglist.getCompoundTagAt(i); + pendingSpawns.add(ItemStack.loadItemStackFromNBT(nbttagcompound1)); + } + + } + + @Override + public void writeToNBT(NBTTagCompound nbttagcompound) { + super.writeToNBT(nbttagcompound); + if (swarmerInventory != null) + swarmerInventory.writeToNBT(nbttagcompound); + + NBTTagList nbttaglist = new NBTTagList(); + ItemStack[] offspring = pendingSpawns.toArray(new ItemStack[pendingSpawns.size()]); + for (int i = 0; i < offspring.length; i++) + if (offspring[i] != null) { + NBTTagCompound nbttagcompound1 = new NBTTagCompound(); + nbttagcompound1.setByte("Slot", (byte) i); + offspring[i].writeToNBT(nbttagcompound1); + nbttaglist.appendTag(nbttagcompound1); + } + nbttagcompound.setTag("PendingSpawns", nbttaglist); + + } + + @Override + protected void createInventory() { + swarmerInventory = new TileInventoryAdapter(this, 4, "SwarmInv"); + } + + @Override + public IInventory getInventory() { + return swarmerInventory; + } + + /* ISPECIALINVENTORY */ + @Override + public int addItem(ItemStack stack, boolean doAdd, ForgeDirection from) { + if (swarmerInventory != null) + return swarmerInventory.addStack(stack, false, doAdd); + else + return 0; + } + + @Override + public ItemStack[] extractItem(boolean doRemove, ForgeDirection from, int maxItemCount) { + return null; + } + + /* IINVENTORY */ + @Override + public int getSizeInventory() { + if (swarmerInventory != null) + return swarmerInventory.getSizeInventory(); + else + return 0; + } + + @Override + public ItemStack getStackInSlot(int slotIndex) { + if (swarmerInventory != null) + return swarmerInventory.getStackInSlot(slotIndex); + else + return null; + } + + @Override + public ItemStack decrStackSize(int slotIndex, int amount) { + if (swarmerInventory != null) + return swarmerInventory.decrStackSize(slotIndex, amount); + else + return null; + } + + @Override + public ItemStack getStackInSlotOnClosing(int slotIndex) { + if (swarmerInventory != null) + return swarmerInventory.getStackInSlotOnClosing(slotIndex); + else + return null; + } + + @Override + public void setInventorySlotContents(int slotIndex, ItemStack itemstack) { + // Client side handling for container synch + if (swarmerInventory == null && !Proxies.common.isSimulating(worldObj)) + createInventory(); + + if (swarmerInventory != null) + swarmerInventory.setInventorySlotContents(slotIndex, itemstack); + } + + @Override + public String getInventoryName() { + return "tile.alveary.2"; + } + + @Override + public int getInventoryStackLimit() { + if (swarmerInventory != null) + return swarmerInventory.getInventoryStackLimit(); + else + return 0; + } + + @Override public void openInventory() {} + @Override public void closeInventory() {} + + /** + * TODO: just a specialsource workaround + */ + @Override + public boolean isUseableByPlayer(EntityPlayer player) { + return super.isUseableByPlayer(player); + } + + /** + * TODO: just a specialsource workaround + */ + @Override + public boolean hasCustomInventoryName() { + return super.hasCustomInventoryName(); + } + + /** + * TODO: just a specialsource workaround + */ + @Override + public boolean isItemValidForSlot(int slotIndex, ItemStack itemstack) { + return super.isItemValidForSlot(slotIndex, itemstack); + } +} diff --git a/forestry_common/apiculture/forestry/apiculture/gadgets/TileApiaristChest.java b/forestry_common/apiculture/forestry/apiculture/gadgets/TileApiaristChest.java new file mode 100755 index 000000000..10cb5fdbd --- /dev/null +++ b/forestry_common/apiculture/forestry/apiculture/gadgets/TileApiaristChest.java @@ -0,0 +1,21 @@ +/******************************************************************************* + * Copyright 2011-2014 by SirSengir + * + * This work is licensed under a Creative Commons Attribution-NonCommercial-NoDerivs 3.0 Unported License. + * + * To view a copy of this license, visit http://creativecommons.org/licenses/by-nc-nd/3.0/. + ******************************************************************************/ +package forestry.apiculture.gadgets; + +import forestry.api.genetics.AlleleManager; +import forestry.apiculture.genetics.BeeHelper; +import forestry.core.gadgets.TileNaturalistChest; +import forestry.core.network.GuiId; + +public class TileApiaristChest extends TileNaturalistChest { + + public TileApiaristChest() { + super(AlleleManager.alleleRegistry.getSpeciesRoot(BeeHelper.UID), GuiId.ApiaristChestGUI.ordinal()); + } + +} diff --git a/forestry_common/apiculture/forestry/apiculture/gadgets/TileApiary.java b/forestry_common/apiculture/forestry/apiculture/gadgets/TileApiary.java new file mode 100755 index 000000000..fa2192abb --- /dev/null +++ b/forestry_common/apiculture/forestry/apiculture/gadgets/TileApiary.java @@ -0,0 +1,352 @@ +/******************************************************************************* + * Copyright 2011-2014 by SirSengir + * + * This work is licensed under a Creative Commons Attribution-NonCommercial-NoDerivs 3.0 Unported License. + * + * To view a copy of this license, visit http://creativecommons.org/licenses/by-nc-nd/3.0/. + ******************************************************************************/ +package forestry.apiculture.gadgets; + +import java.util.LinkedList; + +import net.minecraft.entity.player.EntityPlayer; +import net.minecraft.inventory.ISidedInventory; +import net.minecraft.item.ItemStack; + +import buildcraft.api.gates.ITrigger; + +import forestry.api.apiculture.IBeeGenome; +import forestry.api.apiculture.IHiveFrame; +import forestry.api.core.ForestryAPI; +import forestry.core.gadgets.TileBase; +import forestry.core.network.GuiId; +import forestry.core.triggers.ForestryTrigger; +import forestry.plugins.PluginApiculture; + +public class TileApiary extends TileBeehouse implements ISidedInventory { + + @Override + public String getInventoryName() { + return "apiculture.0"; + } + + @Override + public void openGui(EntityPlayer player, TileBase tile) { + player.openGui(ForestryAPI.instance, GuiId.ApiaryGUI.ordinal(), worldObj, xCoord, yCoord, zCoord); + } + + /* IBEEHOUSING */ + @Override + public float getTerritoryModifier(IBeeGenome genome, float currentModifier) { + float mod = 1.0f; + for (int i = SLOT_FRAMES_1; i < SLOT_FRAMES_1 + SLOT_FRAMES_COUNT; i++) { + if (inventory.getStackInSlot(i) == null) + continue; + if (inventory.getStackInSlot(i).getItem() instanceof IHiveFrame) + mod *= ((IHiveFrame) inventory.getStackInSlot(i).getItem()).getTerritoryModifier(genome, mod); + } + return mod; + } + + @Override + public float getProductionModifier(IBeeGenome genome, float currentModifier) { + float mod = 0.1f; + for (int i = SLOT_FRAMES_1; i < SLOT_FRAMES_1 + SLOT_FRAMES_COUNT; i++) { + if (inventory.getStackInSlot(i) == null) + continue; + if (inventory.getStackInSlot(i).getItem() instanceof IHiveFrame) + mod *= ((IHiveFrame) inventory.getStackInSlot(i).getItem()).getProductionModifier(genome, mod); + } + return mod; + } + + @Override + public float getMutationModifier(IBeeGenome genome, IBeeGenome mate, float currentModifier) { + float mod = 1.0f; + for (int i = SLOT_FRAMES_1; i < SLOT_FRAMES_1 + SLOT_FRAMES_COUNT; i++) { + if (inventory.getStackInSlot(i) == null) + continue; + if (inventory.getStackInSlot(i).getItem() instanceof IHiveFrame) + mod *= ((IHiveFrame) inventory.getStackInSlot(i).getItem()).getMutationModifier(genome, mate, mod); + } + return mod; + } + + @Override + public float getLifespanModifier(IBeeGenome genome, IBeeGenome mate, float currentModifier) { + float mod = 1.0f; + for (int i = SLOT_FRAMES_1; i < SLOT_FRAMES_1 + SLOT_FRAMES_COUNT; i++) { + if (inventory.getStackInSlot(i) == null) + continue; + if (inventory.getStackInSlot(i).getItem() instanceof IHiveFrame) + mod *= ((IHiveFrame) inventory.getStackInSlot(i).getItem()).getLifespanModifier(genome, mate, mod); + } + return mod; + } + + @Override + public float getFloweringModifier(IBeeGenome genome, float currentModifier) { + float mod = 1f; + for (int i = SLOT_FRAMES_1; i < SLOT_FRAMES_1 + SLOT_FRAMES_COUNT; i++) { + if (inventory.getStackInSlot(i) == null) + continue; + if (inventory.getStackInSlot(i).getItem() instanceof IHiveFrame) + mod *= ((IHiveFrame) inventory.getStackInSlot(i).getItem()).getFloweringModifier(genome, mod); + } + return mod; + } + + @Override + public float getGeneticDecay(IBeeGenome genome, float currentModifier) { + float mod = 1f; + for (int i = SLOT_FRAMES_1; i < SLOT_FRAMES_1 + SLOT_FRAMES_COUNT; i++) { + if (inventory.getStackInSlot(i) == null) + continue; + if (inventory.getStackInSlot(i).getItem() instanceof IHiveFrame) + mod *= ((IHiveFrame) inventory.getStackInSlot(i).getItem()).getGeneticDecay(genome, mod); + } + return mod; + } + + @Override + public void wearOutEquipment(int amount) { + int wear = Math.round(amount * PluginApiculture.beeInterface.getBeekeepingMode(worldObj).getWearModifier()); + + for (int i = SLOT_FRAMES_1; i < SLOT_FRAMES_1 + SLOT_FRAMES_COUNT; i++) { + if (inventory.getStackInSlot(i) == null) + continue; + if (!(inventory.getStackInSlot(i).getItem() instanceof IHiveFrame)) + continue; + + inventory.setInventorySlotContents( + i, + ((IHiveFrame) inventory.getStackInSlot(i).getItem()).frameUsed(this, inventory.getStackInSlot(i), + PluginApiculture.beeInterface.getMember(inventory.getStackInSlot(SLOT_QUEEN)), wear)); + } + } + + /* IINVENTORY */ + @Override + protected boolean canTakeStackFromSide(int slotIndex, ItemStack itemstack, int side) { + if (!super.canTakeStackFromSide(slotIndex, itemstack, side)) + return false; + + switch (slotIndex) { + case SLOT_QUEEN: + case SLOT_DRONE: + case SLOT_FRAMES_1: + case SLOT_FRAMES_2: + case SLOT_FRAMES_3: + return false; + default: + return true; + } + } + + @Override + protected boolean canPutStackFromSide(int slotIndex, ItemStack itemstack, int side) { + if (!super.canPutStackFromSide(slotIndex, itemstack, side)) + return false; + + if (slotIndex == SLOT_QUEEN && PluginApiculture.beeInterface.isMember(itemstack) + && !PluginApiculture.beeInterface.isDrone(itemstack)) + return true; + + if (slotIndex == SLOT_DRONE && PluginApiculture.beeInterface.isDrone(itemstack)) + return true; + + return false; + } + + /** + * TODO: just a specialsource workaround + */ + @Override + public ItemStack getStackInSlot(int i) { + return super.getStackInSlot(i); + } + + @Override + public void setInventorySlotContents(int i, ItemStack itemstack) { + super.setSlotContents(i, itemstack); + } + + @Override + public int getSizeInventory() { + return inventory.getSizeInventory(); + } + + @Override + public ItemStack decrStackSize(int i, int j) { + return inventory.decrStackSize(i, j); + } + + @Override + public ItemStack getStackInSlotOnClosing(int slot) { + return inventory.getStackInSlotOnClosing(slot); + } + + @Override + public int getInventoryStackLimit() { + return inventory.getInventoryStackLimit(); + } + + @Override + public void openInventory() { + } + + @Override + public void closeInventory() { + } + + /** + * TODO: just a specialsource workaround + */ + @Override + public boolean isUseableByPlayer(EntityPlayer player) { + return super.isUseableByPlayer(player); + } + + /** + * TODO: just a specialsource workaround + */ + @Override + public boolean hasCustomInventoryName() { + return super.hasCustomInventoryName(); + } + + /** + * TODO: just a specialsource workaround + */ + @Override + public boolean isItemValidForSlot(int slotIndex, ItemStack itemstack) { + return super.isItemValidForSlot(slotIndex, itemstack); + } + + /** + * TODO: just a specialsource workaround + */ + @Override + public boolean canInsertItem(int i, ItemStack itemstack, int j) { + return super.canInsertItem(i, itemstack, j); + } + + /** + * TODO: just a specialsource workaround + */ + @Override + public boolean canExtractItem(int i, ItemStack itemstack, int j) { + return super.canExtractItem(i, itemstack, j); + } + + /** + * TODO: just a specialsource workaround + */ + @Override + public int[] getAccessibleSlotsFromSide(int side) { + return super.getAccessibleSlotsFromSide(side); + } + + /* ISPECIALINVENTORY */ + // @Override + // public ItemStack[] extractItem(boolean doRemove, ForgeDirection from, int maxItemCount) { + // ItemStack product = null; + // + // for (int i = SLOT_PRODUCT_1; i < SLOT_PRODUCT_1 + SLOT_PRODUCT_COUNT; i++) { + // if (inventory.getStackInSlot(i) == null) + // continue; + // + // // Princesses can only be extracted from top. + // if (ForestryItem.beePrincessGE.isItemEqual(inventory.getStackInSlot(i))) { + // if (PluginApiculture.apiarySideSensitive && from != ForgeDirection.UP) + // continue; + // + // product = inventory.getStackInSlot(i).copy(); + // if (doRemove) { + // inventory.getStackInSlot(i).stackSize = 0; + // inventory.setInventorySlotContents(i, null); + // } + // break; + // + // // Drones can only be extracted from the bottom. + // } else if (ForestryItem.beeDroneGE.isItemEqual(inventory.getStackInSlot(i))) { + // if (PluginApiculture.apiarySideSensitive && from != ForgeDirection.DOWN) + // continue; + // + // product = StackUtils.createSplitStack(inventory.getStackInSlot(i), 1); + // product.stackSize = 1; + // if (doRemove) { + // inventory.getStackInSlot(i).stackSize--; + // if (inventory.getStackInSlot(i).stackSize <= 0) + // inventory.setInventorySlotContents(i, null); + // } + // break; + // + // // Everything else to be extracted from the sides + // } else { + // if (PluginApiculture.apiarySideSensitive && (from == ForgeDirection.UP || from == ForgeDirection.DOWN)) + // continue; + // + // product = StackUtils.createSplitStack(inventory.getStackInSlot(i), 1); + // if (doRemove) { + // inventory.getStackInSlot(i).stackSize--; + // if (inventory.getStackInSlot(i).stackSize <= 0) + // inventory.setInventorySlotContents(i, null); + // } + // break; + // } + // } + // + // return new ItemStack[] { product }; + // } + // + // @Override + // public int addItem(ItemStack stack, boolean doAdd, ForgeDirection from) { + // // Princesses && Queens + // if (ForestryItem.beePrincessGE.isItemEqual(stack) || ForestryItem.beeQueenGE.isItemEqual(stack)) + // if (inventory.getStackInSlot(SLOT_QUEEN) == null) { + // if (doAdd) { + // inventory.setInventorySlotContents(SLOT_QUEEN, stack.copy()); + // inventory.getStackInSlot(SLOT_QUEEN).stackSize = 1; + // } + // + // return 1; + // } + // + // // Drones + // if (ForestryItem.beeDroneGE.isItemEqual(stack)) { + // + // ItemStack droneStack = inventory.getStackInSlot(SLOT_DRONE); + // if (droneStack == null) { + // if (doAdd) + // inventory.setInventorySlotContents(SLOT_DRONE, stack.copy()); + // return stack.stackSize; + // } else { + // if (!droneStack.isItemEqual(stack)) + // return 0; + // if (!ItemStack.areItemStackTagsEqual(droneStack, stack)) + // return 0; + // int space = droneStack.getMaxStackSize() - droneStack.stackSize; + // if (space <= 0) + // return 0; + // + // int added = space > stack.stackSize ? stack.stackSize : space; + // if (doAdd) + // droneStack.stackSize += added; + // return added; + // } + // } + // + // return 0; + // } + + /* ITRIGGERPROVIDER */ + @Override + public LinkedList getCustomTriggers() { + LinkedList res = new LinkedList(); + res.add(ForestryTrigger.missingQueen); + res.add(ForestryTrigger.missingDrone); + res.add(PluginApiculture.triggerNoFrames); + return res; + } +} diff --git a/forestry_common/apiculture/forestry/apiculture/gadgets/TileBeehouse.java b/forestry_common/apiculture/forestry/apiculture/gadgets/TileBeehouse.java new file mode 100755 index 000000000..031f338e5 --- /dev/null +++ b/forestry_common/apiculture/forestry/apiculture/gadgets/TileBeehouse.java @@ -0,0 +1,438 @@ +/******************************************************************************* + * Copyright 2011-2014 by SirSengir + * + * This work is licensed under a Creative Commons Attribution-NonCommercial-NoDerivs 3.0 Unported License. + * + * To view a copy of this license, visit http://creativecommons.org/licenses/by-nc-nd/3.0/. + ******************************************************************************/ +package forestry.apiculture.gadgets; + +import net.minecraft.entity.player.EntityPlayer; +import net.minecraft.inventory.Container; +import net.minecraft.inventory.ICrafting; +import net.minecraft.item.ItemStack; +import net.minecraft.nbt.NBTTagCompound; +import net.minecraft.world.World; +import net.minecraft.world.biome.BiomeGenBase; + +import forestry.api.apiculture.IBee; +import forestry.api.apiculture.IBeeGenome; +import forestry.api.apiculture.IBeeHousing; +import forestry.api.apiculture.IBeekeepingLogic; +import forestry.api.core.EnumHumidity; +import forestry.api.core.EnumTemperature; +import forestry.api.core.ForestryAPI; +import forestry.api.genetics.IIndividual; +import forestry.core.EnumErrorCode; +import forestry.core.config.Config; +import forestry.core.config.ForestryItem; +import forestry.core.gadgets.TileBase; +import forestry.core.interfaces.IClimatised; +import forestry.core.network.GuiId; +import forestry.core.network.PacketIds; +import forestry.core.network.PacketInventoryStack; +import forestry.core.network.PacketTileUpdate; +import forestry.core.proxy.Proxies; +import forestry.core.utils.InventoryAdapter; +import forestry.core.utils.Utils; +import forestry.plugins.PluginApiculture; + +public class TileBeehouse extends TileBase implements IBeeHousing, IClimatised { + + // CONSTANTS + public static final int SLOT_QUEEN = 0; + public static final int SLOT_DRONE = 1; + public static final int SLOT_INVENTORY_1 = 2; + protected static int SLOT_PRODUCT_1 = 2; + protected static int SLOT_PRODUCT_COUNT = 7; + public static final int SLOT_FRAMES_1 = 9; + public static final int SLOT_FRAMES_2 = 10; + public static final int SLOT_FRAMES_3 = 11; + public static final int SLOT_INVENTORY_COUNT = 7; + public static final int SLOT_FRAMES_COUNT = 3; + // Inventory + protected InventoryAdapter inventory = new InventoryAdapter(12, "Items"); + private final IBeekeepingLogic logic; + private int biomeId = -1; + private float temperature; + private float humidity; + private int displayHealthMax = 0; + private int displayHealth = 0; + + public TileBeehouse() { + setHints(Config.hints.get("apiary")); + logic = PluginApiculture.beeInterface.createBeekeepingLogic(this); + } + + @Override + public String getInventoryName() { + return "apiculture.2"; + } + + @Override + public void openGui(EntityPlayer player, TileBase tile) { + player.openGui(ForestryAPI.instance, GuiId.BeehouseGUI.ordinal(), worldObj, xCoord, yCoord, zCoord); + } + + /* LOADING & SAVING */ + @Override + public void writeToNBT(NBTTagCompound nbttagcompound) { + super.writeToNBT(nbttagcompound); + + nbttagcompound.setFloat("Temp", temperature); + nbttagcompound.setFloat("Humidity", humidity); + nbttagcompound.setInteger("BiomeId", biomeId); + + inventory.writeToNBT(nbttagcompound); + if (logic != null) + logic.writeToNBT(nbttagcompound); + } + + @Override + public void readFromNBT(NBTTagCompound nbttagcompound) { + super.readFromNBT(nbttagcompound); + + temperature = nbttagcompound.getFloat("Temp"); + humidity = nbttagcompound.getFloat("Humidity"); + biomeId = nbttagcompound.getInteger("BiomeId"); + + inventory.readFromNBT(nbttagcompound); + logic.readFromNBT(nbttagcompound); + + } + + @Override + public void initialize() { + super.initialize(); + updateBiome(); + } + + @Override + public void validate() { + updateBiome(); + } + + /* ICLIMATISED */ + @Override + public boolean isClimatized() { + return true; + } + + @Override + public EnumTemperature getTemperature() { + if (EnumTemperature.isBiomeHellish(biomeId)) + return EnumTemperature.HELLISH; + return EnumTemperature.getFromValue(temperature); + } + + @Override + public EnumHumidity getHumidity() { + return EnumHumidity.getFromValue(humidity); + } + + @Override + public float getExactTemperature() { + return this.temperature; + } + + @Override + public float getExactHumidity() { + return this.humidity; + } + + /* UPDATING */ + @Override + public void updateClientSide() { + + // / Multiplayer FX + if (PluginApiculture.beeInterface.isMated(inventory.getStackInSlot(SLOT_QUEEN))) + if (getErrorState() == EnumErrorCode.OK && worldObj.getTotalWorldTime() % 2 % 2 == 0) { + IBee displayQueen = PluginApiculture.beeInterface.getMember(inventory.getStackInSlot(SLOT_QUEEN)); + displayQueen.doFX(logic.getEffectData(), this); + } + return; + + } + + @Override + public void updateServerSide() { + + logic.update(); + + IBee queen = logic.getQueen(); + if (queen == null) + return; + + // Add swarm effects + if (worldObj.getTotalWorldTime() % 200 * 10 == 0) + onQueenChange(inventory.getStackInSlot(SLOT_QUEEN)); + /* These should get already done on the client / doesn't work server-side anyway + if (getErrorState() == EnumErrorCode.OK && worldObj.getTotalWorldTime() % 2 % 2 == 0) + queen.doFX(logic.getEffectData(), this); + + if (getErrorState() == EnumErrorCode.OK && worldObj.getTotalWorldTime() % 50 == 0) { + float f = xCoord + 0.5F; + float f1 = yCoord + 0.0F + (worldObj.rand.nextFloat() * 6F) / 16F; + float f2 = zCoord + 0.5F; + float f3 = 0.52F; + float f4 = worldObj.rand.nextFloat() * 0.6F - 0.3F; + + Proxies.common.addEntitySwarmFX(worldObj, (f - f3), f1, (f2 + f4), 0F, 0F, 0F); + Proxies.common.addEntitySwarmFX(worldObj, (f + f3), f1, (f2 + f4), 0F, 0F, 0F); + Proxies.common.addEntitySwarmFX(worldObj, (f + f4), f1, (f2 - f3), 0F, 0F, 0F); + Proxies.common.addEntitySwarmFX(worldObj, (f + f4), f1, (f2 + f3), 0F, 0F, 0F); + }*/ + + } + + // @Override + public boolean isWorking() { + return getErrorState() == EnumErrorCode.OK; + } + + @Override + public boolean addProduct(ItemStack product, boolean all) { + return inventory.tryAddStack(product, SLOT_PRODUCT_1, SLOT_PRODUCT_COUNT, all, true); + } + + /* NETWORK SYNCH */ + @Override + public void onQueenChange(ItemStack queenStack) { + if (!Proxies.common.isSimulating(worldObj)) + return; + + Proxies.net.sendNetworkPacket(new PacketInventoryStack(PacketIds.IINVENTORY_STACK, xCoord, yCoord, zCoord, SLOT_QUEEN, queenStack), xCoord, yCoord, + zCoord); + Proxies.net.sendNetworkPacket(new PacketTileUpdate(this), xCoord, yCoord, zCoord); + } + + /* STATE INFORMATION */ + private int getHealthDisplay() { + if (inventory.getStackInSlot(SLOT_QUEEN) == null) + return 0; + + if (ForestryItem.beeQueenGE.isItemEqual(inventory.getStackInSlot(SLOT_QUEEN))) + return PluginApiculture.beeInterface.getMember(inventory.getStackInSlot(SLOT_QUEEN)).getHealth(); + else if (ForestryItem.beePrincessGE.isItemEqual(inventory.getStackInSlot(SLOT_QUEEN))) + return displayHealth; + else + return 0; + } + + private int getMaxHealthDisplay() { + if (inventory.getStackInSlot(SLOT_QUEEN) == null) + return 0; + + if (ForestryItem.beeQueenGE.isItemEqual(inventory.getStackInSlot(SLOT_QUEEN))) + return PluginApiculture.beeInterface.getMember(inventory.getStackInSlot(SLOT_QUEEN)).getMaxHealth(); + else if (ForestryItem.beePrincessGE.isItemEqual(inventory.getStackInSlot(SLOT_QUEEN))) + return displayHealthMax; + else + return 0; + } + + /** + * Returns scaled queen health or breeding progress + * + * @param i + * @return + */ + public int getHealthScaled(int i) { + if (getMaxHealthDisplay() == 0) + return 0; + + return (getHealthDisplay() * i) / getMaxHealthDisplay(); + } + + public int getTemperatureScaled(int i) { + return Math.round(i * (temperature / 2)); + } + + public int getHumidityScaled(int i) { + return Math.round(i * humidity); + } + + public void updateBiome() { + if (worldObj != null) { + BiomeGenBase biome = Utils.getBiomeAt(worldObj, xCoord, zCoord); + if (biome != null) { + this.biomeId = biome.biomeID; + this.temperature = biome.temperature; + this.humidity = biome.rainfall; + setErrorState(EnumErrorCode.OK); + } + } + } + + /* SMP */ + // @Override + public void getGUINetworkData(int i, int j) { + if (logic == null) + return; + + switch (i) { + case 0: + displayHealth = j; + break; + case 1: + displayHealthMax = j; + break; + } + } + + // @Override + public void sendGUINetworkData(Container container, ICrafting iCrafting) { + if (logic == null) + return; + + iCrafting.sendProgressBarUpdate(container, 0, logic.getBreedingTime()); + iCrafting.sendProgressBarUpdate(container, 1, logic.getTotalBreedingTime()); + } + + /* INVENTORY MANAGMENT */ + @Override + public InventoryAdapter getInternalInventory() { + return inventory; + } + + public ItemStack getStackInSlot(int i) { + return inventory.getStackInSlot(i); + } + + public void setSlotContents(int i, ItemStack itemstack) { + inventory.setInventorySlotContents(i, itemstack); + } + + // / IBEEHOUSING + @Override + public int getXCoord() { + return xCoord; + } + + @Override + public int getYCoord() { + return yCoord; + } + + @Override + public int getZCoord() { + return zCoord; + } + + @Override + public int getBiomeId() { + return this.biomeId; + } + + @Override + public ItemStack getQueen() { + return getStackInSlot(SLOT_QUEEN); + } + + @Override + public ItemStack getDrone() { + return getStackInSlot(SLOT_DRONE); + } + + @Override + public void setQueen(ItemStack itemstack) { + setSlotContents(SLOT_QUEEN, itemstack); + } + + @Override + public void setDrone(ItemStack itemstack) { + setSlotContents(SLOT_DRONE, itemstack); + } + + @Override + public World getWorld() { + return worldObj; + } + + @Override + public void setErrorState(int state) { + setErrorState(EnumErrorCode.values()[state]); + } + + @Override + public int getErrorOrdinal() { + return getErrorState().ordinal(); + } + + @Override + public boolean canBreed() { + return true; + } + + @Override + public float getTerritoryModifier(IBeeGenome genome, float currentModifier) { + return 1.0f; + } + + @Override + public float getProductionModifier(IBeeGenome genome, float currentModifier) { + return 0.25f; + } + + @Override + public float getMutationModifier(IBeeGenome genome, IBeeGenome mate, float currentModifier) { + return 0.0f; + } + + @Override + public float getLifespanModifier(IBeeGenome genome, IBeeGenome mate, float currentModifier) { + return 3.0f; + } + + @Override + public float getFloweringModifier(IBeeGenome genome, float currentModifier) { + return 3.0f; + } + + @Override + public float getGeneticDecay(IBeeGenome genome, float currentModifier) { + return 0.0f; + } + + @Override + public void wearOutEquipment(int amount) { + } + + @Override + public boolean isSealed() { + return false; + } + + @Override + public boolean isSelfLighted() { + return false; + } + + @Override + public boolean isSunlightSimulated() { + return false; + } + + @Override + public boolean isHellish() { + return false; + } + + @Override + public void onQueenDeath(IBee queen) { + } + + @Override + public void onPostQueenDeath(IBee queen) { + } + + @Override + public boolean onPollenRetrieved(IBee queen, IIndividual pollen, boolean isHandled) { + return false; + } + + @Override + public boolean onEggLaid(IBee queen) { + return false; + } +} diff --git a/forestry_common/apiculture/forestry/apiculture/gadgets/TileCandle.java b/forestry_common/apiculture/forestry/apiculture/gadgets/TileCandle.java new file mode 100755 index 000000000..8fb61efee --- /dev/null +++ b/forestry_common/apiculture/forestry/apiculture/gadgets/TileCandle.java @@ -0,0 +1,82 @@ +/******************************************************************************* + * Copyright 2011-2014 by SirSengir + * + * This work is licensed under a Creative Commons Attribution-NonCommercial-NoDerivs 3.0 Unported License. + * + * To view a copy of this license, visit http://creativecommons.org/licenses/by-nc-nd/3.0/. + ******************************************************************************/ +package forestry.apiculture.gadgets; + +import net.minecraft.nbt.NBTTagCompound; +import net.minecraft.network.NetworkManager; +import net.minecraft.network.Packet; +import net.minecraft.network.play.server.S35PacketUpdateTileEntity; +import net.minecraft.tileentity.TileEntity; + +public class TileCandle extends TileEntity { + private int colour; + + // This is a non-ticking Tile Entity. + @Override + public boolean canUpdate() { + return false; + } + + @Override + public Packet getDescriptionPacket() { + NBTTagCompound nbt = new NBTTagCompound(); + writeToNBT(nbt); + + return new S35PacketUpdateTileEntity(xCoord, yCoord, zCoord, 0, nbt); + } + + @Override + public void onDataPacket(NetworkManager net, S35PacketUpdateTileEntity pkt) { + readFromNBT(pkt.func_148857_g()); + } + + @Override + public void readFromNBT(NBTTagCompound tagRoot) { + super.readFromNBT(tagRoot); + this.setColour(tagRoot.getInteger("colour")); + } + + @Override + public void writeToNBT(NBTTagCompound tagRoot) { + super.writeToNBT(tagRoot); + tagRoot.setInteger("colour", this.colour); + } + + public int getColour() { + return this.colour; + } + + public void setColour(int value) { + this.colour = value; + } + + public void setColour(int red, int green, int blue) { + this.colour = toIntColour(red, green, blue); + } + + /*public void setColour(int[] cs) { + this.colour = toIntColour(cs[0], cs[1], cs[2]); + }*/ + + public void addColour(int red, int green, int blue) { + int[] myColour = fromIntColour(this.colour); + this.colour = toIntColour((red + myColour[0]) / 2, (green + myColour[0]) / 2, (blue + myColour[2]) / 2); + } + + private static int[] fromIntColour(int value) { + int[] cs = new int[3]; + cs[0] = (value & 0xff0000) >> 16; + cs[1] = (value & 0x00ff00) >> 8; + cs[2] = value & 0x0000ff; + return cs; + } + + private static int toIntColour(int r, int g, int b) { + return r << 16 | g << 8 | b; + } +} diff --git a/forestry_common/apiculture/forestry/apiculture/gadgets/TileSwarm.java b/forestry_common/apiculture/forestry/apiculture/gadgets/TileSwarm.java new file mode 100755 index 000000000..d494f420d --- /dev/null +++ b/forestry_common/apiculture/forestry/apiculture/gadgets/TileSwarm.java @@ -0,0 +1,52 @@ +/******************************************************************************* + * Copyright 2011-2014 by SirSengir + * + * This work is licensed under a Creative Commons Attribution-NonCommercial-NoDerivs 3.0 Unported License. + * + * To view a copy of this license, visit http://creativecommons.org/licenses/by-nc-nd/3.0/. + ******************************************************************************/ +package forestry.apiculture.gadgets; + +import net.minecraft.item.ItemStack; +import net.minecraft.nbt.NBTTagCompound; +import net.minecraft.tileentity.TileEntity; + +import forestry.core.utils.InventoryAdapter; + +public class TileSwarm extends TileEntity { + + public InventoryAdapter contained = new InventoryAdapter(2, "Contained"); + + @Override + public boolean canUpdate() { + return false; + } + + public TileSwarm setContained(ItemStack[] bees) { + for (ItemStack itemstack : bees) + contained.addStack(itemstack, false, true); + + return this; + } + + public boolean containsBees() { + for (int i = 0; i < contained.getSizeInventory(); i++) + if (contained.getStackInSlot(i) != null) + return true; + + return false; + } + + @Override + public void readFromNBT(NBTTagCompound nbttagcompound) { + super.readFromNBT(nbttagcompound); + contained.readFromNBT(nbttagcompound); + } + + @Override + public void writeToNBT(NBTTagCompound nbttagcompound) { + super.writeToNBT(nbttagcompound); + contained.writeToNBT(nbttagcompound); + } + +} diff --git a/forestry_common/apiculture/forestry/apiculture/genetics/AIAvoidPlayers.java b/forestry_common/apiculture/forestry/apiculture/genetics/AIAvoidPlayers.java new file mode 100755 index 000000000..d80e7820d --- /dev/null +++ b/forestry_common/apiculture/forestry/apiculture/genetics/AIAvoidPlayers.java @@ -0,0 +1,87 @@ +/******************************************************************************* + * Copyright 2011-2014 by SirSengir + * + * This work is licensed under a Creative Commons Attribution-NonCommercial-NoDerivs 3.0 Unported License. + * + * To view a copy of this license, visit http://creativecommons.org/licenses/by-nc-nd/3.0/. + ******************************************************************************/ +package forestry.apiculture.genetics; + +import net.minecraft.entity.EntityCreature; +import net.minecraft.entity.ai.EntityAIBase; +import net.minecraft.entity.ai.RandomPositionGenerator; +import net.minecraft.entity.player.EntityPlayer; +import net.minecraft.pathfinding.PathEntity; +import net.minecraft.pathfinding.PathNavigate; +import net.minecraft.util.Vec3; + +public class AIAvoidPlayers extends EntityAIBase { + + private EntityCreature mob; + + private float farSpeed; + private float nearSpeed; + private float minDistance; + + private PathEntity pathing; + + private PathNavigate pathNavigator; + + private EntityPlayer player; + + public AIAvoidPlayers(EntityCreature mob, float minDistance, float farSpeed, float nearSpeed) { + this.mob = mob; + this.minDistance = minDistance; + this.farSpeed = farSpeed; + this.nearSpeed = nearSpeed; + this.pathNavigator = mob.getNavigator(); + this.setMutexBits(1); + } + + @Override + public boolean shouldExecute() { + + player = mob.worldObj.getClosestPlayerToEntity(mob, minDistance); + + if (player == null) + return false; + + if (!mob.getEntitySenses().canSee(player)) + return false; + + Vec3 randomTarget = RandomPositionGenerator.findRandomTargetBlockAwayFrom(mob, 16, 7, + mob.worldObj.getWorldVec3Pool().getVecFromPool(player.posX, player.posY, player.posZ)); + + if (randomTarget == null) + return false; + + if (player.getDistanceSq(randomTarget.xCoord, randomTarget.yCoord, randomTarget.zCoord) < player.getDistanceSqToEntity(mob)) + return false; + + pathing = pathNavigator.getPathToXYZ(randomTarget.xCoord, randomTarget.yCoord, randomTarget.zCoord); + return pathing == null ? false : pathing.isDestinationSame(randomTarget); + } + + @Override + public boolean continueExecuting() { + return !this.pathNavigator.noPath(); + } + + @Override + public void startExecuting() { + this.pathNavigator.setPath(pathing, farSpeed); + } + + @Override + public void resetTask() { + player = null; + } + + @Override + public void updateTask() { + if (mob.getDistanceSqToEntity(player) < 49.0D) + mob.getNavigator().setSpeed(nearSpeed); + else + mob.getNavigator().setSpeed(farSpeed); + } +} diff --git a/forestry_common/apiculture/forestry/apiculture/genetics/AlleleBeeSpecies.java b/forestry_common/apiculture/forestry/apiculture/genetics/AlleleBeeSpecies.java new file mode 100755 index 000000000..1eefe2a7c --- /dev/null +++ b/forestry_common/apiculture/forestry/apiculture/genetics/AlleleBeeSpecies.java @@ -0,0 +1,233 @@ +/******************************************************************************* + * Copyright 2011-2014 by SirSengir + * + * This work is licensed under a Creative Commons Attribution-NonCommercial-NoDerivs 3.0 Unported License. + * + * To view a copy of this license, visit http://creativecommons.org/licenses/by-nc-nd/3.0/. + ******************************************************************************/ +package forestry.apiculture.genetics; + +import java.util.ArrayList; +import java.util.HashMap; +import java.util.Locale; + +import net.minecraft.client.renderer.texture.IIconRegister; +import net.minecraft.item.ItemStack; +import net.minecraft.util.IIcon; +import net.minecraft.world.World; + +import cpw.mods.fml.relauncher.Side; +import cpw.mods.fml.relauncher.SideOnly; + +import forestry.api.apiculture.EnumBeeChromosome; +import forestry.api.apiculture.EnumBeeType; +import forestry.api.apiculture.IAlleleBeeSpecies; +import forestry.api.apiculture.IBeeGenome; +import forestry.api.apiculture.IBeeHousing; +import forestry.api.apiculture.IBeeRoot; +import forestry.api.core.IIconProvider; +import forestry.api.genetics.AlleleManager; +import forestry.api.genetics.IAllele; +import forestry.api.genetics.IClassification; +import forestry.api.genetics.IIndividual; +import forestry.api.genetics.IMutation; +import forestry.core.config.Defaults; +import forestry.core.genetics.AlleleSpecies; +import forestry.core.render.TextureManager; +import forestry.core.utils.StackUtils; + +public class AlleleBeeSpecies extends AlleleSpecies implements IAlleleBeeSpecies, IIconProvider { + + public IJubilanceProvider jubilanceProvider; + + private IBeeRoot root; + + private HashMap products = new HashMap(); + private HashMap specialty = new HashMap(); + + private String texture; + private int primaryColour; + private int secondaryColour; + + private String iconType = "default"; + + public AlleleBeeSpecies(String uid, boolean dominant, String name, IClassification branch, int primaryColor, int secondaryColor) { + this(uid, dominant, name, branch, null, primaryColor, secondaryColor); + } + + public AlleleBeeSpecies(String uid, boolean dominant, String name, IClassification branch, String binomial, int primaryColor, int secondaryColor) { + this(uid, dominant, name, branch, binomial, primaryColor, secondaryColor, new JubilanceDefault()); + } + + public AlleleBeeSpecies(String uid, boolean dominant, String name, IClassification branch, String binomial, int primaryColor, int secondaryColor, + IJubilanceProvider jubilanceProvider) { + super(uid, dominant, name, branch, binomial); + + this.root = (IBeeRoot)AlleleManager.alleleRegistry.getSpeciesRoot("rootBees"); + this.primaryColour = primaryColor; + this.secondaryColour = secondaryColor; + this.jubilanceProvider = jubilanceProvider; + texture = Defaults.TEXTURE_PATH_ENTITIES + "/bees/honeyBee.png"; + } + + @Override + public IBeeRoot getRoot() { + return root; + } + + public AlleleBeeSpecies setEntityTexture(String texture) { + this.texture = Defaults.TEXTURE_PATH_ENTITIES + "/bees/" + texture + ".png"; + return this; + } + + public AlleleBeeSpecies addProduct(ItemStack product, int chance) { + this.products.put(product, chance); + return this; + } + + public AlleleBeeSpecies addSpecialty(ItemStack specialty, int chance) { + this.specialty.put(specialty, chance); + return this; + } + + public AlleleBeeSpecies setJubilanceProvider(IJubilanceProvider provider) { + this.jubilanceProvider = provider; + return this; + } + + /* RESEARCH */ + @Override + public int getComplexity() { + return 1 + getGeneticAdvancement(this, new ArrayList()); + } + + private int getGeneticAdvancement(IAllele species, ArrayList exclude) { + + int own = 1; + int highest = 0; + exclude.add(species); + + for(IMutation mutation : getRoot().getPaths(species, EnumBeeChromosome.SPECIES.ordinal())) { + if(!exclude.contains(mutation.getAllele0())) { + int otherAdvance = getGeneticAdvancement(mutation.getAllele0(), exclude); + if(otherAdvance > highest) + highest = otherAdvance; + } + if(!exclude.contains(mutation.getAllele1())) { + int otherAdvance = getGeneticAdvancement(mutation.getAllele1(), exclude); + if(otherAdvance > highest) + highest = otherAdvance; + } + } + + return own + (highest < 0 ? 0 : highest); + } + + @Override + public float getResearchSuitability(ItemStack itemstack) { + if(itemstack == null) + return 0f; + + for(ItemStack stack : products.keySet()) + if(stack.isItemEqual(itemstack)) + return 1.0f; + for(ItemStack stack : specialty.keySet()) + if(stack.isItemEqual(itemstack)) + return 1.0f; + + return super.getResearchSuitability(itemstack); + } + + @Override + public ItemStack[] getResearchBounty(World world, String researcher, IIndividual individual, int bountyLevel) { + ArrayList bounty = new ArrayList(); + for(ItemStack stack : super.getResearchBounty(world, researcher, individual, bountyLevel)) + bounty.add(stack); + + if(bountyLevel > 10) { + for(ItemStack stack : specialty.keySet()) { + bounty.add(StackUtils.copyWithRandomSize(stack, (int)((float)bountyLevel / 2), world.rand)); + } + } + for(ItemStack stack : products.keySet()) { + bounty.add(StackUtils.copyWithRandomSize(stack, (int)((float)bountyLevel / 2), world.rand)); + } + return bounty.toArray(StackUtils.EMPTY_STACK_ARRAY); + } + + /* OTHER */ + @Override + public boolean isNocturnal() { + return false; + } + + @Override + public HashMap getProducts() { + return products; + } + + @Override + public HashMap getSpecialty() { + return specialty; + } + + @Override + public boolean isJubilant(IBeeGenome genome, IBeeHousing housing) { + return jubilanceProvider.isJubilant(this, genome, housing); + } + + @Override + public String getEntityTexture() { + return texture; + } + + @Override + public int getIconColour(int renderPass) { + if (renderPass == 0) + return primaryColour; + if (renderPass == 1) + return secondaryColour; + return 0xffffff; + } + + @SideOnly(Side.CLIENT) + private static IIcon[][] icons; + + @SideOnly(Side.CLIENT) + @Override + public void registerIcons(IIconRegister register) { + icons = new IIcon[EnumBeeType.values().length][3]; + + IIcon body1 = TextureManager.getInstance().registerTex(register, "bees/" + iconType + "/body1"); + + for (int i = 0; i < EnumBeeType.values().length; i++) { + if(EnumBeeType.values()[i] == EnumBeeType.NONE) + continue; + + icons[i][0] = TextureManager.getInstance().registerTex(register, "bees/" + iconType + "/" + EnumBeeType.values()[i].toString().toLowerCase(Locale.ENGLISH) + ".outline");; + icons[i][1] = (EnumBeeType.values()[i] != EnumBeeType.LARVAE) ? body1 + : TextureManager.getInstance().registerTex(register, "bees/" + iconType + "/" + EnumBeeType.values()[i].toString().toLowerCase(Locale.ENGLISH) + ".body"); + icons[i][2] = TextureManager.getInstance().registerTex(register, "bees/" + iconType + "/" + EnumBeeType.values()[i].toString().toLowerCase(Locale.ENGLISH) + ".body2"); + } + + } + + @Override + @SideOnly(Side.CLIENT) + public IIcon getIcon(EnumBeeType type, int renderPass) { + return icons[type.ordinal()][renderPass]; + } + + @Override + @SideOnly(Side.CLIENT) + public IIconProvider getIconProvider() { + return this; + } + + @Override + @SideOnly(Side.CLIENT) + public IIcon getIcon(short texUID) { + return null; + } + +} diff --git a/forestry_common/apiculture/forestry/apiculture/genetics/AlleleEffectAggressive.java b/forestry_common/apiculture/forestry/apiculture/genetics/AlleleEffectAggressive.java new file mode 100755 index 000000000..aff8f5ebb --- /dev/null +++ b/forestry_common/apiculture/forestry/apiculture/genetics/AlleleEffectAggressive.java @@ -0,0 +1,67 @@ +/******************************************************************************* + * Copyright 2011-2014 by SirSengir + * + * This work is licensed under a Creative Commons Attribution-NonCommercial-NoDerivs 3.0 Unported License. + * + * To view a copy of this license, visit http://creativecommons.org/licenses/by-nc-nd/3.0/. + ******************************************************************************/ +package forestry.apiculture.genetics; + +import java.util.List; + +import net.minecraft.entity.EntityLivingBase; +import net.minecraft.entity.player.EntityPlayer; +import net.minecraft.util.AxisAlignedBB; +import net.minecraft.util.DamageSource; + +import forestry.api.apiculture.IBeeGenome; +import forestry.api.apiculture.IBeeHousing; +import forestry.api.genetics.IEffectData; +import forestry.apiculture.items.ItemArmorApiarist; +import forestry.core.utils.DamageSourceForestry; + +public class AlleleEffectAggressive extends AlleleEffectThrottled { + + public static DamageSource damageSourceBeeAggressive = new DamageSourceForestry("bee.aggressive"); + + public AlleleEffectAggressive(String uid) { + super(uid, "aggressive", true, 40, false, false); + } + + @Override + public IEffectData doEffect(IBeeGenome genome, IEffectData storedData, IBeeHousing housing) { + + if (isHalted(storedData, housing)) + return storedData; + + AxisAlignedBB hurtBox = getBounding(genome, housing, 1.0f); + @SuppressWarnings("rawtypes") + List list = housing.getWorld().getEntitiesWithinAABB(EntityLivingBase.class, hurtBox); + + for (Object obj : list) { + EntityLivingBase entity = (EntityLivingBase) obj; + + int damage = 4; + + // Players are not attacked if they wear a full set of apiarist's + // armor. + if (entity instanceof EntityPlayer) { + int count = ItemArmorApiarist.wearsItems((EntityPlayer) entity, getUID(), true); + // Full set, no damage/effect + if (count > 3) + continue; + else if (count > 2) + damage = 1; + else if (count > 1) + damage = 2; + else if (count > 0) + damage = 3; + } + + entity.attackEntityFrom(damageSourceBeeAggressive, damage); + } + + return storedData; + } + +} diff --git a/forestry_common/apiculture/forestry/apiculture/genetics/AlleleEffectCreeper.java b/forestry_common/apiculture/forestry/apiculture/genetics/AlleleEffectCreeper.java new file mode 100755 index 000000000..1f9130270 --- /dev/null +++ b/forestry_common/apiculture/forestry/apiculture/genetics/AlleleEffectCreeper.java @@ -0,0 +1,111 @@ +/******************************************************************************* + * Copyright 2011-2014 by SirSengir + * + * This work is licensed under a Creative Commons Attribution-NonCommercial-NoDerivs 3.0 Unported License. + * + * To view a copy of this license, visit http://creativecommons.org/licenses/by-nc-nd/3.0/. + ******************************************************************************/ +package forestry.apiculture.genetics; + +import java.util.List; + +import net.minecraft.entity.player.EntityPlayer; +import net.minecraft.util.AxisAlignedBB; +import net.minecraft.world.World; + +import forestry.api.apiculture.IBeeGenome; +import forestry.api.apiculture.IBeeHousing; +import forestry.api.genetics.IEffectData; +import forestry.apiculture.items.ItemArmorApiarist; +import forestry.core.genetics.EffectData; + +public class AlleleEffectCreeper extends AlleleEffectThrottled { + + private final int explosionChance = 50; + byte defaultForce = 12; + byte indexExplosionTimer = 1; + byte indexExplosionForce = 2; + + public AlleleEffectCreeper(String uid) { + super(uid, "creeper", true, 20, false, true); + } + + @Override + public IEffectData validateStorage(IEffectData storedData) { + if (!(storedData instanceof EffectData)) + return new EffectData(3, 0); + + if (((EffectData) storedData).getIntSize() < 3) + return new EffectData(3, 0); + + return storedData; + } + + @Override + public IEffectData doEffect(IBeeGenome genome, IEffectData storedData, IBeeHousing housing) { + + World world = housing.getWorld(); + + if (isHalted(storedData, housing)) + return storedData; + + // If we are already triggered, we continue the explosion sequence. + if (storedData.getInteger(indexExplosionTimer) > 0) { + progressExplosion(storedData, world, housing.getXCoord(), housing.getYCoord(), housing.getZCoord()); + return storedData; + } + + AxisAlignedBB infectionBox = getBounding(genome, housing, 1.0f); + + @SuppressWarnings("rawtypes") + List list = world.getEntitiesWithinAABB(EntityPlayer.class, infectionBox); + + for (Object obj : list) { + + EntityPlayer player = (EntityPlayer) obj; + + int chance = explosionChance; + storedData.setInteger(indexExplosionForce, defaultForce); + + // Players are not attacked if they wear a full set of apiarist's + // armor. + int count = ItemArmorApiarist.wearsItems(player, getUID(), true); + // Full set, no damage/effect + if (count > 3) + continue; + else if (count > 2) { + chance = 5; + storedData.setInteger(indexExplosionForce, 6); + } else if (count > 1) { + chance = 20; + storedData.setInteger(indexExplosionForce, 8); + } else if (count > 0) { + chance = 35; + storedData.setInteger(indexExplosionForce, 10); + } + + if (world.rand.nextInt(1000) >= chance) + continue; + + world.playSoundEffect(housing.getXCoord(), housing.getYCoord(), housing.getZCoord(), "mob.creeper", 4F, + (1.0F + (world.rand.nextFloat() - world.rand.nextFloat()) * 0.2F) * 0.7F); + storedData.setInteger(indexExplosionTimer, 2); // Set explosion + // timer + } + + return storedData; + } + + private void progressExplosion(IEffectData storedData, World world, int x, int y, int z) { + + int explosionTimer = storedData.getInteger(indexExplosionTimer); + explosionTimer--; + storedData.setInteger(indexExplosionTimer, explosionTimer); + + if (explosionTimer > 0) + return; + + world.createExplosion(null, x, y, z, storedData.getInteger(indexExplosionForce), false); + } + +} diff --git a/forestry_common/apiculture/forestry/apiculture/genetics/AlleleEffectExploration.java b/forestry_common/apiculture/forestry/apiculture/genetics/AlleleEffectExploration.java new file mode 100755 index 000000000..d629c26a0 --- /dev/null +++ b/forestry_common/apiculture/forestry/apiculture/genetics/AlleleEffectExploration.java @@ -0,0 +1,43 @@ +/******************************************************************************* + * Copyright 2011-2014 by SirSengir + * + * This work is licensed under a Creative Commons Attribution-NonCommercial-NoDerivs 3.0 Unported License. + * + * To view a copy of this license, visit http://creativecommons.org/licenses/by-nc-nd/3.0/. + ******************************************************************************/ +package forestry.apiculture.genetics; + +import java.util.List; + +import net.minecraft.entity.player.EntityPlayer; +import net.minecraft.util.AxisAlignedBB; + +import forestry.api.apiculture.IBeeGenome; +import forestry.api.apiculture.IBeeHousing; +import forestry.api.genetics.IEffectData; + +public class AlleleEffectExploration extends AlleleEffectThrottled { + + public AlleleEffectExploration(String uid) { + super(uid, "exploration", false, 80, true, false); + } + + @Override + public IEffectData doEffect(IBeeGenome genome, IEffectData storedData, IBeeHousing housing) { + + if (isHalted(storedData, housing)) + return storedData; + + AxisAlignedBB beatifyBox = getBounding(genome, housing, 1.0f); + @SuppressWarnings("rawtypes") + List list = housing.getWorld().getEntitiesWithinAABB(EntityPlayer.class, beatifyBox); + + for (Object obj : list) { + EntityPlayer player = (EntityPlayer) obj; + player.addExperience(2); + } + + return storedData; + } + +} diff --git a/forestry_common/apiculture/forestry/apiculture/genetics/AlleleEffectGlacial.java b/forestry_common/apiculture/forestry/apiculture/genetics/AlleleEffectGlacial.java new file mode 100755 index 000000000..f4a35b8a2 --- /dev/null +++ b/forestry_common/apiculture/forestry/apiculture/genetics/AlleleEffectGlacial.java @@ -0,0 +1,70 @@ +/******************************************************************************* + * Copyright 2011-2014 by SirSengir + * + * This work is licensed under a Creative Commons Attribution-NonCommercial-NoDerivs 3.0 Unported License. + * + * To view a copy of this license, visit http://creativecommons.org/licenses/by-nc-nd/3.0/. + ******************************************************************************/ +package forestry.apiculture.genetics; + +import net.minecraft.block.Block; +import net.minecraft.init.Blocks; +import net.minecraft.world.World; +import net.minecraft.world.biome.BiomeGenBase; + +import forestry.api.apiculture.IBeeGenome; +import forestry.api.apiculture.IBeeHousing; +import forestry.api.core.EnumTemperature; +import forestry.api.genetics.IEffectData; +import forestry.core.proxy.Proxies; +import forestry.core.utils.Vect; + +public class AlleleEffectGlacial extends AlleleEffectThrottled { + + public AlleleEffectGlacial(String uid) { + super(uid, "glacial", false, 200, true, false); + } + + @Override + public IEffectData doEffect(IBeeGenome genome, IEffectData storedData, IBeeHousing housing) { + + World world = housing.getWorld(); + + if (isHalted(storedData, housing)) + return storedData; + + EnumTemperature temp = EnumTemperature.getFromValue(BiomeGenBase.getBiome(housing.getBiomeId()).temperature); + + switch (temp) { + case HELLISH: + case HOT: + case WARM: + return storedData; + default: + } + + int[] areaAr = genome.getTerritory(); + Vect area = new Vect(areaAr[0], areaAr[1], areaAr[2]); + Vect offset = new Vect(-Math.round(area.x / 2), -Math.round(area.y / 2), -Math.round(area.z / 2)); + + for (int i = 0; i < 10; i++) { + + Vect randomPos = new Vect(world.rand.nextInt(area.x), world.rand.nextInt(area.y), world.rand.nextInt(area.z)); + + Vect posBlock = randomPos.add(new Vect(housing.getXCoord(), housing.getYCoord(), housing.getZCoord())); + posBlock = posBlock.add(offset); + + // Freeze water + Block block = world.getBlock(posBlock.x, posBlock.y, posBlock.z); + if (block != Blocks.water) + continue; + + if (!world.isAirBlock(posBlock.x, posBlock.y + 1, posBlock.z)) + continue; + + Proxies.common.setBlockWithNotify(world, posBlock.x, posBlock.y, posBlock.z, Blocks.ice); + } + + return storedData; + } +} diff --git a/forestry_common/apiculture/forestry/apiculture/genetics/AlleleEffectHeroic.java b/forestry_common/apiculture/forestry/apiculture/genetics/AlleleEffectHeroic.java new file mode 100755 index 000000000..834865759 --- /dev/null +++ b/forestry_common/apiculture/forestry/apiculture/genetics/AlleleEffectHeroic.java @@ -0,0 +1,44 @@ +/******************************************************************************* + * Copyright 2011-2014 by SirSengir + * + * This work is licensed under a Creative Commons Attribution-NonCommercial-NoDerivs 3.0 Unported License. + * + * To view a copy of this license, visit http://creativecommons.org/licenses/by-nc-nd/3.0/. + ******************************************************************************/ +package forestry.apiculture.genetics; + +import java.util.List; + +import net.minecraft.entity.monster.EntityMob; +import net.minecraft.util.AxisAlignedBB; +import net.minecraft.util.DamageSource; + +import forestry.api.apiculture.IBeeGenome; +import forestry.api.apiculture.IBeeHousing; +import forestry.api.genetics.IEffectData; + +public class AlleleEffectHeroic extends AlleleEffectThrottled { + + public AlleleEffectHeroic(String uid) { + super(uid, "heroic", false, 40, true, false); + } + + @Override + public IEffectData doEffect(IBeeGenome genome, IEffectData storedData, IBeeHousing housing) { + + if (isHalted(storedData, housing)) + return storedData; + + AxisAlignedBB hurtBox = getBounding(genome, housing, 1.0f); + @SuppressWarnings("rawtypes") + List list = housing.getWorld().getEntitiesWithinAABB(EntityMob.class, hurtBox); + + for (Object obj : list) { + EntityMob mob = (EntityMob) obj; + mob.attackEntityFrom(DamageSource.generic, 2); + } + + return storedData; + } + +} diff --git a/forestry_common/apiculture/forestry/apiculture/genetics/AlleleEffectIgnition.java b/forestry_common/apiculture/forestry/apiculture/genetics/AlleleEffectIgnition.java new file mode 100755 index 000000000..6f6b9d26b --- /dev/null +++ b/forestry_common/apiculture/forestry/apiculture/genetics/AlleleEffectIgnition.java @@ -0,0 +1,92 @@ +/******************************************************************************* + * Copyright 2011-2014 by SirSengir + * + * This work is licensed under a Creative Commons Attribution-NonCommercial-NoDerivs 3.0 Unported License. + * + * To view a copy of this license, visit http://creativecommons.org/licenses/by-nc-nd/3.0/. + ******************************************************************************/ +package forestry.apiculture.genetics; + +import java.util.List; + +import net.minecraft.entity.EntityLivingBase; +import net.minecraft.entity.player.EntityPlayer; +import net.minecraft.util.AxisAlignedBB; +import net.minecraft.world.World; + +import forestry.api.apiculture.IBeeGenome; +import forestry.api.apiculture.IBeeHousing; +import forestry.api.genetics.IEffectData; +import forestry.apiculture.items.ItemArmorApiarist; +import forestry.plugins.PluginApiculture; + +public class AlleleEffectIgnition extends AlleleEffectThrottled { + + int ignitionChance = 50; + int fireDuration = 500; + + public AlleleEffectIgnition(String uid) { + super(uid, "ignition", false, 20, false, true); + } + + @Override + public IEffectData doEffect(IBeeGenome genome, IEffectData storedData, IBeeHousing housing) { + + World world = housing.getWorld(); + + if (isHalted(storedData, housing)) + return storedData; + + AxisAlignedBB hurtBox = getBounding(genome, housing, 1.0f); + @SuppressWarnings("rawtypes") + List list = world.getEntitiesWithinAABB(EntityLivingBase.class, hurtBox); + + for (Object obj : list) { + EntityLivingBase entity = (EntityLivingBase) obj; + + int chance = ignitionChance; + int duration = fireDuration; + + // Players are not attacked if they wear a full set of apiarist's + // armor. + if (entity instanceof EntityPlayer) { + int count = ItemArmorApiarist.wearsItems((EntityPlayer) entity, getUID(), true); + // Full set, no damage/effect + if (count > 3) + continue; + else if (count > 2) { + chance = 5; + duration = 50; + } else if (count > 1) { + chance = 20; + duration = 200; + } else if (count > 0) { + chance = 35; + duration = 350; + } + } + + if (world.rand.nextInt(1000) >= chance) + continue; + + entity.setFire(duration); + } + + return storedData; + } + + @Override + public IEffectData doFX(IBeeGenome genome, IEffectData storedData, IBeeHousing housing) { + + int[] area = getModifiedArea(genome, housing); + + if (housing.getWorld().rand.nextBoolean()) + PluginApiculture.proxy.addBeeHiveFX("particles/swarm_bee", housing.getWorld(), housing.getXCoord(), housing.getYCoord(), + housing.getZCoord(), genome.getPrimary().getIconColour(0), area[0], area[1], area[2]); + else + PluginApiculture.proxy.addBeeHiveFX("particles/ember", housing.getWorld(), housing.getXCoord(), housing.getYCoord(), + housing.getZCoord(), 0xffffff, area[0], area[1], area[2]); + return storedData; + } + +} diff --git a/forestry_common/apiculture/forestry/apiculture/genetics/AlleleEffectMiasmic.java b/forestry_common/apiculture/forestry/apiculture/genetics/AlleleEffectMiasmic.java new file mode 100755 index 000000000..6cb7837aa --- /dev/null +++ b/forestry_common/apiculture/forestry/apiculture/genetics/AlleleEffectMiasmic.java @@ -0,0 +1,86 @@ +/******************************************************************************* + * Copyright 2011-2014 by SirSengir + * + * This work is licensed under a Creative Commons Attribution-NonCommercial-NoDerivs 3.0 Unported License. + * + * To view a copy of this license, visit http://creativecommons.org/licenses/by-nc-nd/3.0/. + ******************************************************************************/ +package forestry.apiculture.genetics; + +import java.util.List; + +import net.minecraft.entity.player.EntityPlayer; +import net.minecraft.potion.Potion; +import net.minecraft.potion.PotionEffect; +import net.minecraft.util.AxisAlignedBB; +import net.minecraft.world.World; + +import forestry.api.apiculture.IBeeGenome; +import forestry.api.apiculture.IBeeHousing; +import forestry.api.genetics.IEffectData; +import forestry.apiculture.items.ItemArmorApiarist; +import forestry.plugins.PluginApiculture; + +public class AlleleEffectMiasmic extends AlleleEffectThrottled { + + private final int infectionChance = 50; + + public AlleleEffectMiasmic(String uid) { + super(uid, "misasmic", false, 50, false, false); + } + + @Override + public IEffectData doEffect(IBeeGenome genome, IEffectData storedData, IBeeHousing housing) { + + World world = housing.getWorld(); + + if (isHalted(storedData, housing)) + return storedData; + + AxisAlignedBB infectionBox = getBounding(genome, housing, 1.0f); + @SuppressWarnings("rawtypes") + List list = world.getEntitiesWithinAABB(EntityPlayer.class, infectionBox); + + for (Object obj : list) { + + if (world.rand.nextInt(1000) >= infectionChance) + continue; + + EntityPlayer player = (EntityPlayer) obj; + + int duration = 800; + + // Players are not attacked if they wear a full set of apiarist's + // armor. + int count = ItemArmorApiarist.wearsItems(player, getUID(), true); + // Full set, no damage/effect + if (count > 3) + continue; + else if (count > 2) + duration = 200; + else if (count > 1) + duration = 400; + else if (count > 0) + duration = 600; + + player.addPotionEffect(new PotionEffect(Potion.poison.id, duration, 0)); + } + + return storedData; + } + + @Override + public IEffectData doFX(IBeeGenome genome, IEffectData storedData, IBeeHousing housing) { + + int[] area = getModifiedArea(genome, housing); + + if (housing.getWorld().rand.nextBoolean()) + PluginApiculture.proxy.addBeeHiveFX("particles/swarm_bee", housing.getWorld(), housing.getXCoord(), housing.getYCoord(), + housing.getZCoord(), genome.getPrimary().getIconColour(0), area[0], area[1], area[2]); + else + PluginApiculture.proxy.addBeeHiveFX("particles/poison", housing.getWorld(), housing.getXCoord(), housing.getYCoord(), + housing.getZCoord(), 0xffffff, area[0], area[1], area[2]); + return storedData; + } + +} diff --git a/forestry_common/apiculture/forestry/apiculture/genetics/AlleleEffectMisanthrope.java b/forestry_common/apiculture/forestry/apiculture/genetics/AlleleEffectMisanthrope.java new file mode 100755 index 000000000..f557de48d --- /dev/null +++ b/forestry_common/apiculture/forestry/apiculture/genetics/AlleleEffectMisanthrope.java @@ -0,0 +1,64 @@ +/******************************************************************************* + * Copyright 2011-2014 by SirSengir + * + * This work is licensed under a Creative Commons Attribution-NonCommercial-NoDerivs 3.0 Unported License. + * + * To view a copy of this license, visit http://creativecommons.org/licenses/by-nc-nd/3.0/. + ******************************************************************************/ +package forestry.apiculture.genetics; + +import java.util.List; + +import net.minecraft.entity.player.EntityPlayer; +import net.minecraft.util.AxisAlignedBB; +import net.minecraft.util.DamageSource; + +import forestry.api.apiculture.IBeeGenome; +import forestry.api.apiculture.IBeeHousing; +import forestry.api.genetics.IEffectData; +import forestry.apiculture.items.ItemArmorApiarist; +import forestry.core.utils.DamageSourceForestry; + +public class AlleleEffectMisanthrope extends AlleleEffectThrottled { + + public static DamageSource damageSourceBeeEnd = new DamageSourceForestry("bee.end"); + + public AlleleEffectMisanthrope(String uid) { + super(uid, "misanthrope", true, 20, false, false); + } + + @Override + public IEffectData doEffect(IBeeGenome genome, IEffectData storedData, IBeeHousing housing) { + + if (isHalted(storedData, housing)) + return storedData; + + AxisAlignedBB beatifyBox = getBounding(genome, housing, 1.0f); + @SuppressWarnings("rawtypes") + List list = housing.getWorld().getEntitiesWithinAABB(EntityPlayer.class, beatifyBox); + + for (Object obj : list) { + EntityPlayer player = (EntityPlayer) obj; + + int damage = 4; + + // Players are not attacked if they wear a full set of apiarist's + // armor. + int count = ItemArmorApiarist.wearsItems(player, getUID(), true); + // Full set, no damage/effect + if (count > 3) + continue; + else if (count > 2) + damage = 1; + else if (count > 1) + damage = 2; + else if (count > 0) + damage = 3; + + player.attackEntityFrom(damageSourceBeeEnd, damage); + } + + return storedData; + } + +} diff --git a/forestry_common/apiculture/forestry/apiculture/genetics/AlleleEffectNone.java b/forestry_common/apiculture/forestry/apiculture/genetics/AlleleEffectNone.java new file mode 100755 index 000000000..cd8aabbc4 --- /dev/null +++ b/forestry_common/apiculture/forestry/apiculture/genetics/AlleleEffectNone.java @@ -0,0 +1,69 @@ +/******************************************************************************* + * Copyright 2011-2014 by SirSengir + * + * This work is licensed under a Creative Commons Attribution-NonCommercial-NoDerivs 3.0 Unported License. + * + * To view a copy of this license, visit http://creativecommons.org/licenses/by-nc-nd/3.0/. + ******************************************************************************/ +package forestry.apiculture.genetics; + +import net.minecraft.world.World; + +import forestry.api.apiculture.IAlleleBeeEffect; +import forestry.api.apiculture.IBeeGenome; +import forestry.api.apiculture.IBeeHousing; +import forestry.api.genetics.IEffectData; +import forestry.core.genetics.Allele; +import forestry.plugins.PluginApiculture; + +public class AlleleEffectNone extends Allele implements IAlleleBeeEffect { + + public AlleleEffectNone(String uid) { + super(uid, true); + } + + @Override + public IEffectData validateStorage(IEffectData storedData) { + return null; + } + + @Override + public boolean isCombinable() { + return false; + } + + @Override + public IEffectData doEffect(IBeeGenome genome, IEffectData storedData, IBeeHousing housing) { + return doEffect(genome, storedData, housing.getWorld(), housing.getBiomeId(), housing.getXCoord(), housing.getYCoord(), housing.getZCoord()); + } + + protected IEffectData doEffect(IBeeGenome genome, IEffectData storedData, World world, int biomeid, int x, int y, int z) { + return storedData; + } + + @Override + public String getName() { + return "None"; + } + + @Override + public IEffectData doFX(IBeeGenome genome, IEffectData storedData, IBeeHousing housing) { + + int[] area = genome.getTerritory(); + area[0] *= housing.getTerritoryModifier(genome, 1f); + area[1] *= housing.getTerritoryModifier(genome, 1f); + area[2] *= housing.getTerritoryModifier(genome, 1f); + + if (area[0] < 1) + area[0] = 1; + if (area[1] < 1) + area[1] = 1; + if (area[2] < 1) + area[2] = 1; + + PluginApiculture.proxy.addBeeHiveFX("particles/swarm_bee", housing.getWorld(), housing.getXCoord(), housing.getYCoord(), + housing.getZCoord(), genome.getPrimary().getIconColour(0), area[0], area[1], area[2]); + return storedData; + } + +} diff --git a/forestry_common/apiculture/forestry/apiculture/genetics/AlleleEffectPotion.java b/forestry_common/apiculture/forestry/apiculture/genetics/AlleleEffectPotion.java new file mode 100755 index 000000000..9a53f84f8 --- /dev/null +++ b/forestry_common/apiculture/forestry/apiculture/genetics/AlleleEffectPotion.java @@ -0,0 +1,50 @@ +/******************************************************************************* + * Copyright 2011-2014 by SirSengir + * + * This work is licensed under a Creative Commons Attribution-NonCommercial-NoDerivs 3.0 Unported License. + * + * To view a copy of this license, visit http://creativecommons.org/licenses/by-nc-nd/3.0/. + ******************************************************************************/ +package forestry.apiculture.genetics; + +import java.util.List; + +import net.minecraft.entity.player.EntityPlayer; +import net.minecraft.potion.Potion; +import net.minecraft.potion.PotionEffect; +import net.minecraft.util.AxisAlignedBB; + +import forestry.api.apiculture.IBeeGenome; +import forestry.api.apiculture.IBeeHousing; +import forestry.api.genetics.IEffectData; + +public class AlleleEffectPotion extends AlleleEffectThrottled { + + private int potionId = 0; + private final int duration; + + public AlleleEffectPotion(String uid, String name, boolean isDominant, Potion potion, int duration, boolean requiresWorking) { + super(uid, name, isDominant, 200, requiresWorking, false); + potionId = potion.getId(); + this.duration = duration; + } + + @Override + public IEffectData doEffect(IBeeGenome genome, IEffectData storedData, IBeeHousing housing) { + + if (isHalted(storedData, housing)) + return storedData; + + AxisAlignedBB beatifyBox = getBounding(genome, housing, 1.0f); + @SuppressWarnings("rawtypes") + List list = housing.getWorld().getEntitiesWithinAABB(EntityPlayer.class, beatifyBox); + + for (Object obj : list) { + EntityPlayer player = (EntityPlayer) obj; + player.addPotionEffect(new PotionEffect(potionId, duration, 0)); + } + + return storedData; + } + +} diff --git a/forestry_common/apiculture/forestry/apiculture/genetics/AlleleEffectRadioactive.java b/forestry_common/apiculture/forestry/apiculture/genetics/AlleleEffectRadioactive.java new file mode 100755 index 000000000..2e658d0fe --- /dev/null +++ b/forestry_common/apiculture/forestry/apiculture/genetics/AlleleEffectRadioactive.java @@ -0,0 +1,122 @@ +/******************************************************************************* + * Copyright 2011-2014 by SirSengir + * + * This work is licensed under a Creative Commons Attribution-NonCommercial-NoDerivs 3.0 Unported License. + * + * To view a copy of this license, visit http://creativecommons.org/licenses/by-nc-nd/3.0/. + ******************************************************************************/ +package forestry.apiculture.genetics; + +import java.util.List; +import java.util.Random; + +import net.minecraft.block.Block; +import net.minecraft.entity.EntityLivingBase; +import net.minecraft.entity.player.EntityPlayer; +import net.minecraft.tileentity.TileEntity; +import net.minecraft.util.AxisAlignedBB; +import net.minecraft.util.DamageSource; +import net.minecraft.world.World; + +import forestry.api.apiculture.IBeeGenome; +import forestry.api.apiculture.IBeeHousing; +import forestry.api.genetics.IEffectData; +import forestry.apiculture.gadgets.BlockAlveary; +import forestry.apiculture.gadgets.TileAlveary; +import forestry.apiculture.items.ItemArmorApiarist; +import forestry.core.utils.DamageSourceForestry; +import forestry.core.utils.Vect; + +public class AlleleEffectRadioactive extends AlleleEffectThrottled { + + public static DamageSource damageSourceBeeRadioactive = new DamageSourceForestry("bee.radioactive"); + + public AlleleEffectRadioactive(String uid) { + super(uid, "radioactive", true, 40, false, true); + } + + @Override + public IEffectData doEffect(IBeeGenome genome, IEffectData storedData, IBeeHousing housing) { + + World world = housing.getWorld(); + + if (isHalted(storedData, housing)) + return storedData; + + int[] areaAr = genome.getTerritory(); + Vect area = new Vect(areaAr[0] * 2, areaAr[1] * 2, areaAr[2] * 2); + Vect offset = new Vect(-Math.round(area.x / 2), -Math.round(area.y / 2), -Math.round(area.z / 2)); + + // Radioactivity hurts players and mobs + Vect min = new Vect(housing.getXCoord() + offset.x, housing.getYCoord() + offset.y, housing.getZCoord() + offset.z); + Vect max = new Vect(housing.getXCoord() + offset.x + area.x, housing.getYCoord() + offset.y + area.y, housing.getZCoord() + offset.z + area.z); + + AxisAlignedBB hurtBox = AxisAlignedBB.getAABBPool().getAABB(min.x, min.y, min.z, max.x, max.y, max.z); + + @SuppressWarnings("rawtypes") + List list = housing.getWorld().getEntitiesWithinAABB(EntityLivingBase.class, hurtBox); + + for (Object obj : list) { + EntityLivingBase entity = (EntityLivingBase) obj; + + int damage = 8; + + // Players are not attacked if they wear a full set of apiarist's + // armor. + if (entity instanceof EntityPlayer) { + int count = ItemArmorApiarist.wearsItems((EntityPlayer) entity, getUID(), true); + // Full set, no damage/effect + if (count > 3) + continue; + else if (count > 2) + damage = 1; + else if (count > 1) + damage = 2; + else if (count > 0) + damage = 3; + } + + entity.attackEntityFrom(damageSourceBeeRadioactive, damage); + + } + + Random rand = housing.getWorld().rand; + // Radioactivity destroys environment + for (int i = 0; i < 20; i++) { + + Vect randomPos = new Vect(rand.nextInt(area.x), rand.nextInt(area.y), rand.nextInt(area.z)); + + Vect posBlock = randomPos.add(new Vect(housing.getXCoord(), housing.getYCoord(), housing.getZCoord())); + posBlock = posBlock.add(offset); + + if(posBlock.y <= 1 || posBlock.y >= housing.getWorld().getActualHeight()) + continue; + + // Don't destroy ourself and blocks below us. + if (posBlock.x == housing.getXCoord() && posBlock.z == housing.getZCoord() && posBlock.y <= housing.getYCoord()) + continue; + + if (world.isAirBlock(posBlock.x, posBlock.y, posBlock.z)) + continue; + + Block block = world.getBlock(posBlock.x, posBlock.y, posBlock.z); + + if (block instanceof BlockAlveary) + continue; + + TileEntity tile = world.getTileEntity(posBlock.x, posBlock.y, posBlock.z); + if (tile instanceof IBeeHousing) + continue; + if (tile instanceof TileAlveary) + continue; + + if (block.getBlockHardness(world, posBlock.x, posBlock.y, posBlock.z) < 0) + continue; + + world.setBlockToAir(posBlock.x, posBlock.y, posBlock.z); + break; + } + + return storedData; + } +} diff --git a/forestry_common/apiculture/forestry/apiculture/genetics/AlleleEffectRepulsion.java b/forestry_common/apiculture/forestry/apiculture/genetics/AlleleEffectRepulsion.java new file mode 100755 index 000000000..0a7034503 --- /dev/null +++ b/forestry_common/apiculture/forestry/apiculture/genetics/AlleleEffectRepulsion.java @@ -0,0 +1,55 @@ +/******************************************************************************* + * Copyright 2011-2014 by SirSengir + * + * This work is licensed under a Creative Commons Attribution-NonCommercial-NoDerivs 3.0 Unported License. + * + * To view a copy of this license, visit http://creativecommons.org/licenses/by-nc-nd/3.0/. + ******************************************************************************/ +package forestry.apiculture.genetics; + +import java.util.List; + +import net.minecraft.entity.ai.EntityAITasks.EntityAITaskEntry; +import net.minecraft.entity.monster.EntityMob; +import net.minecraft.util.AxisAlignedBB; + +import forestry.api.apiculture.IBeeGenome; +import forestry.api.apiculture.IBeeHousing; +import forestry.api.genetics.IEffectData; + +public class AlleleEffectRepulsion extends AlleleEffectThrottled { + + public AlleleEffectRepulsion(String uid) { + super(uid, "repulsion", false, 100, true, true); + } + + @Override + public IEffectData doEffect(IBeeGenome genome, IEffectData storedData, IBeeHousing housing) { + if (isHalted(storedData, housing)) + return storedData; + + if (housing.getOwnerName() == null || housing.getOwnerName().isEmpty()) + return storedData; + + AxisAlignedBB hurtBox = getBounding(genome, housing, 1.0f); + @SuppressWarnings("rawtypes") + List list = housing.getWorld().getEntitiesWithinAABB(EntityMob.class, hurtBox); + + for (Object obj : list) { + EntityMob mob = (EntityMob) obj; + + for (Object objT : mob.tasks.taskEntries) { + EntityAITaskEntry task = (EntityAITaskEntry) objT; + if (task.action instanceof AIAvoidPlayers) + return storedData; + } + + mob.tasks.addTask(3, new AIAvoidPlayers(mob, 6.0f, 0.25f, 0.3f)); + mob.tasks.onUpdateTasks(); + + } + + return storedData; + } + +} diff --git a/forestry_common/apiculture/forestry/apiculture/genetics/AlleleEffectResurrection.java b/forestry_common/apiculture/forestry/apiculture/genetics/AlleleEffectResurrection.java new file mode 100755 index 000000000..d7fabfcc2 --- /dev/null +++ b/forestry_common/apiculture/forestry/apiculture/genetics/AlleleEffectResurrection.java @@ -0,0 +1,108 @@ +/******************************************************************************* + * Copyright 2011-2014 by SirSengir + * + * This work is licensed under a Creative Commons Attribution-NonCommercial-NoDerivs 3.0 Unported License. + * + * To view a copy of this license, visit http://creativecommons.org/licenses/by-nc-nd/3.0/. + ******************************************************************************/ +package forestry.apiculture.genetics; + +import java.util.ArrayList; +import java.util.Collections; +import java.util.List; + +import net.minecraft.entity.EntityLiving; +import net.minecraft.entity.boss.EntityDragon; +import net.minecraft.entity.item.EntityItem; +import net.minecraft.entity.monster.EntityBlaze; +import net.minecraft.entity.monster.EntityCaveSpider; +import net.minecraft.entity.monster.EntityCreeper; +import net.minecraft.entity.monster.EntityEnderman; +import net.minecraft.entity.monster.EntityGhast; +import net.minecraft.entity.monster.EntitySkeleton; +import net.minecraft.entity.monster.EntitySpider; +import net.minecraft.entity.monster.EntityZombie; +import net.minecraft.init.Blocks; +import net.minecraft.init.Items; +import net.minecraft.item.ItemStack; +import net.minecraft.util.AxisAlignedBB; + +import forestry.api.apiculture.IBeeGenome; +import forestry.api.apiculture.IBeeHousing; +import forestry.api.genetics.IEffectData; +import forestry.core.utils.StackUtils; +import forestry.core.utils.Utils; + +public class AlleleEffectResurrection extends AlleleEffectThrottled { + + public static class Resurrectable { + public final ItemStack res; + public final Class risen; + + public Resurrectable(ItemStack res, Class risen) { + this.res = res; + this.risen = risen; + } + } + + public static List getReanimationList() { + ArrayList list = new ArrayList(); + list.add(new Resurrectable(new ItemStack(Items.bone), EntitySkeleton.class)); + list.add(new Resurrectable(new ItemStack(Items.arrow), EntitySkeleton.class)); + list.add(new Resurrectable(new ItemStack(Items.rotten_flesh), EntityZombie.class)); + list.add(new Resurrectable(new ItemStack(Items.blaze_rod), EntityBlaze.class)); + return list; + } + + public static List getResurrectionList() { + ArrayList list = new ArrayList(); + list.add(new Resurrectable(new ItemStack(Items.gunpowder), EntityCreeper.class)); + list.add(new Resurrectable(new ItemStack(Items.ender_pearl), EntityEnderman.class)); + list.add(new Resurrectable(new ItemStack(Items.string), EntitySpider.class)); + list.add(new Resurrectable(new ItemStack(Items.spider_eye), EntitySpider.class)); + list.add(new Resurrectable(new ItemStack(Items.string), EntityCaveSpider.class)); + list.add(new Resurrectable(new ItemStack(Items.spider_eye), EntityCaveSpider.class)); + list.add(new Resurrectable(new ItemStack(Items.ghast_tear), EntityGhast.class)); + list.add(new Resurrectable(new ItemStack(Blocks.dragon_egg), EntityDragon.class)); + return list; + } + + private final List resurrectables; + + public AlleleEffectResurrection(String uid, String name, List resurrectables) { + super(uid, name, true, 40, true, true); + this.resurrectables = resurrectables; + } + + @Override + public IEffectData doEffect(IBeeGenome genome, IEffectData storedData, IBeeHousing housing) { + if (isHalted(storedData, housing)) + return storedData; + + AxisAlignedBB bounding = getBounding(genome, housing, 1.0f); + @SuppressWarnings("rawtypes") + List list = housing.getWorld().getEntitiesWithinAABB(EntityItem.class, bounding); + + if (list.size() > 0) + Collections.shuffle(resurrectables); + + for (Object obj : list) { + EntityItem item = (EntityItem) obj; + if (item.isDead) + continue; + + ItemStack contained = item.getEntityItem(); + for (Resurrectable entry : resurrectables) + if (StackUtils.isIdenticalItem(entry.res, contained)) { + Utils.spawnEntity(housing.getWorld(), entry.risen, item.posX, item.posY, item.posZ); + contained.stackSize--; + if (contained.stackSize <= 0) + item.setDead(); + break; + } + } + + return storedData; + } + +} diff --git a/forestry_common/apiculture/forestry/apiculture/genetics/AlleleEffectSnowing.java b/forestry_common/apiculture/forestry/apiculture/genetics/AlleleEffectSnowing.java new file mode 100755 index 000000000..3364f631e --- /dev/null +++ b/forestry_common/apiculture/forestry/apiculture/genetics/AlleleEffectSnowing.java @@ -0,0 +1,79 @@ +/******************************************************************************* + * Copyright 2011-2014 by SirSengir + * + * This work is licensed under a Creative Commons Attribution-NonCommercial-NoDerivs 3.0 Unported License. + * + * To view a copy of this license, visit http://creativecommons.org/licenses/by-nc-nd/3.0/. + ******************************************************************************/ +package forestry.apiculture.genetics; + +import net.minecraft.init.Blocks; +import net.minecraft.world.World; +import net.minecraft.world.biome.BiomeGenBase; + +import net.minecraftforge.common.util.ForgeDirection; + +import forestry.api.apiculture.IBeeGenome; +import forestry.api.apiculture.IBeeHousing; +import forestry.api.core.EnumTemperature; +import forestry.api.genetics.IEffectData; +import forestry.core.proxy.Proxies; +import forestry.core.utils.Vect; + +public class AlleleEffectSnowing extends AlleleEffectThrottled { + + public AlleleEffectSnowing(String uid) { + super(uid, "snowing", false, 20, true, true); + } + + @Override + public IEffectData doEffect(IBeeGenome genome, IEffectData storedData, IBeeHousing housing) { + + World world = housing.getWorld(); + + if (isHalted(storedData, housing)) + return storedData; + + EnumTemperature temp = EnumTemperature.getFromValue(BiomeGenBase.getBiome(housing.getBiomeId()).temperature); + + switch (temp) { + case HELLISH: + case HOT: + case WARM: + return storedData; + default: + } + + int[] areaAr = genome.getTerritory(); + Vect area = new Vect(areaAr[0], areaAr[1], areaAr[2]); + Vect offset = new Vect(-Math.round(area.x / 2), -Math.round(area.y / 2), -Math.round(area.z / 2)); + + for (int i = 0; i < 1; i++) { + + Vect randomPos = new Vect(world.rand.nextInt(area.x), world.rand.nextInt(area.y), world.rand.nextInt(area.z)); + + Vect posBlock = randomPos.add(new Vect(housing.getXCoord(), housing.getYCoord(), housing.getZCoord())); + posBlock = posBlock.add(offset); + + // Put snow on the ground + if (!world.isSideSolid(posBlock.x, posBlock.y - 1, posBlock.z, ForgeDirection.UP, false)) + continue; + + if (!world.isAirBlock(posBlock.x, posBlock.y, posBlock.z)) + continue; + + Proxies.common.setBlockWithNotify(world, posBlock.x, posBlock.y, posBlock.z, Blocks.snow_layer); + } + + return storedData; + } + + @Override + public IEffectData doFX(IBeeGenome genome, IEffectData storedData, IBeeHousing housing) { + if (housing.getWorld().rand.nextInt(3) == 0) { + int[] area = getModifiedArea(genome, housing); + Proxies.render.addSnowFX(housing.getWorld(), housing.getXCoord(), housing.getYCoord(), housing.getZCoord(), genome.getPrimary().getIconColour(0), area[0], area[1], area[2]); + } + return storedData; + } +} diff --git a/forestry_common/apiculture/forestry/apiculture/genetics/AlleleEffectThrottled.java b/forestry_common/apiculture/forestry/apiculture/genetics/AlleleEffectThrottled.java new file mode 100755 index 000000000..f64bb8b0c --- /dev/null +++ b/forestry_common/apiculture/forestry/apiculture/genetics/AlleleEffectThrottled.java @@ -0,0 +1,114 @@ +/******************************************************************************* + * Copyright 2011-2014 by SirSengir + * + * This work is licensed under a Creative Commons Attribution-NonCommercial-NoDerivs 3.0 Unported License. + * + * To view a copy of this license, visit http://creativecommons.org/licenses/by-nc-nd/3.0/. + ******************************************************************************/ +package forestry.apiculture.genetics; + +import net.minecraft.util.AxisAlignedBB; + +import forestry.api.apiculture.IAlleleBeeEffect; +import forestry.api.apiculture.IBeeGenome; +import forestry.api.apiculture.IBeeHousing; +import forestry.api.genetics.IEffectData; +import forestry.core.EnumErrorCode; +import forestry.core.genetics.Allele; +import forestry.core.genetics.EffectData; +import forestry.core.utils.StringUtil; +import forestry.core.utils.Vect; +import forestry.plugins.PluginApiculture; + +public abstract class AlleleEffectThrottled extends Allele implements IAlleleBeeEffect { + + private String name; + private boolean isCombinable = false; + private int throttle; + private boolean requiresWorkingQueen = false; + + public AlleleEffectThrottled(String uid, String name, boolean isDominant, int throttle, boolean requiresWorking, boolean isCombinable) { + super(uid, isDominant); + this.name = "apiculture.effect." + name; + this.throttle = throttle; + this.isCombinable = isCombinable; + this.requiresWorkingQueen = requiresWorking; + } + + @Override + public String getName() { + return StringUtil.localize(name); + } + + public int getThrottle() { + return throttle; + } + + @Override + public boolean isCombinable() { + return isCombinable; + } + + @Override + public IEffectData validateStorage(IEffectData storedData) { + if (storedData instanceof EffectData) + return storedData; + + return new EffectData(1, 0); + } + + public boolean isHalted(IEffectData storedData, IBeeHousing housing) { + + if (requiresWorkingQueen && housing.getErrorOrdinal() != EnumErrorCode.OK.ordinal()) + return true; + + int throttle = storedData.getInteger(0); + throttle++; + storedData.setInteger(0, throttle); + + if (throttle < getThrottle()) + return true; + + // Reset since we are done throttling. + storedData.setInteger(0, 0); + return false; + } + + @Override + public IEffectData doFX(IBeeGenome genome, IEffectData storedData, IBeeHousing housing) { + + int[] area = getModifiedArea(genome, housing); + + PluginApiculture.proxy.addBeeHiveFX("particles/swarm_bee", housing.getWorld(), housing.getXCoord(), housing.getYCoord(), + housing.getZCoord(), genome.getPrimary().getIconColour(0), area[0], area[1], area[2]); + return storedData; + } + + protected int[] getModifiedArea(IBeeGenome genome, IBeeHousing housing) { + int[] area = genome.getTerritory(); + area[0] *= housing.getTerritoryModifier(genome, 1f) * 3; + area[1] *= housing.getTerritoryModifier(genome, 1f) * 3; + area[2] *= housing.getTerritoryModifier(genome, 1f) * 3; + + if (area[0] < 1) + area[0] = 1; + if (area[1] < 1) + area[1] = 1; + if (area[2] < 1) + area[2] = 1; + + return area; + } + + protected AxisAlignedBB getBounding(IBeeGenome genome, IBeeHousing housing, float modifier) { + int[] areaAr = genome.getTerritory(); + Vect area = new Vect(areaAr[0], areaAr[1], areaAr[2]).multiply(modifier); + Vect offset = new Vect(-Math.round(area.x / 2), -Math.round(area.y / 2), -Math.round(area.z / 2)); + + // Radioactivity hurts players and mobs + Vect min = new Vect(housing.getXCoord() + offset.x, housing.getYCoord() + offset.y, housing.getZCoord() + offset.z); + Vect max = new Vect(housing.getXCoord() + offset.x + area.x, housing.getYCoord() + offset.y + area.y, housing.getZCoord() + offset.z + area.z); + + return AxisAlignedBB.getAABBPool().getAABB(min.x, min.y, min.z, max.x, max.y, max.z); + } +} diff --git a/forestry_common/apiculture/forestry/apiculture/genetics/AlleleFlowers.java b/forestry_common/apiculture/forestry/apiculture/genetics/AlleleFlowers.java new file mode 100755 index 000000000..0f9c85c44 --- /dev/null +++ b/forestry_common/apiculture/forestry/apiculture/genetics/AlleleFlowers.java @@ -0,0 +1,37 @@ +/******************************************************************************* + * Copyright 2011-2014 by SirSengir + * + * This work is licensed under a Creative Commons Attribution-NonCommercial-NoDerivs 3.0 Unported License. + * + * To view a copy of this license, visit http://creativecommons.org/licenses/by-nc-nd/3.0/. + ******************************************************************************/ +package forestry.apiculture.genetics; + +import forestry.api.genetics.IAlleleFlowers; +import forestry.api.genetics.IFlowerProvider; +import forestry.core.genetics.Allele; + +public class AlleleFlowers extends Allele implements IAlleleFlowers { + + IFlowerProvider provider; + + public AlleleFlowers(String uid, IFlowerProvider provider) { + this(uid, provider, false); + } + + public AlleleFlowers(String uid, IFlowerProvider provider, boolean isDominant) { + super(uid, isDominant); + this.provider = provider; + } + + @Override + public IFlowerProvider getProvider() { + return provider; + } + + @Override + public String getName() { + return getProvider().getDescription(); + } + +} diff --git a/forestry_common/apiculture/forestry/apiculture/genetics/ApiaristTracker.java b/forestry_common/apiculture/forestry/apiculture/genetics/ApiaristTracker.java new file mode 100755 index 000000000..d3e80d541 --- /dev/null +++ b/forestry_common/apiculture/forestry/apiculture/genetics/ApiaristTracker.java @@ -0,0 +1,110 @@ +/******************************************************************************* + * Copyright 2011-2014 by SirSengir + * + * This work is licensed under a Creative Commons Attribution-NonCommercial-NoDerivs 3.0 Unported License. + * + * To view a copy of this license, visit http://creativecommons.org/licenses/by-nc-nd/3.0/. + ******************************************************************************/ +package forestry.apiculture.genetics; + +import net.minecraft.entity.player.EntityPlayer; +import net.minecraft.nbt.NBTTagCompound; + +import forestry.api.apiculture.IApiaristTracker; +import forestry.api.genetics.IBreedingTracker; +import forestry.api.genetics.IIndividual; +import forestry.core.genetics.BreedingTracker; +import forestry.plugins.PluginApiculture; + +public class ApiaristTracker extends BreedingTracker implements IApiaristTracker { + + public ApiaristTracker(String s) { + this(s, ""); + } + + public ApiaristTracker(String s, String player) { + super(s, player); + } + + private int queensTotal = 0; + private int dronesTotal = 0; + private int princessesTotal = 0; + + @Override + public void readFromNBT(NBTTagCompound nbttagcompound) { + + queensTotal = nbttagcompound.getInteger("QueensTotal"); + princessesTotal = nbttagcompound.getInteger("PrincessesTotal"); + dronesTotal = nbttagcompound.getInteger("DronesTotal"); + + super.readFromNBT(nbttagcompound); + + } + + @Override + public void writeToNBT(NBTTagCompound nbttagcompound) { + + nbttagcompound.setInteger("QueensTotal", queensTotal); + nbttagcompound.setInteger("PrincessesTotal", princessesTotal); + nbttagcompound.setInteger("DronesTotal", dronesTotal); + + super.writeToNBT(nbttagcompound); + + } + + @Override + public void registerPickup(IIndividual individual) { + if(!individual.getGenome().getPrimary().getRoot().getUID().equals(BeeHelper.UID)) + return; + if(!individual.isPureBred(0)) + return; + if(PluginApiculture.beeInterface.getCombinations(individual.getGenome().getPrimary()).size() > 0) + return; + + registerSpecies(individual.getGenome().getPrimary()); + } + + @Override + public void registerQueen(IIndividual bee) { + queensTotal++; + } + + @Override + public int getQueenCount() { + return queensTotal; + } + + @Override + public void registerPrincess(IIndividual bee) { + + princessesTotal++; + registerBirth(bee); + } + + @Override + public int getPrincessCount() { + return princessesTotal; + } + + @Override + public void registerDrone(IIndividual bee) { + dronesTotal++; + registerBirth(bee); + } + + @Override + public int getDroneCount() { + return dronesTotal; + } + + @Override + protected IBreedingTracker getCommonTracker(EntityPlayer player) { + return PluginApiculture.beeInterface.getBreedingTracker(player.worldObj, "__COMMON_"); + } + + @Override + protected String getPacketTag() { + return BeeHelper.UID; + } + +} diff --git a/forestry_common/apiculture/forestry/apiculture/genetics/Bee.java b/forestry_common/apiculture/forestry/apiculture/genetics/Bee.java new file mode 100755 index 000000000..0e65f93f8 --- /dev/null +++ b/forestry_common/apiculture/forestry/apiculture/genetics/Bee.java @@ -0,0 +1,713 @@ +/******************************************************************************* + * Copyright 2011-2014 by SirSengir + * + * This work is licensed under a Creative Commons Attribution-NonCommercial-NoDerivs 3.0 Unported License. + * + * To view a copy of this license, visit http://creativecommons.org/licenses/by-nc-nd/3.0/. + ******************************************************************************/ +package forestry.apiculture.genetics; + +import java.util.ArrayList; +import java.util.List; +import java.util.Map; +import java.util.Set; + +import net.minecraft.item.ItemStack; +import net.minecraft.nbt.NBTTagCompound; +import net.minecraft.tileentity.TileEntity; +import net.minecraft.world.World; +import net.minecraft.world.biome.BiomeGenBase; + +import net.minecraftforge.common.BiomeDictionary; + +import forestry.api.apiculture.EnumBeeChromosome; +import forestry.api.apiculture.IAlleleBeeEffect; +import forestry.api.apiculture.IAlleleBeeSpecies; +import forestry.api.apiculture.IApiaristTracker; +import forestry.api.apiculture.IBee; +import forestry.api.apiculture.IBeeGenome; +import forestry.api.apiculture.IBeeHousing; +import forestry.api.apiculture.IBeeMutation; +import forestry.api.apiculture.IBeekeepingMode; +import forestry.api.core.EnumHumidity; +import forestry.api.core.EnumTemperature; +import forestry.api.genetics.AlleleManager; +import forestry.api.genetics.EnumTolerance; +import forestry.api.genetics.IAllele; +import forestry.api.genetics.IChromosome; +import forestry.api.genetics.IEffectData; +import forestry.api.genetics.IFlowerProvider; +import forestry.api.genetics.IGenome; +import forestry.api.genetics.IIndividual; +import forestry.api.genetics.IPollinatable; +import forestry.core.EnumErrorCode; +import forestry.core.config.Defaults; +import forestry.core.genetics.Chromosome; +import forestry.core.genetics.ClimateHelper; +import forestry.core.genetics.GenericRatings; +import forestry.core.genetics.IndividualLiving; +import forestry.core.proxy.Proxies; +import forestry.core.utils.StackUtils; +import forestry.core.utils.StringUtil; +import forestry.core.utils.Utils; +import forestry.core.utils.Vect; +import forestry.plugins.PluginApiculture; + +public class Bee extends IndividualLiving implements IBee { + + public IBeeGenome genome; + public IBeeGenome mate; + + /* CONSTRUCTOR */ + public Bee(NBTTagCompound nbttagcompound) { + readFromNBT(nbttagcompound); + } + + public Bee(World world, IBeeGenome genome, IBee mate) { + this(world, genome); + this.mate = mate.getGenome(); + this.isIrregularMating = mate.isNatural() != this.isNatural; + } + + public Bee(IBeeGenome genome, IBee mate) { + this(genome); + this.mate = mate.getGenome(); + this.isIrregularMating = mate.isNatural() != this.isNatural; + } + + public Bee(World world, IBeeGenome genome) { + this(world, genome, true, 0); + } + + public Bee(IBeeGenome genome) { + this(genome, true, 0); + } + + public Bee(World world, IBeeGenome genome, boolean isNatural, int generation) { + super(genome.getLifespan(), isNatural, generation); + this.genome = genome; + } + + public Bee(IBeeGenome genome, boolean isNatural, int generation) { + super(genome.getLifespan(), isNatural, generation); + this.genome = genome; + } + + /* SAVING & LOADING */ + @Override + public void readFromNBT(NBTTagCompound nbttagcompound) { + + if (nbttagcompound == null) { + this.genome = PluginApiculture.beeInterface.templateAsGenome(BeeTemplates.getForestTemplate()); + return; + } + + super.readFromNBT(nbttagcompound); + + if (nbttagcompound.hasKey("Genome")) + genome = new BeeGenome(nbttagcompound.getCompoundTag("Genome")); + else + genome = PluginApiculture.beeInterface.templateAsGenome(BeeTemplates.getForestTemplate()); + if (nbttagcompound.hasKey("Mate")) + mate = new BeeGenome(nbttagcompound.getCompoundTag("Mate")); + + } + + @Override + public void mate(IIndividual individual) { + if(!(individual instanceof IBee)) + return; + + IBee drone = (IBee)individual; + mate = drone.getGenome(); + this.isIrregularMating = drone.isNatural() != this.isNatural; + } + + /* EFFECTS */ + @Override + public IEffectData[] doEffect(IEffectData[] storedData, IBeeHousing housing) { + IAlleleBeeEffect effect = genome.getEffect(); + + if (effect == null) + return null; + + storedData[0] = doEffect(effect, storedData[0], housing); + + // Return here if the primary can already not be combined + if (!effect.isCombinable()) + return storedData; + + IAlleleBeeEffect secondary = (IAlleleBeeEffect) genome.getInactiveAllele(EnumBeeChromosome.EFFECT.ordinal()); + if (!secondary.isCombinable()) + return storedData; + + storedData[1] = doEffect(secondary, storedData[1], housing); + + return storedData; + } + + private IEffectData doEffect(IAlleleBeeEffect effect, IEffectData storedData, IBeeHousing housing) { + storedData = effect.validateStorage(storedData); + return effect.doEffect(genome, storedData, housing); + } + + @Override + public IEffectData[] doFX(IEffectData[] storedData, IBeeHousing housing) { + IAlleleBeeEffect effect = genome.getEffect(); + + if (effect == null) + return null; + + storedData[0] = doFX(effect, storedData[0], housing); + + // Return here if the primary can already not be combined + if (!effect.isCombinable()) + return storedData; + + IAlleleBeeEffect secondary = (IAlleleBeeEffect) genome.getInactiveAllele(EnumBeeChromosome.EFFECT.ordinal()); + if (!secondary.isCombinable()) + return storedData; + + storedData[1] = doFX(secondary, storedData[1], housing); + + return storedData; + } + + private IEffectData doFX(IAlleleBeeEffect effect, IEffectData storedData, IBeeHousing housing) { + return effect.doFX(genome, storedData, housing); + } + + // / INFORMATION + @Override + public IBeeGenome getGenome() { + return genome; + } + + @Override + public IBeeGenome getMate() { + return mate; + } + + @Override + public IBee copy() { + NBTTagCompound nbttagcompound = new NBTTagCompound(); + this.writeToNBT(nbttagcompound); + return new Bee(nbttagcompound); + + } + + @Override + public boolean canSpawn() { + return mate != null; + } + + @Override + public int isWorking(IBeeHousing housing) { + + World world = housing.getWorld(); + // / Rain needs tolerant flyers + if (world.isRaining() && !genome.getTolerantFlyer() && housing.getHumidity() != EnumHumidity.ARID && !housing.isSealed()) + return EnumErrorCode.ISRAINING.ordinal(); + + // / Night or darkness requires nocturnal species + if(world.isDaytime()) { + if(!canWorkDuringDay()) + return EnumErrorCode.NOTNIGHT.ordinal(); + } else if (!canWorkAtNight() && !housing.isSelfLighted()) + return EnumErrorCode.NOTDAY.ordinal(); + + if (world.getBlockLightValue(housing.getXCoord(), housing.getYCoord() + 2, housing.getZCoord()) > Defaults.APIARY_MIN_LEVEL_LIGHT) { + if(!canWorkDuringDay()) + return EnumErrorCode.NOTGLOOMY.ordinal(); + } else if(!canWorkAtNight() && !housing.isSelfLighted()) + return EnumErrorCode.NOTLUCID.ordinal(); + + // / No sky, except if in hell + BiomeGenBase biome = BiomeGenBase.getBiome(housing.getBiomeId()); + if(biome == null) + return EnumErrorCode.NOSKY.ordinal(); + if (!BiomeDictionary.isBiomeOfType(biome, BiomeDictionary.Type.NETHER) && !world.canBlockSeeTheSky(housing.getXCoord(), housing.getYCoord() + 3, housing.getZCoord()) + && !genome.getCaveDwelling() && !housing.isSunlightSimulated()) + return EnumErrorCode.NOSKY.ordinal(); + + // / And finally biome check + if (!checkBiomeHazard(world, housing.getTemperature(), housing.getHumidity(), housing.getXCoord(), housing.getYCoord(), housing.getZCoord())) + return EnumErrorCode.INVALIDBIOME.ordinal(); + + return EnumErrorCode.OK.ordinal(); + } + + private boolean canWorkAtNight() { + return genome.getPrimary().isNocturnal() || genome.getNocturnal(); + } + + private boolean canWorkDuringDay() { + return !genome.getPrimary().isNocturnal() || genome.getNocturnal(); + } + + private boolean checkBiomeHazard(World world, EnumTemperature temperature, EnumHumidity humidity, int x, int y, int z) { + + return ClimateHelper.isWithinLimits(temperature, humidity, + genome.getPrimary().getTemperature(), genome.getToleranceTemp(), + genome.getPrimary().getHumidity(), genome.getToleranceHumid()); + } + + @Override + public boolean hasFlower(IBeeHousing housing) { + + IFlowerProvider provider = genome.getFlowerProvider(); + + Vect coords = new Vect(housing.getXCoord(), housing.getYCoord(), housing.getZCoord()); + Vect posCurrent = new Vect(0, 0, 0); + int[] areaAr = genome.getTerritory(); + Vect area = new Vect(areaAr[0], areaAr[1], areaAr[2]).multiply(housing.getTerritoryModifier(genome, 1f)); + + if (area.x < 1) + area.x = 1; + if (area.y < 1) + area.y = 1; + if (area.z < 1) + area.z = 1; + + Vect offset = new Vect(-Math.round(area.x / 2), -Math.round(area.y / 2), -Math.round(area.z / 2)); + + boolean hasFlower = false; + + while (advancePosition(posCurrent, area)) { + + Vect posBlock = posCurrent.add(coords); + posBlock = posBlock.add(offset); + + if (provider.isAcceptedFlower(housing.getWorld(), this, posBlock.x, posBlock.y, posBlock.z)) { + hasFlower = true; + break; + } + + } + + return hasFlower; + } + + private boolean advancePosition(Vect posCurrent, Vect area) { + // Increment z first until end reached + if (posCurrent.z < area.z - 1) + posCurrent.z++; + else { + posCurrent.z = 0; + + if (posCurrent.x < area.x - 1) + posCurrent.x++; + else { + posCurrent.x = 0; + + if (posCurrent.y < area.y - 1) + posCurrent.y++; + else + return false; + } + } + + return true; + } + + @Override + public ArrayList getSuitableBiomeIds() { + EnumTemperature temperature = genome.getPrimary().getTemperature(); + EnumTolerance temperatureTolerance = genome.getToleranceTemp(); + + ArrayList toleratedTemperatures = ClimateHelper.getToleratedTemperature(temperature, temperatureTolerance); + + EnumHumidity humidity = genome.getPrimary().getHumidity(); + EnumTolerance humidityTolerance = genome.getToleranceHumid(); + + ArrayList toleratedHumidities = ClimateHelper.getToleratedHumidity(humidity, humidityTolerance); + + ArrayList biomeIdsTemp = new ArrayList(); + for (EnumTemperature temp : toleratedTemperatures) + biomeIdsTemp.addAll(EnumTemperature.getBiomeIds(temp)); + + ArrayList biomeIdsHumid = new ArrayList(); + for (EnumHumidity humid : toleratedHumidities) + biomeIdsHumid.addAll(EnumHumidity.getBiomeIds(humid)); + + biomeIdsTemp.retainAll(biomeIdsHumid); + + return biomeIdsTemp; + } + + @SuppressWarnings({ "rawtypes", "unchecked" }) + @Override + public void addTooltip(List list) { + + // No info 4 u! + if (!isAnalyzed) { + list.add("<" + StringUtil.localize("gui.unknown") + ">"); + return; + } + + // You analyzed it? Juicy tooltip coming up! + IAlleleBeeSpecies primary = genome.getPrimary(); + IAlleleBeeSpecies secondary = genome.getSecondary(); + if (!isPureBred(EnumBeeChromosome.SPECIES.ordinal())) + list.add("\u00A79" + primary.getName() + StringUtil.localize("bees.hyphen.adj.add") + "-" + secondary.getName() + + StringUtil.localize("bees.hybrid.adj.add") + " " + StringUtil.localize("gui.hybrid")); + list.add(genome.getActiveAllele(EnumBeeChromosome.SPEED.ordinal()).getName() + " " + StringUtil.localize("gui.worker")); + list.add(genome.getActiveAllele(EnumBeeChromosome.LIFESPAN.ordinal()).getName() + " " + StringUtil.localize("gui.life")); + list.add("\u00A7aT: " + ClimateHelper.toDisplay(genome.getPrimary().getTemperature()) + " / " + + StringUtil.capitalize(genome.getToleranceTemp().name())); + list.add("\u00A7aH: " + ClimateHelper.toDisplay(genome.getPrimary().getHumidity()) + " / " + + StringUtil.capitalize(genome.getToleranceHumid().name())); + list.add(StringUtil.localize(genome.getFlowerProvider().getDescription())); + if (genome.getNocturnal()) + list.add("\u00A7c" + GenericRatings.rateActivityTime(genome.getNocturnal(), false)); + } + + @Override + public void age(World world, float housingLifespanModifier) { + IBeekeepingMode mode = PluginApiculture.beeInterface.getBeekeepingMode(world); + float finalModifier = housingLifespanModifier * mode.getLifespanModifier(genome, mate, housingLifespanModifier); + + super.age(world, finalModifier); + } + + // / PRODUCTION + @Override + public ItemStack[] getProduceList() { + ArrayList products = new ArrayList(); + + IAlleleBeeSpecies primary = genome.getPrimary(); + IAlleleBeeSpecies secondary = genome.getSecondary(); + + products.addAll(primary.getProducts().keySet()); + + Set secondaryProducts = secondary.getProducts().keySet(); + // Remove duplicates + for (ItemStack second : secondaryProducts) { + boolean skip = false; + + for (ItemStack compare : products) + if (second.isItemEqual(compare)) { + skip = true; + break; + } + + if (!skip) + products.add(second); + + } + + return products.toArray(new ItemStack[0]); + } + + @Override + public ItemStack[] getSpecialtyList() { + return genome.getPrimary().getSpecialty().keySet().toArray(new ItemStack[0]); + } + + @Override + public ItemStack[] produceStacks(IBeeHousing housing) { + if (!hasFlower(housing)) + return null; + + if (housing == null) { + Proxies.log.warning("Failed to produce in an apiary because the beehousing was null."); + return null; + } + IBeekeepingMode mode = PluginApiculture.beeInterface.getBeekeepingMode(housing.getWorld()); + if (mode == null) { + Proxies.log.warning("Failed to produce in an apiary because the beekeeping mode was null."); + return null; + } + + ArrayList products = new ArrayList(); + + IAlleleBeeSpecies primary = genome.getPrimary(); + IAlleleBeeSpecies secondary = genome.getSecondary(); + + // All work and no play makes queen a dull girl. + if(mode.isOverworked(this, housing)) + setIsNatural(false); + + // Bee genetic speed * beehousing * beekeeping mode + float speed = genome.getSpeed() * housing.getProductionModifier(genome, 1f) * mode.getProductionModifier(genome, 1f); + + // / Primary Products + for (Map.Entry entry : primary.getProducts().entrySet()) + if (housing.getWorld().rand.nextInt(100) < entry.getValue() * speed) + products.add(entry.getKey().copy()); + // / Secondary Products + for (Map.Entry entry : secondary.getProducts().entrySet()) + if (housing.getWorld().rand.nextInt(100) < Math.round(entry.getValue() / 2) * speed) + products.add(entry.getKey().copy()); + + // We are done if the we are not jubilant. + if (!primary.isJubilant(genome, housing) || !secondary.isJubilant(genome, housing)) + return products.toArray(StackUtils.EMPTY_STACK_ARRAY); + + // / Specialty products + for (Map.Entry entry : primary.getSpecialty().entrySet()) + if (housing.getWorld().rand.nextInt(100) < entry.getValue() * speed) + products.add(entry.getKey().copy()); + + return genome.getFlowerProvider().affectProducts(housing.getWorld(), this, housing.getXCoord(), housing.getYCoord(), housing.getZCoord(), + products.toArray(StackUtils.EMPTY_STACK_ARRAY)); + } + + /* REPRODUCTION */ + @Override + public IBee spawnPrincess(IBeeHousing housing) { + + // We need a mated queen to produce offspring. + if (mate == null) + return null; + + // Fatigued queens do not produce princesses. + if (PluginApiculture.beeInterface.getBeekeepingMode(housing.getWorld()).isFatigued(this, housing)) + return null; + + return createOffspring(housing, getGeneration() + 1); + } + + @Override + public IBee[] spawnDrones(IBeeHousing housing) { + + World world = housing.getWorld(); + + // We need a mated queen to produce offspring. + if (mate == null) + return null; + + ArrayList bees = new ArrayList(); + + int toCreate = PluginApiculture.beeInterface.getBeekeepingMode(world).getFinalFertility(this, world, housing.getXCoord(), housing.getYCoord(), + housing.getZCoord()); + + if (toCreate <= 0) + toCreate = 1; + + for (int i = 0; i < toCreate; i++) { + IBee offspring = createOffspring(housing, -1); + if (offspring != null) { + offspring.setIsNatural(true); + bees.add(offspring); + } + } + + if (bees.size() > 0) + return bees.toArray(new IBee[0]); + else + return null; + } + + private IBee createOffspring(IBeeHousing housing, int generation) { + + World world = housing.getWorld(); + + IChromosome[] chromosomes = new IChromosome[genome.getChromosomes().length]; + IChromosome[] parent1 = genome.getChromosomes(); + IChromosome[] parent2 = mate.getChromosomes(); + + // Check for mutation. Replace one of the parents with the mutation + // template if mutation occured. + IChromosome[] mutated1 = mutateSpecies(housing, genome, mate); + if (mutated1 != null) + parent1 = mutated1; + IChromosome[] mutated2 = mutateSpecies(housing, mate, genome); + if (mutated2 != null) + parent2 = mutated2; + + for (int i = 0; i < parent1.length; i++) + if (parent1[i] != null && parent2[i] != null) + chromosomes[i] = Chromosome.inheritChromosome(world.rand, parent1[i], parent2[i]); + + IBeekeepingMode mode = PluginApiculture.beeInterface.getBeekeepingMode(world); + IBee offspring = new Bee(world, new BeeGenome(chromosomes), mode.isNaturalOffspring(this), generation); + + /* Disabling the mutation rate nerf + // All mutation and no play makes queen a dull girl. + if(mode.isDegenerating(this, offspring, housing)) + offspring.setIsNatural(false);*/ + + return offspring; + } + + private IChromosome[] mutateSpecies(IBeeHousing housing, IGenome genomeOne, IGenome genomeTwo) { + + World world = housing.getWorld(); + + IChromosome[] parent1 = genomeOne.getChromosomes(); + IChromosome[] parent2 = genomeTwo.getChromosomes(); + + IGenome genome0; + IGenome genome1; + IAllele allele0; + IAllele allele1; + + if (world.rand.nextBoolean()) { + allele0 = parent1[EnumBeeChromosome.SPECIES.ordinal()].getPrimaryAllele(); + allele1 = parent2[EnumBeeChromosome.SPECIES.ordinal()].getSecondaryAllele(); + + genome0 = genomeOne; + genome1 = genomeTwo; + } else { + allele0 = parent2[EnumBeeChromosome.SPECIES.ordinal()].getPrimaryAllele(); + allele1 = parent1[EnumBeeChromosome.SPECIES.ordinal()].getSecondaryAllele(); + + genome0 = genomeTwo; + genome1 = genomeOne; + } + + for (IBeeMutation mutation : PluginApiculture.beeInterface.getMutations(true)) { + float chance = 0; + + if ((chance = mutation.getChance(housing, allele0, allele1, genome0, genome1)) > 0) + if (world.rand.nextFloat()*100 < chance) { + IApiaristTracker breedingTracker = PluginApiculture.beeInterface.getBreedingTracker(world, housing.getOwnerName()); + breedingTracker.registerMutation(mutation); + return PluginApiculture.beeInterface.templateAsChromosomes(mutation.getTemplate()); + } + } + + return null; + } + + /* FLOWERS */ + @Override + public IIndividual retrievePollen(IBeeHousing housing) { + + int chance = (int) (genome.getFlowering() * housing.getFloweringModifier(getGenome(), 1f)); + + // Correct speed + if (housing.getWorld().rand.nextInt(100) >= chance) + return null; + + int[] areaAr = genome.getTerritory(); + Vect area = new Vect(areaAr[0], areaAr[1], areaAr[2]).multiply(housing.getTerritoryModifier(genome, 1f)).multiply(3.0f); + Vect offset = new Vect(-Math.round(area.x / 2), -Math.round(area.y / 2), -Math.round(area.z / 2)); + + if (area.x < 1) + area.x = 1; + if (area.y < 1) + area.y = 1; + if (area.z < 1) + area.z = 1; + + // We have up to ten attempts + for (int i = 0; i < 20; i++) { + + Vect randomPos = new Vect(housing.getWorld().rand.nextInt(area.x), housing.getWorld().rand.nextInt(area.y), housing.getWorld().rand.nextInt(area.z)); + + Vect posBlock = randomPos.add(new Vect(housing.getXCoord(), housing.getYCoord(), housing.getZCoord())); + posBlock = posBlock.add(offset); + + TileEntity tile = housing.getWorld().getTileEntity(posBlock.x, posBlock.y, posBlock.z); + if (!(tile instanceof IPollinatable)) { + if (housing.getWorld().isAirBlock(posBlock.x, posBlock.y, posBlock.z)) + continue; + + // Test for ersatz genomes + for (Map.Entry entry : AlleleManager.ersatzSpecimen.entrySet()) { + if (!StackUtils.equals(housing.getWorld().getBlock(posBlock.x, posBlock.y, posBlock.z), entry.getKey())) + continue; + if (entry.getKey().getItemDamage() != housing.getWorld().getBlockMetadata(posBlock.x, posBlock.y, posBlock.z)) + continue; + + // We matched, return ersatz genome + return entry.getValue().copy(); + } + + continue; + } + + IPollinatable pitcher = (IPollinatable) tile; + if (!genome.getFlowerProvider().isAcceptedPollinatable(housing.getWorld(), pitcher)) + continue; + + IIndividual pollen = pitcher.getPollen(); + + if (pollen != null) + return pollen; + } + + return null; + } + + @Override + public boolean pollinateRandom(IBeeHousing housing, IIndividual pollen) { + + int chance = (int) (genome.getFlowering() * housing.getFloweringModifier(getGenome(), 1f)); + + // Correct speed + if (housing.getWorld().rand.nextInt(100) >= chance) + return false; + + int[] areaAr = genome.getTerritory(); + Vect area = new Vect(areaAr[0], areaAr[1], areaAr[2]).multiply(housing.getTerritoryModifier(genome, 1f)).multiply(3.0f); + Vect offset = new Vect(-Math.round(area.x / 2), -Math.round(area.y / 4), -Math.round(area.z / 2)); + + if (area.x < 1) + area.x = 1; + if (area.y < 1) + area.y = 1; + if (area.z < 1) + area.z = 1; + + // We have up to ten attempts + for (int i = 0; i < 30; i++) { + + Vect randomPos = new Vect(housing.getWorld().rand.nextInt(area.x), housing.getWorld().rand.nextInt(area.y), housing.getWorld().rand.nextInt(area.z)); + + Vect posBlock = randomPos.add(new Vect(housing.getXCoord(), housing.getYCoord(), housing.getZCoord())); + posBlock = posBlock.add(offset); + + IPollinatable receiver = Utils.getOrCreatePollinatable(housing.getOwnerName(), housing.getWorld(), posBlock.x, posBlock.y, posBlock.z); + if(receiver == null) + continue; + + if (!genome.getFlowerProvider().isAcceptedPollinatable(housing.getWorld(), receiver)) + continue; + if (!receiver.canMateWith(pollen)) + continue; + + receiver.mateWith(pollen); + return true; + } + + return false; + } + + @Override + public void plantFlowerRandom(IBeeHousing housing) { + + int chance = (int) (genome.getFlowering() * housing.getFloweringModifier(getGenome(), 1f)); + + // Correct speed + if (housing.getWorld().rand.nextInt(100) >= chance) + return; + + // Gather required info + IFlowerProvider provider = genome.getFlowerProvider(); + int[] areaAr = genome.getTerritory(); + Vect area = new Vect(areaAr[0], areaAr[1], areaAr[2]).multiply(housing.getTerritoryModifier(genome, 1f)).multiply(3.0f); + Vect offset = new Vect(-Math.round(area.x / 2), -Math.round(area.y / 4), -Math.round(area.z / 2)); + + if (area.x < 1) + area.x = 1; + if (area.y < 1) + area.y = 1; + if (area.z < 1) + area.z = 1; + + // We have up to ten attempts + for (int i = 0; i < 10; i++) { + + Vect randomPos = new Vect(housing.getWorld().rand.nextInt(area.x), housing.getWorld().rand.nextInt(area.y), housing.getWorld().rand.nextInt(area.z)); + + Vect posBlock = randomPos.add(new Vect(housing.getXCoord(), housing.getYCoord(), housing.getZCoord())); + posBlock = posBlock.add(offset); + + if (provider.growFlower(housing.getWorld(), this, posBlock.x, posBlock.y, posBlock.z)) + break; + } + } +} diff --git a/forestry_common/apiculture/forestry/apiculture/genetics/BeeGenome.java b/forestry_common/apiculture/forestry/apiculture/genetics/BeeGenome.java new file mode 100755 index 000000000..6cfe7727f --- /dev/null +++ b/forestry_common/apiculture/forestry/apiculture/genetics/BeeGenome.java @@ -0,0 +1,145 @@ +/******************************************************************************* + * Copyright 2011-2014 by SirSengir + * + * This work is licensed under a Creative Commons Attribution-NonCommercial-NoDerivs 3.0 Unported License. + * + * To view a copy of this license, visit http://creativecommons.org/licenses/by-nc-nd/3.0/. + ******************************************************************************/ +package forestry.apiculture.genetics; + +import net.minecraft.nbt.NBTTagCompound; + +import forestry.api.apiculture.EnumBeeChromosome; +import forestry.api.apiculture.IAlleleBeeEffect; +import forestry.api.apiculture.IAlleleBeeSpecies; +import forestry.api.apiculture.IBeeGenome; +import forestry.api.genetics.EnumTolerance; +import forestry.api.genetics.IAlleleFloat; +import forestry.api.genetics.IAlleleFlowers; +import forestry.api.genetics.IAlleleInteger; +import forestry.api.genetics.IChromosome; +import forestry.api.genetics.IFlowerProvider; +import forestry.api.genetics.ISpeciesRoot; +import forestry.core.genetics.AlleleArea; +import forestry.core.genetics.AlleleBoolean; +import forestry.core.genetics.AlleleTolerance; +import forestry.core.genetics.Genome; +import forestry.core.utils.Vect; +import forestry.plugins.PluginApiculture; + +public class BeeGenome extends Genome implements IBeeGenome { + /** + * 0 - Species (determines product) + * + * 1 - Speed + * + * 2 - Lifespan + * + * 3 - Fertility (Maximum number of offspring) + * + * 4 - Preferred temperature Icy: Snow biomes Cold: Tundra/Steppe, Extreme Mountains/Hills? Normal: Plains, Forests, Mountains Hot: Desert Hellish: Nether + * + * 5 - Temperature tolerance (Range +/-) + * + * 6 - Nocturnal + * + * 7 - Preferred humidity (Arid - Normal - Damp) + * + * 8 - Humidity tolerance (Range +/-) + * + * 9 - Flight interference tolerance (stuff falling from the sky/other hindrances -> tolerates dampness + flight interference tolerance => rain resistance) + * + * 10 - Cave dwelling + * + * 11 - Required flowers + * + * 12 - Flower plant chance + * + * 13 - Territory + */ + /* CONSTRUCTOR */ + public BeeGenome(NBTTagCompound nbttagcompound) { + super(nbttagcompound); + } + + public BeeGenome(IChromosome[] chromosomes) { + super(chromosomes); + } + + // / INFORMATION RETRIEVAL + @Override + public IAlleleBeeSpecies getPrimary() { + return (IAlleleBeeSpecies) getActiveAllele(EnumBeeChromosome.SPECIES.ordinal()); + } + + @Override + public IAlleleBeeSpecies getSecondary() { + return (IAlleleBeeSpecies) getInactiveAllele(EnumBeeChromosome.SPECIES.ordinal()); + } + + @Override + public float getSpeed() { + return ((IAlleleFloat) getActiveAllele(EnumBeeChromosome.SPEED.ordinal())).getValue(); + } + + @Override + public int getLifespan() { + return ((IAlleleInteger) getActiveAllele(EnumBeeChromosome.LIFESPAN.ordinal())).getValue(); + } + + @Override + public int getFertility() { + return ((IAlleleInteger) getActiveAllele(EnumBeeChromosome.FERTILITY.ordinal())).getValue(); + } + + @Override + public EnumTolerance getToleranceTemp() { + return ((AlleleTolerance) getActiveAllele(EnumBeeChromosome.TEMPERATURE_TOLERANCE.ordinal())).getValue(); + } + + @Override + public boolean getNocturnal() { + return ((AlleleBoolean) getActiveAllele(EnumBeeChromosome.NOCTURNAL.ordinal())).getValue(); + } + + @Override + public EnumTolerance getToleranceHumid() { + return ((AlleleTolerance) getActiveAllele(EnumBeeChromosome.HUMIDITY_TOLERANCE.ordinal())).getValue(); + } + + @Override + public boolean getTolerantFlyer() { + return ((AlleleBoolean) getActiveAllele(EnumBeeChromosome.TOLERANT_FLYER.ordinal())).getValue(); + } + + @Override + public boolean getCaveDwelling() { + return ((AlleleBoolean) getActiveAllele(EnumBeeChromosome.CAVE_DWELLING.ordinal())).getValue(); + } + + @Override + public IFlowerProvider getFlowerProvider() { + return ((IAlleleFlowers) getActiveAllele(EnumBeeChromosome.FLOWER_PROVIDER.ordinal())).getProvider(); + } + + @Override + public int getFlowering() { + return ((IAlleleInteger) getActiveAllele(EnumBeeChromosome.FLOWERING.ordinal())).getValue(); + } + + @Override + public int[] getTerritory() { + Vect area = ((AlleleArea) getActiveAllele(EnumBeeChromosome.TERRITORY.ordinal())).getArea(); + return new int[] { area.x, area.y, area.z }; + } + + @Override + public IAlleleBeeEffect getEffect() { + return (IAlleleBeeEffect) getActiveAllele(EnumBeeChromosome.EFFECT.ordinal()); + } + + @Override + public ISpeciesRoot getSpeciesRoot() { + return PluginApiculture.beeInterface; + } +} diff --git a/forestry_common/apiculture/forestry/apiculture/genetics/BeeHelper.java b/forestry_common/apiculture/forestry/apiculture/genetics/BeeHelper.java new file mode 100755 index 000000000..25a41fed1 --- /dev/null +++ b/forestry_common/apiculture/forestry/apiculture/genetics/BeeHelper.java @@ -0,0 +1,331 @@ +/******************************************************************************* + * Copyright 2011-2014 by SirSengir + * + * This work is licensed under a Creative Commons Attribution-NonCommercial-NoDerivs 3.0 Unported License. + * + * To view a copy of this license, visit http://creativecommons.org/licenses/by-nc-nd/3.0/. + ******************************************************************************/ +package forestry.apiculture.genetics; + +import java.util.ArrayList; +import java.util.Collection; +import java.util.Collections; +import java.util.Iterator; +import java.util.Locale; +import java.util.Map.Entry; + +import net.minecraft.item.Item; +import net.minecraft.item.ItemStack; +import net.minecraft.nbt.NBTTagCompound; +import net.minecraft.world.World; + +import cpw.mods.fml.common.FMLCommonHandler; + +import forestry.api.apiculture.EnumBeeChromosome; +import forestry.api.apiculture.EnumBeeType; +import forestry.api.apiculture.IAlleleBeeSpecies; +import forestry.api.apiculture.IAlvearyComponent; +import forestry.api.apiculture.IApiaristTracker; +import forestry.api.apiculture.IBee; +import forestry.api.apiculture.IBeeGenome; +import forestry.api.apiculture.IBeeHousing; +import forestry.api.apiculture.IBeeMutation; +import forestry.api.apiculture.IBeeRoot; +import forestry.api.apiculture.IBeekeepingLogic; +import forestry.api.apiculture.IBeekeepingMode; +import forestry.api.core.IStructureLogic; +import forestry.api.genetics.AlleleManager; +import forestry.api.genetics.IAllele; +import forestry.api.genetics.IChromosomeType; +import forestry.api.genetics.IIndividual; +import forestry.api.genetics.IMutation; +import forestry.apiculture.BeekeepingLogic; +import forestry.apiculture.gadgets.StructureLogicAlveary; +import forestry.core.config.ForestryItem; +import forestry.core.genetics.SpeciesRoot; +import forestry.plugins.PluginApiculture; + +public class BeeHelper extends SpeciesRoot implements IBeeRoot { + + public static int beeSpeciesCount = -1; + public static final String UID = "rootBees"; + + @Override + public String getUID() { + return UID; + } + + @Override + public Class getMemberClass() { + return IBee.class; + } + + @Override + public int getSpeciesCount() { + if (beeSpeciesCount < 0) { + beeSpeciesCount = 0; + Iterator > it = AlleleManager.alleleRegistry.getRegisteredAlleles().entrySet().iterator(); + while (it.hasNext()) { + Entry entry = it.next(); + if (entry.getValue() instanceof IAlleleBeeSpecies) + if (((IAlleleBeeSpecies) entry.getValue()).isCounted()) + beeSpeciesCount++; + } + } + + return beeSpeciesCount; + } + + @Override + public boolean isMember(ItemStack stack) { + return getType(stack) != EnumBeeType.NONE; + } + + @Override + public boolean isMember(ItemStack stack, int type) { + return getType(stack).ordinal() == type; + } + + @Override + public boolean isMember(IIndividual individual) { + return individual instanceof IBee; + } + + @Override + public ItemStack getMemberStack(IIndividual bee, int type) { + if (!isMember(bee)) + return null; + + Item beeItem = null; + switch (EnumBeeType.VALUES[type]) { + case QUEEN: + beeItem = ForestryItem.beeQueenGE.item(); + break; + case PRINCESS: + beeItem = ForestryItem.beePrincessGE.item(); + break; + case DRONE: + beeItem = ForestryItem.beeDroneGE.item(); + break; + case LARVAE: + beeItem = ForestryItem.beeLarvaeGE.item(); + break; + default: + throw new RuntimeException("Cannot instantiate a bee of type " + type); + + } + + NBTTagCompound nbttagcompound = new NBTTagCompound(); + bee.writeToNBT(nbttagcompound); + ItemStack beeStack = new ItemStack(beeItem); + beeStack.setTagCompound(nbttagcompound); + return beeStack; + } + + @Override + public EnumBeeType getType(ItemStack stack) { + if (stack == null) + return EnumBeeType.NONE; + + if (ForestryItem.beeDroneGE.isItemEqual(stack)) + return EnumBeeType.DRONE; + else if (ForestryItem.beePrincessGE.isItemEqual(stack)) + return EnumBeeType.PRINCESS; + else if (ForestryItem.beeQueenGE.isItemEqual(stack)) + return EnumBeeType.QUEEN; + else if (ForestryItem.beeLarvaeGE.isItemEqual(stack)) + return EnumBeeType.LARVAE; + + return EnumBeeType.NONE; + } + + @Override + public boolean isDrone(ItemStack stack) { + return getType(stack) == EnumBeeType.DRONE; + } + + @Override + public boolean isMated(ItemStack stack) { + if (getType(stack) != EnumBeeType.QUEEN) + return false; + + IBee bee = getMember(stack); + return bee.getMate() != null; + } + + @Override + public IBee getMember(ItemStack stack) { + if (!ForestryItem.beeQueenGE.isItemEqual(stack) && !ForestryItem.beePrincessGE.isItemEqual(stack) + && !ForestryItem.beeDroneGE.isItemEqual(stack) && !ForestryItem.beeLarvaeGE.isItemEqual(stack)) + return null; + + return new Bee(stack.getTagCompound()); + } + + @Override + public IBee getMember(NBTTagCompound compound) { + return new Bee(compound); + } + + @Override + public IBee getBee(World world, IBeeGenome genome) { + return new Bee(world, genome); + } + + @Override + public IBee getBee(World world, IBeeGenome genome, IBee mate) { + return new Bee(world, genome, mate); + } + + /* GENOME CONVERSIONS */ + @Override + public IBeeGenome templateAsGenome(IAllele[] template) { + return new BeeGenome(templateAsChromosomes(template)); + } + + @Override + public IBeeGenome templateAsGenome(IAllele[] templateActive, IAllele[] templateInactive) { + return new BeeGenome(templateAsChromosomes(templateActive, templateInactive)); + } + + @Override + public IBee templateAsIndividual(IAllele[] template) { + return new Bee(templateAsGenome(template)); + } + + @Override + public IBee templateAsIndividual(IAllele[] templateActive, IAllele[] templateInactive) { + return new Bee(templateAsGenome(templateActive, templateInactive)); + } + + /* TEMPLATES */ + public static ArrayList beeTemplates = new ArrayList(); + + @Override + public ArrayList getIndividualTemplates() { + return beeTemplates; + } + + @Override + public void registerTemplate(String identifier, IAllele[] template) { + beeTemplates.add(new Bee(PluginApiculture.beeInterface.templateAsGenome(template))); + speciesTemplates.put(identifier, template); + } + + @Override + public IAllele[] getDefaultTemplate() { + return BeeTemplates.getDefaultTemplate(); + } + + /* MUTATIONS */ + /** + * List of possible mutations on species alleles. + */ + private static ArrayList beeMutations = new ArrayList(); + + @Override + public Collection getMutations(boolean shuffle) { + if (shuffle) + Collections.shuffle(beeMutations); + return beeMutations; + } + + @Override + public void registerMutation(IMutation mutation) { + if (AlleleManager.alleleRegistry.isBlacklisted(mutation.getTemplate()[0].getUID())) + return; + if (AlleleManager.alleleRegistry.isBlacklisted(mutation.getAllele0().getUID())) + return; + if (AlleleManager.alleleRegistry.isBlacklisted(mutation.getAllele1().getUID())) + return; + + beeMutations.add((IBeeMutation) mutation); + } + + /* BREEDING MODES */ + ArrayList beekeepingModes = new ArrayList(); + public static IBeekeepingMode activeBeekeepingMode; + + @Override + public void resetBeekeepingMode() { + activeBeekeepingMode = null; + } + + @Override + public ArrayList getBeekeepingModes() { + return this.beekeepingModes; + } + + @Override + public IBeekeepingMode getBeekeepingMode(World world) { + if (activeBeekeepingMode != null) + return activeBeekeepingMode; + + // No beekeeping mode yet, get it. + IApiaristTracker tracker = getBreedingTracker(world, "__COMMON_"); + String mode = tracker.getModeName(); + if (mode == null || mode.isEmpty()) + mode = PluginApiculture.beekeepingMode; + + setBeekeepingMode(world, mode); + FMLCommonHandler.instance().getFMLLogger().debug("Set beekeeping mode for a world to " + mode); + + return activeBeekeepingMode; + } + + @Override + public void registerBeekeepingMode(IBeekeepingMode mode) { + beekeepingModes.add(mode); + } + + @Override + public void setBeekeepingMode(World world, String name) { + activeBeekeepingMode = getBeekeepingMode(name); + getBreedingTracker(world, "__COMMON_").setModeName(name); + } + + @Override + public IBeekeepingMode getBeekeepingMode(String name) { + for (IBeekeepingMode mode : beekeepingModes) { + if (mode.getName().equals(name) || mode.getName().equals(name.toLowerCase(Locale.ENGLISH))) + return mode; + } + + FMLCommonHandler.instance().getFMLLogger().debug("Failed to find a beekeeping mode called '%s', reverting to fallback."); + return beekeepingModes.get(0); + } + + @Override + public IApiaristTracker getBreedingTracker(World world, String player) { + String filename = "ApiaristTracker." + player; + ApiaristTracker tracker = (ApiaristTracker) world.loadItemData(ApiaristTracker.class, filename); + + // Create a tracker if there is none yet. + if (tracker == null) { + tracker = new ApiaristTracker(filename, player); + world.setItemData(filename, tracker); + } + + return tracker; + } + + @Override + public IBeekeepingLogic createBeekeepingLogic(IBeeHousing housing) { + return new BeekeepingLogic(housing); + } + + @Override + public IStructureLogic createAlvearyStructureLogic(IAlvearyComponent structure) { + return new StructureLogicAlveary(structure); + } + + @Override + public IChromosomeType[] getKaryotype() { + return EnumBeeChromosome.values(); + } + + @Override + public IChromosomeType getKaryotypeKey() { + return EnumBeeChromosome.SPECIES; + } +} diff --git a/forestry_common/apiculture/forestry/apiculture/genetics/BeeMutation.java b/forestry_common/apiculture/forestry/apiculture/genetics/BeeMutation.java new file mode 100755 index 000000000..c97da6d4b --- /dev/null +++ b/forestry_common/apiculture/forestry/apiculture/genetics/BeeMutation.java @@ -0,0 +1,126 @@ +/******************************************************************************* + * Copyright 2011-2014 by SirSengir + * + * This work is licensed under a Creative Commons Attribution-NonCommercial-NoDerivs 3.0 Unported License. + * + * To view a copy of this license, visit http://creativecommons.org/licenses/by-nc-nd/3.0/. + ******************************************************************************/ +package forestry.apiculture.genetics; + +import java.util.ArrayList; + +import net.minecraft.world.World; +import net.minecraft.world.biome.BiomeGenBase; + +import net.minecraftforge.common.BiomeDictionary; + +import forestry.api.apiculture.IBeeGenome; +import forestry.api.apiculture.IBeeHousing; +import forestry.api.apiculture.IBeeMutation; +import forestry.api.apiculture.IBeeRoot; +import forestry.api.genetics.AlleleManager; +import forestry.api.genetics.IAllele; +import forestry.api.genetics.IGenome; +import forestry.core.genetics.Mutation; +import forestry.plugins.PluginApiculture; + +public class BeeMutation extends Mutation implements IBeeMutation { + + private final IBeeRoot root; + + boolean requiresDay = false; + boolean requiresNight = false; + + private final ArrayList restrictBiomeTypes = new ArrayList(); + private boolean strictBiomeCheck = false; + + public BeeMutation(IAllele allele0, IAllele allele1, IAllele[] template, int chance) { + super(allele0, allele1, template, chance); + + root = (IBeeRoot)AlleleManager.alleleRegistry.getSpeciesRoot("rootBees"); + PluginApiculture.beeInterface.registerMutation(this); + } + + @Override + public IBeeRoot getRoot() { + return root; + } + + public BeeMutation enableStrictBiomeCheck() { + strictBiomeCheck = true; + return this; + } + + public BeeMutation restrictBiomeType(BiomeDictionary.Type type) { + restrictBiomeTypes.add(type); + specialConditions.add(String.format("Is restricted to %s-like environments.", type.toString())); + return this; + } + + public BeeMutation requireDay() { + requiresDay = true; + requiresNight = false; + specialConditions.add("Can only occur during the day."); + return this; + } + + public BeeMutation requireNight() { + requiresDay = false; + requiresNight = true; + specialConditions.add("Can only occur during the night."); + return this; + } + + @Override + public float getChance(IBeeHousing housing, IAllele allele0, IAllele allele1, IGenome genome0, IGenome genome1) { + + World world = housing.getWorld(); + if (requiresDay && !world.isDaytime()) + return 0; + + if (requiresNight && world.isDaytime()) + return 0; + + // Skip if we are restricted by biomes and this one does not match. + if (restrictBiomeTypes.size() > 0) { + boolean noneMatched = true; + + BiomeGenBase biome = BiomeGenBase.getBiome(housing.getBiomeId()); + if(strictBiomeCheck) { + BiomeDictionary.Type[] types = BiomeDictionary.getTypesForBiome(biome); + if(types.length == 1 && restrictBiomeTypes.contains(types[0])) + noneMatched = false; + } else { + for(BiomeDictionary.Type type : restrictBiomeTypes) { + if(BiomeDictionary.isBiomeOfType(biome, type)) { + noneMatched = false; + break; + } + } + } + + if (noneMatched) + return 0; + } + + BiomeGenBase biome = world.getWorldChunkManager().getBiomeGenAt(housing.getXCoord(), housing.getZCoord()); + if (biome.temperature < minTemperature || biome.temperature > maxTemperature) + return 0; + if (biome.rainfall < minRainfall || biome.rainfall > maxRainfall) + return 0; + + float processedChance = chance * housing.getMutationModifier((IBeeGenome) genome0, (IBeeGenome) genome1, 1f) + * PluginApiculture.beeInterface.getBeekeepingMode(world).getMutationModifier((IBeeGenome) genome0, (IBeeGenome) genome1, 1f); + if(processedChance <= 0) + return 0; + + if (this.allele0.getUID().equals(allele0.getUID()) && this.allele1.getUID().equals(allele1.getUID())) + return processedChance; + if (this.allele1.getUID().equals(allele0.getUID()) && this.allele0.getUID().equals(allele1.getUID())) + return processedChance; + + return 0; + + } + +} diff --git a/forestry_common/apiculture/forestry/apiculture/genetics/BeeTemplates.java b/forestry_common/apiculture/forestry/apiculture/genetics/BeeTemplates.java new file mode 100755 index 000000000..0c5fce2a0 --- /dev/null +++ b/forestry_common/apiculture/forestry/apiculture/genetics/BeeTemplates.java @@ -0,0 +1,595 @@ +/******************************************************************************* + * Copyright 2011-2014 by SirSengir + * + * This work is licensed under a Creative Commons Attribution-NonCommercial-NoDerivs 3.0 Unported License. + * + * To view a copy of this license, visit http://creativecommons.org/licenses/by-nc-nd/3.0/. + ******************************************************************************/ +package forestry.apiculture.genetics; + +import forestry.api.apiculture.EnumBeeChromosome; +import forestry.api.genetics.IAllele; +import forestry.api.genetics.IMutation; +import forestry.core.genetics.Allele; + +public class BeeTemplates { + + // / MUTATIONS + public static IMutation commonA; + + public static IMutation commonB; + public static IMutation commonC; + + public static IMutation commonD; + public static IMutation commonE; + public static IMutation commonF; + + public static IMutation commonG; + public static IMutation commonH; + public static IMutation commonI; + public static IMutation commonJ; + + public static IMutation commonK; + public static IMutation commonL; + public static IMutation commonM; + public static IMutation commonN; + public static IMutation commonO; + + public static IMutation cultivatedA; + public static IMutation cultivatedB; + public static IMutation cultivatedC; + public static IMutation cultivatedD; + public static IMutation cultivatedE; + public static IMutation cultivatedF; + + public static IMutation nobleA; + public static IMutation majesticA; + public static IMutation imperialA; + + public static IMutation diligentA; + public static IMutation unwearyA; + public static IMutation industriousA; + + public static IMutation heroicA; + + public static IMutation sinisterA; + public static IMutation sinisterB; + public static IMutation fiendishA; + public static IMutation fiendishB; + public static IMutation fiendishC; + public static IMutation demonicA; + + // Austere branch + public static IMutation frugalA; + public static IMutation frugalB; + public static IMutation austereA; + + // Tropical branch + public static IMutation exoticA; + public static IMutation edenicA; + + // Wintry branch + public static IMutation icyA; + public static IMutation glacialA; + + // Festive branch + public static IMutation leporineA; + public static IMutation merryA; + public static IMutation tipsyA; + public static IMutation trickyA; + + // Agrarian branch + public static IMutation ruralA; + + // Monastic branch + public static IMutation secludedA; + public static IMutation hermiticA; + + // End branch + public static IMutation spectralA; + public static IMutation phantasmalA; + + public static IMutation vindictiveA; + + public static IMutation vengefulA; + public static IMutation vengefulB; + public static IMutation avengingA; + + public static IAllele[] getDefaultTemplate() { + IAllele[] alleles = new IAllele[EnumBeeChromosome.values().length]; + + alleles[EnumBeeChromosome.SPECIES.ordinal()] = Allele.speciesForest; + alleles[EnumBeeChromosome.SPEED.ordinal()] = Allele.speedSlowest; + alleles[EnumBeeChromosome.LIFESPAN.ordinal()] = Allele.lifespanShorter; + alleles[EnumBeeChromosome.FERTILITY.ordinal()] = Allele.fertilityNormal; + alleles[EnumBeeChromosome.TEMPERATURE_TOLERANCE.ordinal()] = Allele.toleranceNone; + alleles[EnumBeeChromosome.NOCTURNAL.ordinal()] = Allele.boolFalse; + alleles[EnumBeeChromosome.HUMIDITY_TOLERANCE.ordinal()] = Allele.toleranceNone; + alleles[EnumBeeChromosome.TOLERANT_FLYER.ordinal()] = Allele.boolFalse; + alleles[EnumBeeChromosome.CAVE_DWELLING.ordinal()] = Allele.boolFalse; + alleles[EnumBeeChromosome.FLOWER_PROVIDER.ordinal()] = Allele.flowersVanilla; + alleles[EnumBeeChromosome.FLOWERING.ordinal()] = Allele.floweringSlowest; + alleles[EnumBeeChromosome.TERRITORY.ordinal()] = Allele.territoryDefault; + alleles[EnumBeeChromosome.EFFECT.ordinal()] = Allele.effectNone; + + return alleles; + } + + // / COMMON BRANCH + + public static IAllele[] getForestTemplate() { + IAllele[] alleles = getDefaultTemplate(); + alleles[EnumBeeChromosome.FLOWERING.ordinal()] = Allele.floweringSlower; + alleles[EnumBeeChromosome.FERTILITY.ordinal()] = Allele.fertilityHigh; + return alleles; + } + + public static IAllele[] getForestRainResistTemplate() { + IAllele[] alleles = getForestTemplate(); + alleles[EnumBeeChromosome.TOLERANT_FLYER.ordinal()] = Allele.boolTrue; + return alleles; + } + + public static IAllele[] getMeadowsTemplate() { + IAllele[] alleles = getDefaultTemplate(); + alleles[EnumBeeChromosome.SPECIES.ordinal()] = Allele.speciesMeadows; + alleles[EnumBeeChromosome.FLOWERING.ordinal()] = Allele.floweringSlower; + return alleles; + } + + public static IAllele[] getCommonTemplate() { + IAllele[] alleles = getDefaultTemplate(); + alleles[EnumBeeChromosome.SPECIES.ordinal()] = Allele.speciesCommon; + alleles[EnumBeeChromosome.SPEED.ordinal()] = Allele.speedSlower; + return alleles; + } + + public static IAllele[] getCultivatedTemplate() { + IAllele[] alleles = getDefaultTemplate(); + alleles[EnumBeeChromosome.SPECIES.ordinal()] = Allele.speciesCultivated; + alleles[EnumBeeChromosome.SPEED.ordinal()] = Allele.speedFast; + alleles[EnumBeeChromosome.LIFESPAN.ordinal()] = Allele.lifespanShortest; + return alleles; + } + + // / NOBLE BRANCH + + public static IAllele[] getNobleTemplate() { + IAllele[] alleles = getDefaultTemplate(); + alleles[EnumBeeChromosome.SPECIES.ordinal()] = Allele.speciesNoble; + alleles[EnumBeeChromosome.SPEED.ordinal()] = Allele.speedSlower; + alleles[EnumBeeChromosome.LIFESPAN.ordinal()] = Allele.lifespanShort; + alleles[EnumBeeChromosome.FLOWERING.ordinal()] = Allele.floweringSlow; + return alleles; + } + + public static IAllele[] getMajesticTemplate() { + IAllele[] alleles = getDefaultTemplate(); + alleles[EnumBeeChromosome.SPECIES.ordinal()] = Allele.speciesMajestic; + alleles[EnumBeeChromosome.SPEED.ordinal()] = Allele.speedNorm; + alleles[EnumBeeChromosome.LIFESPAN.ordinal()] = Allele.lifespanShortened; + alleles[EnumBeeChromosome.FERTILITY.ordinal()] = Allele.fertilityMaximum; + return alleles; + } + + public static IAllele[] getImperialTemplate() { + IAllele[] alleles = getDefaultTemplate(); + alleles[EnumBeeChromosome.SPECIES.ordinal()] = Allele.speciesImperial; + alleles[EnumBeeChromosome.SPEED.ordinal()] = Allele.speedSlower; + alleles[EnumBeeChromosome.LIFESPAN.ordinal()] = Allele.lifespanNormal; + alleles[EnumBeeChromosome.EFFECT.ordinal()] = Allele.effectBeatific; + return alleles; + } + + // / INDUSTRIOUS BRANCH + + public static IAllele[] getDiligentTemplate() { + IAllele[] alleles = getDefaultTemplate(); + alleles[EnumBeeChromosome.SPECIES.ordinal()] = Allele.speciesDiligent; + alleles[EnumBeeChromosome.SPEED.ordinal()] = Allele.speedSlower; + alleles[EnumBeeChromosome.LIFESPAN.ordinal()] = Allele.lifespanShort; + alleles[EnumBeeChromosome.FLOWERING.ordinal()] = Allele.floweringSlow; + return alleles; + } + + public static IAllele[] getUnwearyTemplate() { + IAllele[] alleles = getDefaultTemplate(); + alleles[EnumBeeChromosome.SPECIES.ordinal()] = Allele.speciesUnweary; + alleles[EnumBeeChromosome.SPEED.ordinal()] = Allele.speedNorm; + alleles[EnumBeeChromosome.LIFESPAN.ordinal()] = Allele.lifespanShortened; + return alleles; + } + + public static IAllele[] getIndustriousTemplate() { + IAllele[] alleles = getDefaultTemplate(); + alleles[EnumBeeChromosome.SPECIES.ordinal()] = Allele.speciesIndustrious; + alleles[EnumBeeChromosome.SPEED.ordinal()] = Allele.speedSlower; + alleles[EnumBeeChromosome.LIFESPAN.ordinal()] = Allele.lifespanNormal; + alleles[EnumBeeChromosome.FLOWERING.ordinal()] = Allele.floweringFast; + return alleles; + } + + // / HEROIC BRANCH + + public static IAllele[] getSteadfastTemplate() { + IAllele[] alleles = getDefaultTemplate(); + alleles[EnumBeeChromosome.SPECIES.ordinal()] = Allele.speciesSteadfast; + alleles[EnumBeeChromosome.SPEED.ordinal()] = Allele.speedSlower; + alleles[EnumBeeChromosome.LIFESPAN.ordinal()] = Allele.lifespanNormal; + alleles[EnumBeeChromosome.NOCTURNAL.ordinal()] = Allele.boolTrue; + alleles[EnumBeeChromosome.CAVE_DWELLING.ordinal()] = Allele.boolTrue; + return alleles; + } + + public static IAllele[] getValiantTemplate() { + IAllele[] alleles = getDefaultTemplate(); + alleles[EnumBeeChromosome.SPECIES.ordinal()] = Allele.speciesValiant; + alleles[EnumBeeChromosome.SPEED.ordinal()] = Allele.speedSlow; + alleles[EnumBeeChromosome.LIFESPAN.ordinal()] = Allele.lifespanLong; + alleles[EnumBeeChromosome.NOCTURNAL.ordinal()] = Allele.boolTrue; + alleles[EnumBeeChromosome.CAVE_DWELLING.ordinal()] = Allele.boolTrue; + return alleles; + } + + public static IAllele[] getHeroicTemplate() { + IAllele[] alleles = getDefaultTemplate(); + alleles[EnumBeeChromosome.SPECIES.ordinal()] = Allele.speciesHeroic; + alleles[EnumBeeChromosome.SPEED.ordinal()] = Allele.speedSlow; + alleles[EnumBeeChromosome.LIFESPAN.ordinal()] = Allele.lifespanLong; + alleles[EnumBeeChromosome.NOCTURNAL.ordinal()] = Allele.boolTrue; + alleles[EnumBeeChromosome.CAVE_DWELLING.ordinal()] = Allele.boolTrue; + alleles[EnumBeeChromosome.EFFECT.ordinal()] = Allele.effectHeroic; + return alleles; + } + + // / INFERNAL BRANCH + + public static IAllele[] getBranchInfernalTemplate() { + IAllele[] alleles = getDefaultTemplate(); + alleles[EnumBeeChromosome.TEMPERATURE_TOLERANCE.ordinal()] = Allele.toleranceDown2; + alleles[EnumBeeChromosome.NOCTURNAL.ordinal()] = Allele.boolTrue; + alleles[EnumBeeChromosome.FLOWER_PROVIDER.ordinal()] = Allele.flowersNether; + alleles[EnumBeeChromosome.FLOWERING.ordinal()] = Allele.floweringAverage; + return alleles; + } + + public static IAllele[] getSinisterTemplate() { + IAllele[] alleles = getBranchInfernalTemplate(); + alleles[EnumBeeChromosome.SPECIES.ordinal()] = Allele.speciesSinister; + alleles[EnumBeeChromosome.SPEED.ordinal()] = Allele.speedSlower; + alleles[EnumBeeChromosome.LIFESPAN.ordinal()] = Allele.lifespanNormal; + alleles[EnumBeeChromosome.EFFECT.ordinal()] = Allele.effectAggressive; + return alleles; + } + + public static IAllele[] getFiendishTemplate() { + IAllele[] alleles = getBranchInfernalTemplate(); + alleles[EnumBeeChromosome.SPECIES.ordinal()] = Allele.speciesFiendish; + alleles[EnumBeeChromosome.SPEED.ordinal()] = Allele.speedNorm; + alleles[EnumBeeChromosome.LIFESPAN.ordinal()] = Allele.lifespanLong; + alleles[EnumBeeChromosome.EFFECT.ordinal()] = Allele.effectAggressive; + return alleles; + } + + public static IAllele[] getDemonicTemplate() { + IAllele[] alleles = getBranchInfernalTemplate(); + alleles[EnumBeeChromosome.SPECIES.ordinal()] = Allele.speciesDemonic; + alleles[EnumBeeChromosome.SPEED.ordinal()] = Allele.speedSlower; + alleles[EnumBeeChromosome.LIFESPAN.ordinal()] = Allele.lifespanLonger; + alleles[EnumBeeChromosome.EFFECT.ordinal()] = Allele.effectIgnition; + return alleles; + } + + // / AUSTERE BRANCH + + public static IAllele[] getAustereBranchTemplate() { + IAllele[] alleles = getDefaultTemplate(); + alleles[EnumBeeChromosome.TEMPERATURE_TOLERANCE.ordinal()] = Allele.toleranceBoth1; + alleles[EnumBeeChromosome.HUMIDITY_TOLERANCE.ordinal()] = Allele.toleranceUp1; + alleles[EnumBeeChromosome.NOCTURNAL.ordinal()] = Allele.boolTrue; + alleles[EnumBeeChromosome.FLOWER_PROVIDER.ordinal()] = Allele.flowersCacti; + return alleles; + } + + public static IAllele[] getModestTemplate() { + IAllele[] alleles = getAustereBranchTemplate(); + alleles[EnumBeeChromosome.SPECIES.ordinal()] = Allele.speciesModest; + alleles[EnumBeeChromosome.SPEED.ordinal()] = Allele.speedSlower; + alleles[EnumBeeChromosome.LIFESPAN.ordinal()] = Allele.lifespanShort; + return alleles; + } + + public static IAllele[] getFrugalTemplate() { + IAllele[] alleles = getAustereBranchTemplate(); + alleles[EnumBeeChromosome.SPECIES.ordinal()] = Allele.speciesFrugal; + alleles[EnumBeeChromosome.SPEED.ordinal()] = Allele.speedNorm; + alleles[EnumBeeChromosome.LIFESPAN.ordinal()] = Allele.lifespanLong; + return alleles; + } + + public static IAllele[] getAustereTemplate() { + IAllele[] alleles = getAustereBranchTemplate(); + alleles[EnumBeeChromosome.SPECIES.ordinal()] = Allele.speciesAustere; + alleles[EnumBeeChromosome.SPEED.ordinal()] = Allele.speedSlowest; + alleles[EnumBeeChromosome.LIFESPAN.ordinal()] = Allele.lifespanLonger; + alleles[EnumBeeChromosome.TEMPERATURE_TOLERANCE.ordinal()] = Allele.toleranceDown2; + alleles[EnumBeeChromosome.EFFECT.ordinal()] = Allele.effectCreeper; + return alleles; + } + + // / TROPICAL BRANCH + public static IAllele[] getTropicalBranchTemplate() { + IAllele[] alleles = getDefaultTemplate(); + alleles[EnumBeeChromosome.TEMPERATURE_TOLERANCE.ordinal()] = Allele.toleranceBoth1; + alleles[EnumBeeChromosome.HUMIDITY_TOLERANCE.ordinal()] = Allele.toleranceDown1; + alleles[EnumBeeChromosome.FLOWER_PROVIDER.ordinal()] = Allele.flowersJungle; + alleles[EnumBeeChromosome.EFFECT.ordinal()] = Allele.effectMiasmic; + return alleles; + } + + public static IAllele[] getTropicalTemplate() { + IAllele[] alleles = getTropicalBranchTemplate(); + alleles[EnumBeeChromosome.SPECIES.ordinal()] = Allele.speciesTropical; + alleles[EnumBeeChromosome.SPEED.ordinal()] = Allele.speedSlower; + alleles[EnumBeeChromosome.LIFESPAN.ordinal()] = Allele.lifespanShort; + return alleles; + } + + public static IAllele[] getExoticTemplate() { + IAllele[] alleles = getTropicalBranchTemplate(); + alleles[EnumBeeChromosome.SPECIES.ordinal()] = Allele.speciesExotic; + alleles[EnumBeeChromosome.SPEED.ordinal()] = Allele.speedNorm; + alleles[EnumBeeChromosome.LIFESPAN.ordinal()] = Allele.lifespanLong; + return alleles; + } + + public static IAllele[] getEdenicTemplate() { + IAllele[] alleles = getTropicalBranchTemplate(); + alleles[EnumBeeChromosome.SPECIES.ordinal()] = Allele.speciesEdenic; + alleles[EnumBeeChromosome.SPEED.ordinal()] = Allele.speedSlowest; + alleles[EnumBeeChromosome.LIFESPAN.ordinal()] = Allele.lifespanLonger; + alleles[EnumBeeChromosome.TEMPERATURE_TOLERANCE.ordinal()] = Allele.toleranceBoth2; + alleles[EnumBeeChromosome.EFFECT.ordinal()] = Allele.effectExploration; + return alleles; + } + + // / END BRANCH + public static IAllele[] getEndBranchTemplate() { + IAllele[] alleles = getDefaultTemplate(); + alleles[EnumBeeChromosome.FERTILITY.ordinal()] = Allele.fertilityLow; + alleles[EnumBeeChromosome.SPEED.ordinal()] = Allele.speedSlower; + alleles[EnumBeeChromosome.LIFESPAN.ordinal()] = Allele.lifespanLonger; + alleles[EnumBeeChromosome.TEMPERATURE_TOLERANCE.ordinal()] = Allele.toleranceUp1; + alleles[EnumBeeChromosome.TERRITORY.ordinal()] = Allele.territoryLarge; + alleles[EnumBeeChromosome.FLOWER_PROVIDER.ordinal()] = Allele.flowersEnd; + alleles[EnumBeeChromosome.NOCTURNAL.ordinal()] = Allele.boolTrue; + alleles[EnumBeeChromosome.EFFECT.ordinal()] = Allele.effectMisanthrope; + return alleles; + } + + public static IAllele[] getEnderTemplate() { + IAllele[] alleles = getEndBranchTemplate(); + alleles[EnumBeeChromosome.SPECIES.ordinal()] = Allele.speciesEnded; + return alleles; + } + + public static IAllele[] getSpectralTemplate() { + IAllele[] alleles = getEndBranchTemplate(); + alleles[EnumBeeChromosome.SPECIES.ordinal()] = Allele.speciesSpectral; + alleles[EnumBeeChromosome.EFFECT.ordinal()] = Allele.effectReanimation; + return alleles; + } + + public static IAllele[] getPhantasmalTemplate() { + IAllele[] alleles = getEndBranchTemplate(); + alleles[EnumBeeChromosome.SPECIES.ordinal()] = Allele.speciesPhantasmal; + alleles[EnumBeeChromosome.SPEED.ordinal()] = Allele.speedSlowest; + alleles[EnumBeeChromosome.LIFESPAN.ordinal()] = Allele.lifespanLongest; + alleles[EnumBeeChromosome.EFFECT.ordinal()] = Allele.effectResurrection; + return alleles; + } + + // / FROZEN BRANCH + public static IAllele[] getFrozenBranchTemplate() { + IAllele[] alleles = getDefaultTemplate(); + alleles[EnumBeeChromosome.TEMPERATURE_TOLERANCE.ordinal()] = Allele.toleranceUp1; + alleles[EnumBeeChromosome.FLOWER_PROVIDER.ordinal()] = Allele.flowersSnow; + alleles[EnumBeeChromosome.EFFECT.ordinal()] = Allele.effectGlacial; + return alleles; + } + + public static IAllele[] getWintryTemplate() { + IAllele[] alleles = getFrozenBranchTemplate(); + alleles[EnumBeeChromosome.SPECIES.ordinal()] = Allele.speciesWintry; + alleles[EnumBeeChromosome.SPEED.ordinal()] = Allele.speedSlower; + alleles[EnumBeeChromosome.LIFESPAN.ordinal()] = Allele.lifespanShort; + alleles[EnumBeeChromosome.FERTILITY.ordinal()] = Allele.fertilityMaximum; + return alleles; + } + + public static IAllele[] getIcyTemplate() { + IAllele[] alleles = getFrozenBranchTemplate(); + alleles[EnumBeeChromosome.SPECIES.ordinal()] = Allele.speciesIcy; + alleles[EnumBeeChromosome.SPEED.ordinal()] = Allele.speedSlow; + alleles[EnumBeeChromosome.LIFESPAN.ordinal()] = Allele.lifespanShort; + return alleles; + } + + public static IAllele[] getGlacialTemplate() { + IAllele[] alleles = getFrozenBranchTemplate(); + alleles[EnumBeeChromosome.SPECIES.ordinal()] = Allele.speciesGlacial; + alleles[EnumBeeChromosome.SPEED.ordinal()] = Allele.speedSlower; + alleles[EnumBeeChromosome.LIFESPAN.ordinal()] = Allele.lifespanShort; + return alleles; + } + + // / VENGEFUL BRANCH + public static IAllele[] getVengefulBranchTemplate() { + IAllele[] alleles = getDefaultTemplate(); + alleles[EnumBeeChromosome.TERRITORY.ordinal()] = Allele.territoryLargest; + alleles[EnumBeeChromosome.EFFECT.ordinal()] = Allele.effectRadioactive; + return alleles; + } + + public static IAllele[] getVindictiveTemplate() { + IAllele[] alleles = getVengefulBranchTemplate(); + alleles[EnumBeeChromosome.SPECIES.ordinal()] = Allele.speciesVindictive; + alleles[EnumBeeChromosome.SPEED.ordinal()] = Allele.speedSlower; + alleles[EnumBeeChromosome.LIFESPAN.ordinal()] = Allele.lifespanNormal; + return alleles; + } + + public static IAllele[] getVengefulTemplate() { + IAllele[] alleles = getVengefulBranchTemplate(); + alleles[EnumBeeChromosome.SPECIES.ordinal()] = Allele.speciesVengeful; + alleles[EnumBeeChromosome.SPEED.ordinal()] = Allele.speedNorm; + alleles[EnumBeeChromosome.LIFESPAN.ordinal()] = Allele.lifespanLonger; + return alleles; + } + + public static IAllele[] getAvengingTemplate() { + IAllele[] alleles = getVengefulBranchTemplate(); + alleles[EnumBeeChromosome.SPECIES.ordinal()] = Allele.speciesAvenging; + alleles[EnumBeeChromosome.SPEED.ordinal()] = Allele.speedSlowest; + alleles[EnumBeeChromosome.LIFESPAN.ordinal()] = Allele.lifespanLongest; + return alleles; + } + + // / REDDENED BRANCH + public static IAllele[] getReddenedBranchTemplate() { + IAllele[] alleles = getDefaultTemplate(); + alleles[EnumBeeChromosome.SPEED.ordinal()] = Allele.speedSlow; + alleles[EnumBeeChromosome.LIFESPAN.ordinal()] = Allele.lifespanNormal; + alleles[EnumBeeChromosome.TEMPERATURE_TOLERANCE.ordinal()] = Allele.toleranceBoth2; + alleles[EnumBeeChromosome.HUMIDITY_TOLERANCE.ordinal()] = Allele.toleranceBoth1; + return alleles; + } + + public static IAllele[] getDarkenedTemplate() { + IAllele[] alleles = getDefaultTemplate(); + alleles[EnumBeeChromosome.SPECIES.ordinal()] = Allele.speciesDarkened; + return alleles; + } + + public static IAllele[] getReddenedTemplate() { + IAllele[] alleles = getDefaultTemplate(); + alleles[EnumBeeChromosome.SPECIES.ordinal()] = Allele.speciesReddened; + return alleles; + } + + public static IAllele[] getOmegaTemplate() { + IAllele[] alleles = getDefaultTemplate(); + alleles[EnumBeeChromosome.SPECIES.ordinal()] = Allele.speciesOmega; + return alleles; + } + + // / FESTIVE BRANCH + public static IAllele[] getFestiveBranchTemplate() { + IAllele[] alleles = getDefaultTemplate(); + alleles[EnumBeeChromosome.SPEED.ordinal()] = Allele.speedSlower; + alleles[EnumBeeChromosome.TEMPERATURE_TOLERANCE.ordinal()] = Allele.toleranceBoth2; + alleles[EnumBeeChromosome.HUMIDITY_TOLERANCE.ordinal()] = Allele.toleranceBoth1; + alleles[EnumBeeChromosome.LIFESPAN.ordinal()] = Allele.lifespanNormal; + return alleles; + } + + public static IAllele[] getLeporineTemplate() { + IAllele[] alleles = getFestiveBranchTemplate(); + alleles[EnumBeeChromosome.SPECIES.ordinal()] = Allele.speciesLeporine; + alleles[EnumBeeChromosome.EFFECT.ordinal()] = Allele.effectFestiveEaster; + return alleles; + } + + public static IAllele[] getMerryTemplate() { + IAllele[] alleles = getFestiveBranchTemplate(); + alleles[EnumBeeChromosome.SPECIES.ordinal()] = Allele.speciesMerry; + alleles[EnumBeeChromosome.NOCTURNAL.ordinal()] = Allele.boolTrue; + alleles[EnumBeeChromosome.EFFECT.ordinal()] = Allele.effectSnowing; + return alleles; + } + + public static IAllele[] getTipsyTemplate() { + IAllele[] alleles = getFestiveBranchTemplate(); + alleles[EnumBeeChromosome.SPECIES.ordinal()] = Allele.speciesTipsy; + alleles[EnumBeeChromosome.NOCTURNAL.ordinal()] = Allele.boolTrue; + alleles[EnumBeeChromosome.EFFECT.ordinal()] = Allele.effectDrunkard; + return alleles; + } + + public static IAllele[] getTrickyTemplate() { + IAllele[] alleles = getFestiveBranchTemplate(); + alleles[EnumBeeChromosome.SPECIES.ordinal()] = Allele.speciesTricky; + alleles[EnumBeeChromosome.NOCTURNAL.ordinal()] = Allele.boolTrue; + alleles[EnumBeeChromosome.TOLERANT_FLYER.ordinal()] = Allele.boolTrue; + alleles[EnumBeeChromosome.FLOWER_PROVIDER.ordinal()] = Allele.flowersGourd; + return alleles; + } + + // / AGRARIAN BRANCH + public static IAllele[] getAgrarianBranchTemplate() { + IAllele[] alleles = getDefaultTemplate(); + alleles[EnumBeeChromosome.SPEED.ordinal()] = Allele.speedSlower; + alleles[EnumBeeChromosome.LIFESPAN.ordinal()] = Allele.lifespanShorter; + alleles[EnumBeeChromosome.FLOWER_PROVIDER.ordinal()] = Allele.flowersWheat; + alleles[EnumBeeChromosome.FLOWERING.ordinal()] = Allele.floweringFaster; + return alleles; + } + + public static IAllele[] getRuralTemplate() { + IAllele[] alleles = getAgrarianBranchTemplate(); + alleles[EnumBeeChromosome.SPECIES.ordinal()] = Allele.speciesRural; + return alleles; + } + + // / BOGGY BRANCH + public static IAllele[] getBoggyBranchTemplate() { + IAllele[] alleles = getDefaultTemplate(); + alleles[EnumBeeChromosome.FLOWER_PROVIDER.ordinal()] = Allele.flowersMushrooms; + alleles[EnumBeeChromosome.FLOWERING.ordinal()] = Allele.floweringSlower; + alleles[EnumBeeChromosome.HUMIDITY_TOLERANCE.ordinal()] = Allele.toleranceBoth1; + alleles[EnumBeeChromosome.TEMPERATURE_TOLERANCE.ordinal()] = Allele.toleranceBoth1; + return alleles; + } + + public static IAllele[] getMarshyTemplate() { + IAllele[] alleles = getBoggyBranchTemplate(); + alleles[EnumBeeChromosome.SPECIES.ordinal()] = Allele.speciesMarshy; + return alleles; + } + + /* MONASTIC BRANCH */ + public static IAllele[] getMonasticBranchTemplate() { + IAllele[] alleles = getDefaultTemplate(); + alleles[EnumBeeChromosome.SPEED.ordinal()] = Allele.speedSlower; + alleles[EnumBeeChromosome.LIFESPAN.ordinal()] = Allele.lifespanLong; + alleles[EnumBeeChromosome.FERTILITY.ordinal()] = Allele.fertilityLow; + alleles[EnumBeeChromosome.FLOWERING.ordinal()] = Allele.floweringFaster; + alleles[EnumBeeChromosome.HUMIDITY_TOLERANCE.ordinal()] = Allele.toleranceBoth1; + alleles[EnumBeeChromosome.TEMPERATURE_TOLERANCE.ordinal()] = Allele.toleranceBoth1; + alleles[EnumBeeChromosome.CAVE_DWELLING.ordinal()] = Allele.boolTrue; + alleles[EnumBeeChromosome.FLOWER_PROVIDER.ordinal()] = Allele.flowersWheat; + return alleles; + } + + public static IAllele[] getMonasticTemplate() { + IAllele[] alleles = getMonasticBranchTemplate(); + alleles[EnumBeeChromosome.SPECIES.ordinal()] = Allele.speciesMonastic; + return alleles; + } + + public static IAllele[] getSecludedTemplate() { + IAllele[] alleles = getMonasticBranchTemplate(); + alleles[EnumBeeChromosome.SPECIES.ordinal()] = Allele.speciesSecluded; + alleles[EnumBeeChromosome.FLOWERING.ordinal()] = Allele.floweringFastest; + return alleles; + } + + public static IAllele[] getHermiticTemplate() { + IAllele[] alleles = getMonasticBranchTemplate(); + alleles[EnumBeeChromosome.SPECIES.ordinal()] = Allele.speciesHermitic; + alleles[EnumBeeChromosome.FLOWERING.ordinal()] = Allele.floweringFastest; + alleles[EnumBeeChromosome.EFFECT.ordinal()] = Allele.effectRepulsion; + return alleles; + } + +} diff --git a/forestry_common/apiculture/forestry/apiculture/genetics/BeekeepingMode.java b/forestry_common/apiculture/forestry/apiculture/genetics/BeekeepingMode.java new file mode 100755 index 000000000..a46143578 --- /dev/null +++ b/forestry_common/apiculture/forestry/apiculture/genetics/BeekeepingMode.java @@ -0,0 +1,174 @@ +/******************************************************************************* + * Copyright 2011-2014 by SirSengir + * + * This work is licensed under a Creative Commons Attribution-NonCommercial-NoDerivs 3.0 Unported License. + * + * To view a copy of this license, visit http://creativecommons.org/licenses/by-nc-nd/3.0/. + ******************************************************************************/ +package forestry.apiculture.genetics; + +import java.util.ArrayList; +import java.util.Locale; +import java.util.Random; + +import net.minecraft.world.World; + +import forestry.api.apiculture.IBee; +import forestry.api.apiculture.IBeeGenome; +import forestry.api.apiculture.IBeeHousing; +import forestry.api.apiculture.IBeekeepingMode; + +public class BeekeepingMode implements IBeekeepingMode { + + public static IBeekeepingMode easy = new BeekeepingMode("EASY", 2.0f, 1.0f, 1.0f, false, false); + public static IBeekeepingMode normal = new BeekeepingMode("NORMAL", 1.0f, 1.0f, 1.0f, false, true); + public static IBeekeepingMode hard = new BeekeepingMode("HARD", 0.75f, 1.5f, 1.0f, false, true); + public static IBeekeepingMode hardcore = new BeekeepingMode("HARDCORE", 0.5f, 5.0f, 0.8f, true, true); + public static IBeekeepingMode insane = new BeekeepingMode("INSANE", 0.2f, 10.0f, 0.6f, true, true); + + final Random rand; + final String name; + final float mutationModifier; + final float lifespanModifier; + final float speedModifier; + final boolean reducesFertility; + final boolean canFatigue; + + public BeekeepingMode(String name, float mutationModifier, float lifespanModifier, float speedModifier, boolean reducesFertility, boolean canFatigue) { + this.rand = new Random(); + this.name = name; + this.mutationModifier = mutationModifier; + this.lifespanModifier = lifespanModifier; + this.speedModifier = speedModifier; + this.reducesFertility = reducesFertility; + this.canFatigue = canFatigue; + } + + @Override + public String getName() { + return this.name; + } + + @Override + public ArrayList getDescription() { + ArrayList ret = new ArrayList(); + ret.add("beemode." + name.toLowerCase(Locale.ENGLISH) + ".desc"); + return ret; + } + + @Override + public float getWearModifier() { + return 1.0f; + } + + @Override + public float getMutationModifier(IBeeGenome genome, IBeeGenome mate, float currentModifier) { + return this.mutationModifier; + } + + @Override + public float getLifespanModifier(IBeeGenome genome, IBeeGenome mate, float currentModifier) { + return this.lifespanModifier; + } + + @Override + public float getProductionModifier(IBeeGenome genome, float currentModifier) { + return this.speedModifier; + } + + @Override + public float getTerritoryModifier(IBeeGenome genome, float currentModifier) { + return 1.0f; + } + + @Override + public float getFloweringModifier(IBeeGenome genome, float currentModifier) { + return 1.0f; + } + + @Override + public float getGeneticDecay(IBeeGenome genome, float currentModifier) { + return 1.0f; + } + + @Override + public int getFinalFertility(IBee queen, World world, int x, int y, int z) { + int toCreate = queen.getGenome().getFertility(); + + if (reducesFertility) + toCreate = new Random().nextInt(toCreate); + + return toCreate; + } + + @Override + public boolean isFatigued(IBee queen, IBeeHousing housing) { + if (!canFatigue) + return false; + + if (queen.isNatural()) + return false; + + if (queen.getGeneration() > 96 + rand.nextInt(6) + rand.nextInt(6) && + rand.nextFloat() < 0.02f * housing.getGeneticDecay(queen.getGenome(), 1f)) + return true; + + return false; + } + + @Override + public boolean isOverworked(IBee queen, IBeeHousing housing) { + float productionModifier = housing.getProductionModifier(queen.getGenome(), 1f); + if(productionModifier > 16) { + if(housing.getWorld().rand.nextFloat()*100 < 0.01 * ((productionModifier*productionModifier) - 100)) + return true; + } + + return false; + } + + @Override + public boolean isDegenerating(IBee queen, IBee offspring, IBeeHousing housing) { + float mutationModifier = housing.getMutationModifier(queen.getGenome(), queen.getMate(), 1.0f); + if(mutationModifier > 10) { + if(housing.getWorld().rand.nextFloat()*100 < 0.4 * ((mutationModifier*mutationModifier) - 100)) + return true; + } + + return false; + } + + @Override + public boolean isNaturalOffspring(IBee queen) { + if (!queen.isNatural()) + return false; + + return true; + } + + @Override + public boolean mayMultiplyPrincess(IBee queen) { + return true; + } + + @Override + public boolean isSealed() { + return false; + } + + @Override + public boolean isSelfLighted() { + return false; + } + + @Override + public boolean isSunlightSimulated() { + return false; + } + + @Override + public boolean isHellish() { + return false; + } + +} diff --git a/forestry_common/apiculture/forestry/apiculture/genetics/BranchBees.java b/forestry_common/apiculture/forestry/apiculture/genetics/BranchBees.java new file mode 100755 index 000000000..eea9dc5e1 --- /dev/null +++ b/forestry_common/apiculture/forestry/apiculture/genetics/BranchBees.java @@ -0,0 +1,18 @@ +/******************************************************************************* + * Copyright 2011-2014 by SirSengir + * + * This work is licensed under a Creative Commons Attribution-NonCommercial-NoDerivs 3.0 Unported License. + * + * To view a copy of this license, visit http://creativecommons.org/licenses/by-nc-nd/3.0/. + ******************************************************************************/ +package forestry.apiculture.genetics; + +import forestry.core.genetics.Branch; + +public class BranchBees extends Branch { + + public BranchBees(String uid, String scientific) { + super("bees." + uid, scientific); + } + +} diff --git a/forestry_common/apiculture/forestry/apiculture/genetics/HiveDrop.java b/forestry_common/apiculture/forestry/apiculture/genetics/HiveDrop.java new file mode 100755 index 000000000..366bfb00f --- /dev/null +++ b/forestry_common/apiculture/forestry/apiculture/genetics/HiveDrop.java @@ -0,0 +1,75 @@ +/******************************************************************************* + * Copyright 2011-2014 by SirSengir + * + * This work is licensed under a Creative Commons Attribution-NonCommercial-NoDerivs 3.0 Unported License. + * + * To view a copy of this license, visit http://creativecommons.org/licenses/by-nc-nd/3.0/. + ******************************************************************************/ +package forestry.apiculture.genetics; + +import java.util.ArrayList; + +import net.minecraft.item.ItemStack; +import net.minecraft.world.World; + +import forestry.api.apiculture.EnumBeeType; +import forestry.api.apiculture.IBee; +import forestry.api.apiculture.IHiveDrop; +import forestry.api.genetics.IAllele; +import forestry.plugins.PluginApiculture; + +public class HiveDrop implements IHiveDrop { + + private IAllele[] template; + private ArrayList additional = new ArrayList(); + private int chance; + private float ignobleShare = 0.0f; + + public HiveDrop(IAllele[] template, ItemStack[] bonus, int chance) { + this.template = template; + this.chance = chance; + + for (ItemStack stack : bonus) + this.additional.add(stack); + } + + public HiveDrop setIgnobleShare(float share) { + this.ignobleShare = share; + return this; + } + + private IBee createBee(World world) { + IBee bee = PluginApiculture.beeInterface.getBee(world, PluginApiculture.beeInterface.templateAsGenome(template)); + if(world.rand.nextFloat() < ignobleShare) + bee.setIsNatural(false); + return bee; + } + + @Override + public ItemStack getPrincess(World world, int x, int y, int z, int fortune) { + return PluginApiculture.beeInterface.getMemberStack(createBee(world), EnumBeeType.PRINCESS.ordinal()); + } + + @Override + public ArrayList getDrones(World world, int x, int y, int z, int fortune) { + ArrayList ret = new ArrayList(); + ret.add(PluginApiculture.beeInterface.getMemberStack(createBee(world), + EnumBeeType.DRONE.ordinal())); + return ret; + } + + @Override + public ArrayList getAdditional(World world, int x, int y, int z, int fortune) { + ArrayList ret = new ArrayList(); + for (ItemStack stack : additional) + ret.add(stack.copy()); + + return ret; + } + + @Override + public int getChance(World world, int x, int y, int z) { + return chance; + } + +} diff --git a/forestry_common/apiculture/forestry/apiculture/genetics/IJubilanceProvider.java b/forestry_common/apiculture/forestry/apiculture/genetics/IJubilanceProvider.java new file mode 100755 index 000000000..c10e036ae --- /dev/null +++ b/forestry_common/apiculture/forestry/apiculture/genetics/IJubilanceProvider.java @@ -0,0 +1,16 @@ +/******************************************************************************* + * Copyright 2011-2014 by SirSengir + * + * This work is licensed under a Creative Commons Attribution-NonCommercial-NoDerivs 3.0 Unported License. + * + * To view a copy of this license, visit http://creativecommons.org/licenses/by-nc-nd/3.0/. + ******************************************************************************/ +package forestry.apiculture.genetics; + +import forestry.api.apiculture.IAlleleBeeSpecies; +import forestry.api.apiculture.IBeeGenome; +import forestry.api.apiculture.IBeeHousing; + +public interface IJubilanceProvider { + boolean isJubilant(IAlleleBeeSpecies species, IBeeGenome genome, IBeeHousing housing); +} diff --git a/forestry_common/apiculture/forestry/apiculture/genetics/JubilanceDefault.java b/forestry_common/apiculture/forestry/apiculture/genetics/JubilanceDefault.java new file mode 100755 index 000000000..714fe947a --- /dev/null +++ b/forestry_common/apiculture/forestry/apiculture/genetics/JubilanceDefault.java @@ -0,0 +1,44 @@ +/******************************************************************************* + * Copyright 2011-2014 by SirSengir + * + * This work is licensed under a Creative Commons Attribution-NonCommercial-NoDerivs 3.0 Unported License. + * + * To view a copy of this license, visit http://creativecommons.org/licenses/by-nc-nd/3.0/. + ******************************************************************************/ +package forestry.apiculture.genetics; + +import net.minecraft.util.AxisAlignedBB; +import net.minecraft.world.biome.BiomeGenBase; + +import forestry.api.apiculture.IAlleleBeeSpecies; +import forestry.api.apiculture.IBeeGenome; +import forestry.api.apiculture.IBeeHousing; +import forestry.api.core.EnumHumidity; +import forestry.api.core.EnumTemperature; +import forestry.core.utils.Vect; + +public class JubilanceDefault implements IJubilanceProvider { + + @Override + public boolean isJubilant(IAlleleBeeSpecies species, IBeeGenome genome, IBeeHousing housing) { + BiomeGenBase biome = BiomeGenBase.getBiome(housing.getBiomeId()); + + if (EnumTemperature.getFromValue(biome.temperature) != species.getTemperature() || + EnumHumidity.getFromValue(biome.rainfall) != species.getHumidity()) + return false; + + return true; + } + + protected AxisAlignedBB getBounding(IBeeGenome genome, IBeeHousing housing, float modifier) { + int[] areaAr = genome.getTerritory(); + Vect area = new Vect(areaAr[0], areaAr[1], areaAr[2]).multiply(modifier); + Vect offset = new Vect(-Math.round(area.x / 2), -Math.round(area.y / 2), -Math.round(area.z / 2)); + + Vect min = new Vect(housing.getXCoord() + offset.x, housing.getYCoord() + offset.y, housing.getZCoord() + offset.z); + Vect max = new Vect(housing.getXCoord() + offset.x + area.x, housing.getYCoord() + offset.y + area.y, housing.getZCoord() + offset.z + area.z); + + return AxisAlignedBB.getAABBPool().getAABB(min.x, min.y, min.z, max.x, max.y, max.z); + } + +} diff --git a/forestry_common/apiculture/forestry/apiculture/genetics/JubilanceNone.java b/forestry_common/apiculture/forestry/apiculture/genetics/JubilanceNone.java new file mode 100755 index 000000000..3419bd953 --- /dev/null +++ b/forestry_common/apiculture/forestry/apiculture/genetics/JubilanceNone.java @@ -0,0 +1,21 @@ +/******************************************************************************* + * Copyright 2011-2014 by SirSengir + * + * This work is licensed under a Creative Commons Attribution-NonCommercial-NoDerivs 3.0 Unported License. + * + * To view a copy of this license, visit http://creativecommons.org/licenses/by-nc-nd/3.0/. + ******************************************************************************/ +package forestry.apiculture.genetics; + +import forestry.api.apiculture.IAlleleBeeSpecies; +import forestry.api.apiculture.IBeeGenome; +import forestry.api.apiculture.IBeeHousing; + +public class JubilanceNone implements IJubilanceProvider { + + @Override + public boolean isJubilant(IAlleleBeeSpecies species, IBeeGenome genome, IBeeHousing housing) { + return false; + } + +} diff --git a/forestry_common/apiculture/forestry/apiculture/genetics/JubilanceProviderHermit.java b/forestry_common/apiculture/forestry/apiculture/genetics/JubilanceProviderHermit.java new file mode 100755 index 000000000..ba15cea19 --- /dev/null +++ b/forestry_common/apiculture/forestry/apiculture/genetics/JubilanceProviderHermit.java @@ -0,0 +1,36 @@ +/******************************************************************************* + * Copyright 2011-2014 by SirSengir + * + * This work is licensed under a Creative Commons Attribution-NonCommercial-NoDerivs 3.0 Unported License. + * + * To view a copy of this license, visit http://creativecommons.org/licenses/by-nc-nd/3.0/. + ******************************************************************************/ +package forestry.apiculture.genetics; + +import java.util.List; + +import net.minecraft.entity.EntityLiving; +import net.minecraft.util.AxisAlignedBB; + +import forestry.api.apiculture.IAlleleBeeSpecies; +import forestry.api.apiculture.IBeeGenome; +import forestry.api.apiculture.IBeeHousing; + +/** + * Hermits will not produce if there are any other living creatures nearby. + */ +public class JubilanceProviderHermit extends JubilanceDefault { + + @Override + public boolean isJubilant(IAlleleBeeSpecies species, IBeeGenome genome, IBeeHousing housing) { + AxisAlignedBB bounding = this.getBounding(genome, housing, 1.0f); + + @SuppressWarnings("rawtypes") + List list = housing.getWorld().getEntitiesWithinAABB(EntityLiving.class, bounding); + if (list.size() > 0) + return false; + + return true; + } + +} diff --git a/forestry_common/apiculture/forestry/apiculture/genetics/JubilanceReqRes.java b/forestry_common/apiculture/forestry/apiculture/genetics/JubilanceReqRes.java new file mode 100755 index 000000000..4f2ee818e --- /dev/null +++ b/forestry_common/apiculture/forestry/apiculture/genetics/JubilanceReqRes.java @@ -0,0 +1,40 @@ +/******************************************************************************* + * Copyright 2011-2014 by SirSengir + * + * This work is licensed under a Creative Commons Attribution-NonCommercial-NoDerivs 3.0 Unported License. + * + * To view a copy of this license, visit http://creativecommons.org/licenses/by-nc-nd/3.0/. + ******************************************************************************/ +package forestry.apiculture.genetics; + +import net.minecraft.block.Block; +import net.minecraft.item.ItemStack; + +import forestry.api.apiculture.IAlleleBeeSpecies; +import forestry.api.apiculture.IBeeGenome; +import forestry.api.apiculture.IBeeHousing; +import forestry.core.utils.StackUtils; + +public class JubilanceReqRes implements IJubilanceProvider { + + private final ItemStack blockRequired; + + public JubilanceReqRes(ItemStack blockRequired) { + this.blockRequired = blockRequired; + } + + @Override + public boolean isJubilant(IAlleleBeeSpecies species, IBeeGenome genome, IBeeHousing housing) { + + if (blockRequired == null) + return true; + + Block block = housing.getWorld().getBlock(housing.getXCoord(), housing.getYCoord() - 1, housing.getZCoord()); + int meta = housing.getWorld().getBlockMetadata(housing.getXCoord(), housing.getYCoord() - 1, housing.getZCoord()); + if (StackUtils.equals(block, blockRequired) && meta == blockRequired.getItemDamage()) + return true; + else + return false; + } + +} diff --git a/forestry_common/apiculture/forestry/apiculture/genetics/MutationEMC.java b/forestry_common/apiculture/forestry/apiculture/genetics/MutationEMC.java new file mode 100755 index 000000000..fa3ddaddc --- /dev/null +++ b/forestry_common/apiculture/forestry/apiculture/genetics/MutationEMC.java @@ -0,0 +1,93 @@ +/******************************************************************************* + * Copyright 2011-2014 by SirSengir + * + * This work is licensed under a Creative Commons Attribution-NonCommercial-NoDerivs 3.0 Unported License. + * + * To view a copy of this license, visit http://creativecommons.org/licenses/by-nc-nd/3.0/. + ******************************************************************************/ +package forestry.apiculture.genetics; + +import java.lang.reflect.Field; + +import net.minecraft.item.ItemStack; +import net.minecraft.tileentity.TileEntity; +import net.minecraft.world.World; + +import forestry.api.apiculture.IBeeHousing; +import forestry.api.genetics.IAllele; +import forestry.api.genetics.IGenome; +import forestry.core.proxy.Proxies; +import forestry.core.utils.Vect; + +public class MutationEMC extends MutationReqRes { + + int emcRequired = 0; + Class condenserClass; + Field emcField; + + public MutationEMC(IAllele allele0, IAllele allele1, IAllele[] template, int chance, ItemStack blockRequired, Class condenserClass, Field emcField, + int emcRequired) { + super(allele0, allele1, template, chance, blockRequired); + + this.condenserClass = condenserClass; + this.emcField = emcField; + this.emcRequired = emcRequired; + } + + @Override + public float getChance(IBeeHousing housing, IAllele allele0, IAllele allele1, IGenome genome0, IGenome genome1) { + float chance = super.getChance(housing, allele0, allele1, genome0, genome1); + + // If we don't have any chance, return at once. + if (chance <= 0) + return 0; + + if (emcRequired <= 0) + return chance; + + World world = housing.getWorld(); + + Vect[] possibleTargets = new Vect[] { new Vect(housing.getXCoord() + 1, housing.getYCoord(), housing.getZCoord()), + new Vect(housing.getXCoord() - 1, housing.getYCoord(), housing.getZCoord()), + new Vect(housing.getXCoord(), housing.getYCoord(), housing.getZCoord() + 1), + new Vect(housing.getXCoord(), housing.getYCoord(), housing.getZCoord() - 1) }; + + for (Vect target : possibleTargets) { + if (!world.blockExists(target.x, target.y, target.z)) + continue; + + TileEntity entity = world.getTileEntity(target.x, target.y, target.z); + if (entity == null) + continue; + + if (!condenserClass.isInstance(entity)) { + Proxies.log.warning("Did not find a relay at " + target.toString()); + continue; + } + + int emc = 0; + try { + emc = emcField.getInt(entity); + } catch (Exception ex) { + Proxies.log.warning("Failed to fetch EMC information."); + } + + if (emc < emcRequired * 80) + continue; + + boolean removedEMC = false; + try { + emcField.set(entity, emc - (emcRequired * 80)); + removedEMC = true; + } catch (Exception ex) { + Proxies.log.warning("Failed to set EMC information."); + } + + if (removedEMC) + return chance; + + } + + return 0; + } +} diff --git a/forestry_common/apiculture/forestry/apiculture/genetics/MutationReqRes.java b/forestry_common/apiculture/forestry/apiculture/genetics/MutationReqRes.java new file mode 100755 index 000000000..19e4aa3ec --- /dev/null +++ b/forestry_common/apiculture/forestry/apiculture/genetics/MutationReqRes.java @@ -0,0 +1,47 @@ +/******************************************************************************* + * Copyright 2011-2014 by SirSengir + * + * This work is licensed under a Creative Commons Attribution-NonCommercial-NoDerivs 3.0 Unported License. + * + * To view a copy of this license, visit http://creativecommons.org/licenses/by-nc-nd/3.0/. + ******************************************************************************/ +package forestry.apiculture.genetics; + +import net.minecraft.block.Block; +import net.minecraft.item.ItemStack; +import net.minecraft.world.World; + +import forestry.api.apiculture.IBeeHousing; +import forestry.api.genetics.IAllele; +import forestry.api.genetics.IGenome; +import forestry.core.utils.StackUtils; + +public class MutationReqRes extends BeeMutation { + + private final ItemStack blockRequired; + + public MutationReqRes(IAllele allele0, IAllele allele1, IAllele[] template, int chance, ItemStack blockRequired) { + super(allele0, allele1, template, chance); + this.blockRequired = blockRequired; + } + + @Override + public float getChance(IBeeHousing housing, IAllele allele0, IAllele allele1, IGenome genome0, IGenome genome1) { + float chance = super.getChance(housing, allele0, allele1, genome0, genome1); + + // If we have no chance anyway, we don't need to check. + if (chance <= 0) + return 0; + + World world = housing.getWorld(); + if (blockRequired == null) + return chance; + + Block block = world.getBlock(housing.getXCoord(), housing.getYCoord() - 1, housing.getZCoord()); + int meta = world.getBlockMetadata(housing.getXCoord(), housing.getYCoord() - 1, housing.getZCoord()); + if (StackUtils.equals(block, blockRequired) && meta == blockRequired.getItemDamage()) + return chance; + else + return 0; + } +} diff --git a/forestry_common/apiculture/forestry/apiculture/genetics/MutationTimeLimited.java b/forestry_common/apiculture/forestry/apiculture/genetics/MutationTimeLimited.java new file mode 100755 index 000000000..909e65c7a --- /dev/null +++ b/forestry_common/apiculture/forestry/apiculture/genetics/MutationTimeLimited.java @@ -0,0 +1,137 @@ +/******************************************************************************* + * Copyright 2011-2014 by SirSengir + * + * This work is licensed under a Creative Commons Attribution-NonCommercial-NoDerivs 3.0 Unported License. + * + * To view a copy of this license, visit http://creativecommons.org/licenses/by-nc-nd/3.0/. + ******************************************************************************/ +package forestry.apiculture.genetics; + +import java.util.Calendar; + +import forestry.api.apiculture.IBeeHousing; +import forestry.api.genetics.IAllele; +import forestry.api.genetics.IGenome; + +public class MutationTimeLimited extends BeeMutation { + + /** + * Fed up with Date and Calendar and their shinenigans + */ + public static class DayMonth { + + public int day; + public int month; + + public DayMonth() { + this.day = Calendar.getInstance().get(Calendar.DAY_OF_MONTH); + this.month = Calendar.getInstance().get(Calendar.MONTH) + 1; + } + + public DayMonth(int day, int month) { + this.day = day; + this.month = month; + } + + public boolean between(DayMonth start, DayMonth end) { + if (equals(start) || equals(end)) + return true; + if (start.month > end.month) + return after(start) || before(end); + return after(start) && before(end); + } + + public boolean before(DayMonth other) { + + if (other.month > this.month) + return true; + + if (other.month < this.month) + return false; + + return this.day < other.day; + } + + public boolean after(DayMonth other) { + + if (other.month < this.month) + return true; + + if (other.month > this.month) + return false; + + return this.day > other.day; + } + + @Override + public int hashCode() { + int hash = 7; + hash = 89 * hash + this.day; + hash = 89 * hash + this.month; + return hash; + } + + @Override + public boolean equals(Object obj) { + if (obj == null) + return false; + if (getClass() != obj.getClass()) + return false; + final DayMonth other = (DayMonth) obj; + if (this.day != other.day) + return false; + if (this.month != other.month) + return false; + return true; + } + + @Override + public String toString() { + return day + "." + month; + } + } + DayMonth start; + DayMonth end; + + public MutationTimeLimited(IAllele allele0, IAllele allele1, IAllele[] template, int chance, DayMonth start) { + this(allele0, allele1, template, chance, start, null); + } + + public MutationTimeLimited(IAllele allele0, IAllele allele1, IAllele[] template, int chance, DayMonth start, DayMonth end) { + super(allele0, allele1, template, chance); + this.start = start; + this.end = end; + } + + @Override + public float getChance(IBeeHousing housing, IAllele allele0, IAllele allele1, IGenome genome0, IGenome genome1) { + float chance = super.getChance(housing, allele0, allele1, genome0, genome1); + + if (chance == 0) + return 0; + + if (start == null && end == null) + return chance; + + DayMonth now = new DayMonth(); + + // If we are equal to start day, return chance. + if (Calendar.getInstance().get(Calendar.DAY_OF_MONTH) == start.day && Calendar.getInstance().get(Calendar.MONTH) + 1 == start.month) + return chance; + + // Still here but not time span? No mutation! + if (end == null) + return 0; + + // Equal to end date, return chance. + if (Calendar.getInstance().get(Calendar.DAY_OF_MONTH) == end.day && Calendar.getInstance().get(Calendar.MONTH) + 1 == end.month) + return chance; + + // Still a chance we are in between + if (now.between(start, end)) + return chance; + + // Now we finally failed. + return 0; + } +} diff --git a/forestry_common/apiculture/forestry/apiculture/gui/ContainerAlveary.java b/forestry_common/apiculture/forestry/apiculture/gui/ContainerAlveary.java new file mode 100755 index 000000000..1d126c935 --- /dev/null +++ b/forestry_common/apiculture/forestry/apiculture/gui/ContainerAlveary.java @@ -0,0 +1,66 @@ +/******************************************************************************* + * Copyright 2011-2014 by SirSengir + * + * This work is licensed under a Creative Commons Attribution-NonCommercial-NoDerivs 3.0 Unported License. + * + * To view a copy of this license, visit http://creativecommons.org/licenses/by-nc-nd/3.0/. + ******************************************************************************/ +package forestry.apiculture.gui; + +import net.minecraft.entity.player.InventoryPlayer; +import net.minecraft.inventory.ICrafting; +import net.minecraft.inventory.Slot; + +import forestry.apiculture.gadgets.TileAlvearyPlain; +import forestry.core.config.ForestryItem; +import forestry.core.gui.ContainerForestry; +import forestry.core.gui.slots.SlotClosed; +import forestry.core.gui.slots.SlotCustom; + +public class ContainerAlveary extends ContainerForestry { + + private TileAlvearyPlain tile; + + public ContainerAlveary(InventoryPlayer player, TileAlvearyPlain tile) { + super(tile); + + this.tile = tile; + tile.sendNetworkUpdate(); + + // Queen/Princess + this.addSlot(new SlotCustom(tile, TileAlvearyPlain.SLOT_QUEEN, 29, 39, new Object[] { ForestryItem.beePrincessGE, ForestryItem.beeQueenGE })); + + // Drone + this.addSlot(new SlotCustom(tile, TileAlvearyPlain.SLOT_DRONE, 29, 65, new Object[] { ForestryItem.beeDroneGE })); + + // Product Inventory + this.addSlot(new SlotClosed(tile, 2, 116, 52)); + this.addSlot(new SlotClosed(tile, 3, 137, 39)); + this.addSlot(new SlotClosed(tile, 4, 137, 65)); + this.addSlot(new SlotClosed(tile, 5, 116, 78)); + this.addSlot(new SlotClosed(tile, 6, 95, 65)); + this.addSlot(new SlotClosed(tile, 7, 95, 39)); + this.addSlot(new SlotClosed(tile, 8, 116, 26)); + + // Player inventory + for (int i = 0; i < 3; i++) + for (int j = 0; j < 9; j++) + addSlot(new Slot(player, j + i * 9 + 9, 8 + j * 18, 108 + i * 18)); + // Player hotbar + for (int i = 0; i < 9; i++) + addSlot(new Slot(player, i, 8 + i * 18, 166)); + } + + @Override + public void updateProgressBar(int i, int j) { + tile.getGUINetworkData(i, j); + } + + @Override + public void detectAndSendChanges() { + super.detectAndSendChanges(); + for (int i = 0; i < crafters.size(); i++) + tile.sendGUINetworkData(this, (ICrafting) crafters.get(i)); + } + +} diff --git a/forestry_common/apiculture/forestry/apiculture/gui/ContainerAlvearyHygroregulator.java b/forestry_common/apiculture/forestry/apiculture/gui/ContainerAlvearyHygroregulator.java new file mode 100755 index 000000000..fb17e4366 --- /dev/null +++ b/forestry_common/apiculture/forestry/apiculture/gui/ContainerAlvearyHygroregulator.java @@ -0,0 +1,50 @@ +/******************************************************************************* + * Copyright 2011-2014 by SirSengir + * + * This work is licensed under a Creative Commons Attribution-NonCommercial-NoDerivs 3.0 Unported License. + * + * To view a copy of this license, visit http://creativecommons.org/licenses/by-nc-nd/3.0/. + ******************************************************************************/ +package forestry.apiculture.gui; + +import net.minecraft.inventory.ICrafting; +import net.minecraft.inventory.IInventory; +import net.minecraft.inventory.Slot; + +import forestry.apiculture.gadgets.TileAlvearyHygroregulator; +import forestry.core.gui.ContainerLiquidTanks; +import forestry.core.gui.slots.SlotLiquidContainer; + +public class ContainerAlvearyHygroregulator extends ContainerLiquidTanks { + + TileAlvearyHygroregulator tile; + + public ContainerAlvearyHygroregulator(IInventory inventory, TileAlvearyHygroregulator tile) { + super(inventory, tile); + + this.tile = tile; + this.addSlot(new SlotLiquidContainer(tile, 0, 56, 38)); + + for (int i = 0; i < 3; ++i) + for (int var4 = 0; var4 < 9; ++var4) + this.addSlot(new Slot(inventory, var4 + i * 9 + 9, 8 + var4 * 18, 84 + i * 18)); + + for (int i = 0; i < 9; ++i) + this.addSlot(new Slot(inventory, i, 8 + i * 18, 142)); + + } + + @Override + public void updateProgressBar(int i, int j) { + tile.getGUINetworkData(i, j); + } + + @Override + public void detectAndSendChanges() { + super.detectAndSendChanges(); + + for (int i = 0; i < crafters.size(); i++) + tile.sendGUINetworkData(this, (ICrafting) crafters.get(i)); + } + +} diff --git a/forestry_common/apiculture/forestry/apiculture/gui/ContainerAlvearySieve.java b/forestry_common/apiculture/forestry/apiculture/gui/ContainerAlvearySieve.java new file mode 100755 index 000000000..b5dfdb6d0 --- /dev/null +++ b/forestry_common/apiculture/forestry/apiculture/gui/ContainerAlvearySieve.java @@ -0,0 +1,54 @@ +/******************************************************************************* + * Copyright 2011-2014 by SirSengir + * + * This work is licensed under a Creative Commons Attribution-NonCommercial-NoDerivs 3.0 Unported License. + * + * To view a copy of this license, visit http://creativecommons.org/licenses/by-nc-nd/3.0/. + ******************************************************************************/ +package forestry.apiculture.gui; + +import net.minecraft.entity.player.EntityPlayer; +import net.minecraft.entity.player.InventoryPlayer; +import net.minecraft.inventory.IInventory; +import net.minecraft.inventory.Slot; + +import forestry.apiculture.gadgets.TileAlvearySieve; +import forestry.core.config.ForestryItem; +import forestry.core.gui.ContainerForestry; +import forestry.core.gui.slots.SlotCustom; + +public class ContainerAlvearySieve extends ContainerForestry { + + TileAlvearySieve tile; + + public ContainerAlvearySieve(InventoryPlayer player, TileAlvearySieve tile) { + super(tile.getInternalInventory()); + + this.tile = tile; + IInventory inventory = tile.getInternalInventory(); + + addSlot(new SlotCustom(inventory, 0, 94, 52, new Object[0]).setCrafter(tile)); + addSlot(new SlotCustom(inventory, 1, 115, 39, new Object[0]).setCrafter(tile)); + addSlot(new SlotCustom(inventory, 2, 73, 39, new Object[0]).setCrafter(tile)); + addSlot(new SlotCustom(inventory, 3, 94, 26, new Object[0]).setCrafter(tile)); + + addSlot(new SlotCustom(inventory, TileAlvearySieve.SLOT_SIEVE, 43, 39, ForestryItem.craftingMaterial.getItemStack(1, 3)).setCrafter(tile)); + + // Player inventory + for (int i = 0; i < 3; i++) { + for (int j = 0; j < 9; j++) { + addSlot(new Slot(player, j + i * 9 + 9, 8 + j * 18, 87 + i * 18)); + } + } + // Player hotbar + for (int i = 0; i < 9; i++) { + addSlot(new Slot(player, i, 8 + i * 18, 145)); + } + + } + + @Override + public boolean canInteractWith(EntityPlayer entityplayer) { + return tile.isUseableByPlayer(entityplayer); + } +} diff --git a/forestry_common/apiculture/forestry/apiculture/gui/ContainerAlvearySwarmer.java b/forestry_common/apiculture/forestry/apiculture/gui/ContainerAlvearySwarmer.java new file mode 100755 index 000000000..5ff95040f --- /dev/null +++ b/forestry_common/apiculture/forestry/apiculture/gui/ContainerAlvearySwarmer.java @@ -0,0 +1,41 @@ +/******************************************************************************* + * Copyright 2011-2014 by SirSengir + * + * This work is licensed under a Creative Commons Attribution-NonCommercial-NoDerivs 3.0 Unported License. + * + * To view a copy of this license, visit http://creativecommons.org/licenses/by-nc-nd/3.0/. + ******************************************************************************/ +package forestry.apiculture.gui; + +import net.minecraft.entity.player.InventoryPlayer; +import net.minecraft.inventory.Slot; + +import forestry.api.apiculture.BeeManager; +import forestry.apiculture.gadgets.TileAlvearySwarmer; +import forestry.core.gui.ContainerForestry; +import forestry.core.gui.slots.SlotCustom; + +public class ContainerAlvearySwarmer extends ContainerForestry { + + public ContainerAlvearySwarmer(InventoryPlayer player, TileAlvearySwarmer tile) { + super(tile); + + this.addSlot(new SlotCustom(tile, 0, 79, 52, getInducerItems())); + this.addSlot(new SlotCustom(tile, 1, 100, 39, getInducerItems())); + this.addSlot(new SlotCustom(tile, 2, 58, 39, getInducerItems())); + this.addSlot(new SlotCustom(tile, 3, 79, 26, getInducerItems())); + + // Player inventory + for (int i = 0; i < 3; i++) + for (int j = 0; j < 9; j++) + addSlot(new Slot(player, j + i * 9 + 9, 8 + j * 18, 87 + i * 18)); + // Player hotbar + for (int i = 0; i < 9; i++) + addSlot(new Slot(player, i, 8 + i * 18, 145)); + + } + + private Object[] getInducerItems() { + return BeeManager.inducers.keySet().toArray(new Object[0]); + } +} diff --git a/forestry_common/apiculture/forestry/apiculture/gui/ContainerApiary.java b/forestry_common/apiculture/forestry/apiculture/gui/ContainerApiary.java new file mode 100755 index 000000000..0b5b65ba5 --- /dev/null +++ b/forestry_common/apiculture/forestry/apiculture/gui/ContainerApiary.java @@ -0,0 +1,86 @@ +/******************************************************************************* + * Copyright 2011-2014 by SirSengir + * + * This work is licensed under a Creative Commons Attribution-NonCommercial-NoDerivs 3.0 Unported License. + * + * To view a copy of this license, visit http://creativecommons.org/licenses/by-nc-nd/3.0/. + ******************************************************************************/ +package forestry.apiculture.gui; + +import net.minecraft.entity.player.EntityPlayer; +import net.minecraft.entity.player.InventoryPlayer; +import net.minecraft.inventory.ICrafting; +import net.minecraft.inventory.IInventory; +import net.minecraft.inventory.Slot; + +import forestry.api.apiculture.IHiveFrame; +import forestry.apiculture.gadgets.TileBeehouse; +import forestry.core.config.ForestryItem; +import forestry.core.gui.ContainerForestry; +import forestry.core.gui.slots.SlotClosed; +import forestry.core.gui.slots.SlotCustom; +import forestry.core.utils.Utils; + +public class ContainerApiary extends ContainerForestry { + + private final TileBeehouse tile; + + public ContainerApiary(InventoryPlayer player, TileBeehouse tile, boolean hasFrames) { + super(tile.getInternalInventory()); + + this.tile = tile; + tile.sendNetworkUpdate(); + IInventory inventory = tile.getInternalInventory(); + + // Queen/Princess + this.addSlot(new SlotCustom(inventory, TileBeehouse.SLOT_QUEEN, 29, 39, ForestryItem.beePrincessGE, ForestryItem.beeQueenGE)); + + // Drone + this.addSlot(new SlotCustom(inventory, TileBeehouse.SLOT_DRONE, 29, 65, ForestryItem.beeDroneGE)); + + // Frames + if (hasFrames) { + this.addSlot(new SlotCustom(inventory, TileBeehouse.SLOT_FRAMES_1, 66, 23, IHiveFrame.class)); + this.addSlot(new SlotCustom(inventory, TileBeehouse.SLOT_FRAMES_1 + 1, 66, 52, IHiveFrame.class)); + this.addSlot(new SlotCustom(inventory, TileBeehouse.SLOT_FRAMES_1 + 2, 66, 81, IHiveFrame.class)); + } + + // Product Inventory + this.addSlot(new SlotClosed(inventory, 2, 116, 52)); + this.addSlot(new SlotClosed(inventory, 3, 137, 39)); + this.addSlot(new SlotClosed(inventory, 4, 137, 65)); + this.addSlot(new SlotClosed(inventory, 5, 116, 78)); + this.addSlot(new SlotClosed(inventory, 6, 95, 65)); + this.addSlot(new SlotClosed(inventory, 7, 95, 39)); + this.addSlot(new SlotClosed(inventory, 8, 116, 26)); + + // Player inventory + for (int i1 = 0; i1 < 3; i1++) { + for (int l1 = 0; l1 < 9; l1++) { + addSlot(new Slot(player, l1 + i1 * 9 + 9, 8 + l1 * 18, 108 + i1 * 18)); + } + } + // Player hotbar + for (int j1 = 0; j1 < 9; j1++) { + addSlot(new Slot(player, j1, 8 + j1 * 18, 166)); + } + } + + @Override + public void updateProgressBar(int i, int j) { + tile.getGUINetworkData(i, j); + } + + @Override + public void detectAndSendChanges() { + super.detectAndSendChanges(); + for (int i = 0; i < crafters.size(); i++) { + tile.sendGUINetworkData(this, (ICrafting) crafters.get(i)); + } + } + + @Override + public boolean canInteractWith(EntityPlayer entityplayer) { + return Utils.isUseableByPlayer(entityplayer, tile, tile.getWorld(), tile.xCoord, tile.yCoord, tile.zCoord); + } +} diff --git a/forestry_common/apiculture/forestry/apiculture/gui/ContainerBeealyzer.java b/forestry_common/apiculture/forestry/apiculture/gui/ContainerBeealyzer.java new file mode 100755 index 000000000..3c0461082 --- /dev/null +++ b/forestry_common/apiculture/forestry/apiculture/gui/ContainerBeealyzer.java @@ -0,0 +1,80 @@ +/******************************************************************************* + * Copyright 2011-2014 by SirSengir + * + * This work is licensed under a Creative Commons Attribution-NonCommercial-NoDerivs 3.0 Unported License. + * + * To view a copy of this license, visit http://creativecommons.org/licenses/by-nc-nd/3.0/. + ******************************************************************************/ +package forestry.apiculture.gui; + +import net.minecraft.entity.player.EntityPlayer; +import net.minecraft.entity.player.InventoryPlayer; +import net.minecraft.item.ItemStack; + +import forestry.apiculture.items.ItemBeeGE; +import forestry.apiculture.items.ItemBeealyzer.BeealyzerInventory; +import forestry.core.config.ForestryItem; +import forestry.core.gui.ContainerItemInventory; +import forestry.core.gui.slots.SlotCustom; +import forestry.core.proxy.Proxies; + +public class ContainerBeealyzer extends ContainerItemInventory { + + BeealyzerInventory inventory; + + public ContainerBeealyzer(InventoryPlayer inventoryplayer, BeealyzerInventory inventory) { + super(inventory, inventoryplayer.player); + + this.inventory = inventory; + + // Energy + this.addSlot(new SlotCustom(inventory, BeealyzerInventory.SLOT_ENERGY, 172, 8, new Object[] { ForestryItem.honeydew, ForestryItem.honeyDrop })); + + // Bee to analyze + this.addSlot(new SlotCustom(inventory, BeealyzerInventory.SLOT_SPECIMEN, 172, 26, new Object[] { ItemBeeGE.class })); + + // Analyzed bee + this.addSlot(new SlotCustom(inventory, BeealyzerInventory.SLOT_ANALYZE_1, 172, 57, new Object[] { ItemBeeGE.class })); + this.addSlot(new SlotCustom(inventory, BeealyzerInventory.SLOT_ANALYZE_2, 172, 75, new Object[] { ItemBeeGE.class })); + this.addSlot(new SlotCustom(inventory, BeealyzerInventory.SLOT_ANALYZE_3, 172, 93, new Object[] { ItemBeeGE.class })); + this.addSlot(new SlotCustom(inventory, BeealyzerInventory.SLOT_ANALYZE_4, 172, 111, new Object[] { ItemBeeGE.class })); + this.addSlot(new SlotCustom(inventory, BeealyzerInventory.SLOT_ANALYZE_5, 172, 129, new Object[] { ItemBeeGE.class })); + + // Player inventory + for (int i1 = 0; i1 < 3; i1++) + for (int l1 = 0; l1 < 9; l1++) + addSecuredSlot(inventoryplayer, l1 + i1 * 9 + 9, 18 + l1 * 18, 156 + i1 * 18); + // Player hotbar + for (int j1 = 0; j1 < 9; j1++) + addSecuredSlot(inventoryplayer, j1, 18 + j1 * 18, 214); + + } + + @Override + public void onContainerClosed(EntityPlayer entityplayer) { + + if (!Proxies.common.isSimulating(entityplayer.worldObj)) + return; + + // Last slot is the energy slot, so we don't save that one. + for (int i = 0; i < inventory.getSizeInventory(); i++) { + if (i == BeealyzerInventory.SLOT_ENERGY) + continue; + ItemStack stack = inventory.getStackInSlot(i); + if (stack == null) + continue; + + Proxies.common.dropItemPlayer(entityplayer, stack); + inventory.setInventorySlotContents(i, null); + } + + inventory.onGuiSaved(entityplayer); + + } + + @Override + protected boolean isAcceptedItem(EntityPlayer player, ItemStack stack) { + return true; + } + +} diff --git a/forestry_common/apiculture/forestry/apiculture/gui/ContainerHabitatLocator.java b/forestry_common/apiculture/forestry/apiculture/gui/ContainerHabitatLocator.java new file mode 100755 index 000000000..9c7e31854 --- /dev/null +++ b/forestry_common/apiculture/forestry/apiculture/gui/ContainerHabitatLocator.java @@ -0,0 +1,74 @@ +/******************************************************************************* + * Copyright 2011-2014 by SirSengir + * + * This work is licensed under a Creative Commons Attribution-NonCommercial-NoDerivs 3.0 Unported License. + * + * To view a copy of this license, visit http://creativecommons.org/licenses/by-nc-nd/3.0/. + ******************************************************************************/ +package forestry.apiculture.gui; + +import net.minecraft.entity.player.EntityPlayer; +import net.minecraft.entity.player.InventoryPlayer; +import net.minecraft.item.ItemStack; + +import forestry.apiculture.items.ItemBeeGE; +import forestry.apiculture.items.ItemBiomefinder; +import forestry.apiculture.items.ItemBiomefinder.BiomefinderInventory; +import forestry.core.config.ForestryItem; +import forestry.core.gui.ContainerItemInventory; +import forestry.core.gui.slots.SlotCustom; +import forestry.core.proxy.Proxies; + +public class ContainerHabitatLocator extends ContainerItemInventory { + + public BiomefinderInventory inventory; + + public ContainerHabitatLocator(InventoryPlayer inventoryplayer, BiomefinderInventory inventory) { + super(inventory, inventoryplayer.player); + + this.inventory = inventory; + + // Energy + this.addSlot(new SlotCustom(inventory, 2, 152, 8, new Object[] { ForestryItem.honeydew, ForestryItem.honeyDrop })); + + // Bee to analyze + this.addSlot(new SlotCustom(inventory, 0, 152, 32, new Object[] { ItemBeeGE.class })); + // Analyzed bee + this.addSlot(new SlotCustom(inventory, 1, 152, 75, new Object[] { ItemBeeGE.class })); + + // Player inventory + for (int i1 = 0; i1 < 3; i1++) + for (int l1 = 0; l1 < 9; l1++) + addSecuredSlot(inventoryplayer, l1 + i1 * 9 + 9, 8 + l1 * 18, 102 + i1 * 18); + // Player hotbar + for (int j1 = 0; j1 < 9; j1++) + addSecuredSlot(inventoryplayer, j1, 8 + j1 * 18, 160); + } + + @Override + public void onContainerClosed(EntityPlayer entityplayer) { + + if (!Proxies.common.isSimulating(entityplayer.worldObj)) + return; + + ((ItemBiomefinder) ForestryItem.biomeFinder.item()).startBiomeSearch(entityplayer.worldObj, entityplayer, inventory.biomesToSearch); + + for (int i = 0; i < inventory.getSizeInventory() - 1; i++) { + ItemStack stack = inventory.getStackInSlot(i); + if (stack == null) + continue; + + Proxies.common.dropItemPlayer(entityplayer, stack); + inventory.setInventorySlotContents(i, null); + } + + inventory.onGuiSaved(entityplayer); + + } + + @Override + protected boolean isAcceptedItem(EntityPlayer player, ItemStack stack) { + return false; + } + +} diff --git a/forestry_common/apiculture/forestry/apiculture/gui/ContainerImprinter.java b/forestry_common/apiculture/forestry/apiculture/gui/ContainerImprinter.java new file mode 100755 index 000000000..5d6a9b30d --- /dev/null +++ b/forestry_common/apiculture/forestry/apiculture/gui/ContainerImprinter.java @@ -0,0 +1,121 @@ +/******************************************************************************* + * Copyright 2011-2014 by SirSengir + * + * This work is licensed under a Creative Commons Attribution-NonCommercial-NoDerivs 3.0 Unported License. + * + * To view a copy of this license, visit http://creativecommons.org/licenses/by-nc-nd/3.0/. + ******************************************************************************/ +package forestry.apiculture.gui; + +import net.minecraft.entity.player.EntityPlayer; +import net.minecraft.entity.player.InventoryPlayer; +import net.minecraft.inventory.Slot; +import net.minecraft.item.ItemStack; +import net.minecraft.world.World; + +import forestry.apiculture.items.ItemBeeGE; +import forestry.apiculture.items.ItemImprinter.ImprinterInventory; +import forestry.core.gui.ContainerForestry; +import forestry.core.gui.IGuiSelectable; +import forestry.core.gui.slots.SlotCustom; +import forestry.core.network.PacketIds; +import forestry.core.network.PacketPayload; +import forestry.core.network.PacketUpdate; +import forestry.core.proxy.Proxies; + +public class ContainerImprinter extends ContainerForestry implements IGuiSelectable { + + public ImprinterInventory inventory; + private boolean isNetSynched = false; + + public ContainerImprinter(InventoryPlayer inventoryplayer, ImprinterInventory inventory) { + super(inventory); + + this.inventory = inventory; + // Input + this.addSlot(new SlotCustom(inventory, 0, 152, 12, new Object[] { ItemBeeGE.class })); + // Output + this.addSlot(new SlotCustom(inventory, 1, 152, 72, new Object[] { ItemBeeGE.class })); + + // Player inventory + for (int i1 = 0; i1 < 3; i1++) + for (int l1 = 0; l1 < 9; l1++) + addSlot(new Slot(inventoryplayer, l1 + i1 * 9 + 9, 8 + l1 * 18, 103 + i1 * 18)); + // Player hotbar + for (int j1 = 0; j1 < 9; j1++) + addSlot(new Slot(inventoryplayer, j1, 8 + j1 * 18, 161)); + } + + @Override + public void onContainerClosed(EntityPlayer entityplayer) { + + if (!Proxies.common.isSimulating(entityplayer.worldObj)) + return; + + // Drop everything still in there. + for (int i = 0; i < inventory.getSizeInventory(); i++) { + ItemStack stack = inventory.getStackInSlot(i); + if (stack == null) + continue; + + Proxies.common.dropItemPlayer(entityplayer, stack); + inventory.setInventorySlotContents(i, null); + } + + } + + public void advanceSelection(int index, World world) { + PacketPayload payload = new PacketPayload(2, 0, 0); + payload.intPayload[0] = index; + payload.intPayload[1] = 0; + sendSelectionChange(payload); + } + + public void regressSelection(int index, World world) { + PacketPayload payload = new PacketPayload(2, 0, 0); + payload.intPayload[0] = index; + payload.intPayload[1] = 1; + sendSelectionChange(payload); + } + + private void sendSelectionChange(PacketPayload payload) { + PacketUpdate packet = new PacketUpdate(PacketIds.GUI_SELECTION_CHANGE, payload); + Proxies.net.sendToServer(packet); + isNetSynched = false; + } + + @Override + public void setSelection(PacketUpdate packet) { + inventory.setPrimaryIndex(packet.payload.intPayload[0]); + inventory.setSecondaryIndex(packet.payload.intPayload[1]); + } + + public void updateContainer(World world) { + if (!isNetSynched && !Proxies.common.isSimulating(world)) { + isNetSynched = true; + Proxies.net.sendToServer(new PacketUpdate(PacketIds.IMPRINT_SELECTION_GET)); + } + } + + @Override + public void handleSelectionChange(EntityPlayer player, PacketUpdate packet) { + + if (packet.payload.intPayload[1] == 0) { + if (packet.payload.intPayload[0] == 0) + inventory.advancePrimary(); + else + inventory.advanceSecondary(); + + } else if (packet.payload.intPayload[0] == 0) + inventory.regressPrimary(); + else + inventory.regressSecondary(); + } + + public void sendSelection(EntityPlayer player) { + PacketPayload payload = new PacketPayload(2, 0, 0); + payload.intPayload[0] = inventory.getPrimaryIndex(); + payload.intPayload[1] = inventory.getSecondaryIndex(); + Proxies.net.sendToPlayer(new PacketUpdate(PacketIds.GUI_SELECTION, payload), player); + } +} diff --git a/forestry_common/apiculture/forestry/apiculture/gui/GuiAlveary.java b/forestry_common/apiculture/forestry/apiculture/gui/GuiAlveary.java new file mode 100755 index 000000000..783a60811 --- /dev/null +++ b/forestry_common/apiculture/forestry/apiculture/gui/GuiAlveary.java @@ -0,0 +1,65 @@ +/******************************************************************************* + * Copyright 2011-2014 by SirSengir + * + * This work is licensed under a Creative Commons Attribution-NonCommercial-NoDerivs 3.0 Unported License. + * + * To view a copy of this license, visit http://creativecommons.org/licenses/by-nc-nd/3.0/. + ******************************************************************************/ +package forestry.apiculture.gui; + +import net.minecraft.entity.player.InventoryPlayer; + +import forestry.apiculture.gadgets.TileAlvearyPlain; +import forestry.core.config.Defaults; +import forestry.core.gui.GuiForestry; +import forestry.core.utils.EnumTankLevel; +import forestry.core.utils.StringUtil; +import forestry.core.utils.Utils; + +public class GuiAlveary extends GuiForestry { + + public GuiAlveary(InventoryPlayer inventory, TileAlvearyPlain tile) { + super(Defaults.TEXTURE_PATH_GUI + "/alveary.png", new ContainerAlveary(inventory, tile), tile); + + ySize = 190; + } + + @Override + protected void drawGuiContainerForegroundLayer(int mouseX, int mouseY) { + super.drawGuiContainerForegroundLayer(mouseX, mouseY); + String title = StringUtil.localize("tile." + tile.getInventoryName()); + this.fontRendererObj.drawString(title, getCenteredOffset(title), 6, fontColor.get("gui.title")); + } + + @Override + protected void drawGuiContainerBackgroundLayer(float var1, int mouseX, int mouseY) { + super.drawGuiContainerBackgroundLayer(var1, mouseX, mouseY); + + TileAlvearyPlain machine = tile; + drawHealthMeter(guiLeft + 20, guiTop + 37, machine.getHealthScaled(46), Utils.rateTankLevel(machine.getHealthScaled(100))); + } + + private void drawHealthMeter(int x, int y, int height, EnumTankLevel rated) { + int i = 176; + int k = 0; + switch (rated) { + case EMPTY: + break; + case LOW: + i += 4; + break; + case MEDIUM: + i += 8; + break; + case HIGH: + i += 12; + break; + case MAXIMUM: + i += 16; + break; + } + + this.drawTexturedModalRect(x, y + 46 - height, i, k + 46 - height, 4, height); + } + +} diff --git a/forestry_common/apiculture/forestry/apiculture/gui/GuiAlvearyHygroregulator.java b/forestry_common/apiculture/forestry/apiculture/gui/GuiAlvearyHygroregulator.java new file mode 100755 index 000000000..8219bda5c --- /dev/null +++ b/forestry_common/apiculture/forestry/apiculture/gui/GuiAlvearyHygroregulator.java @@ -0,0 +1,33 @@ +/******************************************************************************* + * Copyright 2011-2014 by SirSengir + * + * This work is licensed under a Creative Commons Attribution-NonCommercial-NoDerivs 3.0 Unported License. + * + * To view a copy of this license, visit http://creativecommons.org/licenses/by-nc-nd/3.0/. + ******************************************************************************/ +package forestry.apiculture.gui; + +import net.minecraft.entity.player.InventoryPlayer; + +import forestry.apiculture.gadgets.TileAlvearyHygroregulator; +import forestry.core.config.Defaults; +import forestry.core.gui.GuiForestry; +import forestry.core.gui.widgets.TankWidget; +import forestry.core.utils.StringUtil; + +public class GuiAlvearyHygroregulator extends GuiForestry { + + public GuiAlvearyHygroregulator(InventoryPlayer inventory, TileAlvearyHygroregulator tile) { + super(Defaults.TEXTURE_PATH_GUI + "/hygroregulator.png", new ContainerAlvearyHygroregulator(inventory, tile)); + + widgetManager.add(new TankWidget(this.widgetManager, 104, 17, 0)); + } + + @Override + protected void drawGuiContainerForegroundLayer(int mouseX, int mouseY) { + super.drawGuiContainerForegroundLayer(mouseX, mouseY); + String name = StringUtil.localize("tile.alveary.5"); + this.fontRendererObj.drawString(name, getCenteredOffset(name), 6, fontColor.get("gui.title")); + } + +} diff --git a/forestry_common/apiculture/forestry/apiculture/gui/GuiAlvearySieve.java b/forestry_common/apiculture/forestry/apiculture/gui/GuiAlvearySieve.java new file mode 100755 index 000000000..d7217a92b --- /dev/null +++ b/forestry_common/apiculture/forestry/apiculture/gui/GuiAlvearySieve.java @@ -0,0 +1,23 @@ +/******************************************************************************* + * Copyright 2011-2014 by SirSengir + * + * This work is licensed under a Creative Commons Attribution-NonCommercial-NoDerivs 3.0 Unported License. + * + * To view a copy of this license, visit http://creativecommons.org/licenses/by-nc-nd/3.0/. + ******************************************************************************/ +package forestry.apiculture.gui; + +import net.minecraft.entity.player.InventoryPlayer; + +import forestry.apiculture.gadgets.TileAlvearySieve; +import forestry.core.config.Defaults; +import forestry.core.gui.GuiForestry; + +public class GuiAlvearySieve extends GuiForestry { + + public GuiAlvearySieve(InventoryPlayer inventory, TileAlvearySieve tile) { + super(Defaults.TEXTURE_PATH_GUI + "/sieve.png", new ContainerAlvearySieve(inventory, tile)); + } + + +} diff --git a/forestry_common/apiculture/forestry/apiculture/gui/GuiAlvearySwarmer.java b/forestry_common/apiculture/forestry/apiculture/gui/GuiAlvearySwarmer.java new file mode 100755 index 000000000..f8a5e6099 --- /dev/null +++ b/forestry_common/apiculture/forestry/apiculture/gui/GuiAlvearySwarmer.java @@ -0,0 +1,22 @@ +/******************************************************************************* + * Copyright 2011-2014 by SirSengir + * + * This work is licensed under a Creative Commons Attribution-NonCommercial-NoDerivs 3.0 Unported License. + * + * To view a copy of this license, visit http://creativecommons.org/licenses/by-nc-nd/3.0/. + ******************************************************************************/ +package forestry.apiculture.gui; + +import net.minecraft.entity.player.InventoryPlayer; + +import forestry.apiculture.gadgets.TileAlvearySwarmer; +import forestry.core.config.Defaults; +import forestry.core.gui.GuiForestry; + +public class GuiAlvearySwarmer extends GuiForestry { + + public GuiAlvearySwarmer(InventoryPlayer inventory, TileAlvearySwarmer tile) { + super(Defaults.TEXTURE_PATH_GUI + "/swarmer.png", new ContainerAlvearySwarmer(inventory, tile)); + } + +} diff --git a/forestry_common/apiculture/forestry/apiculture/gui/GuiApiary.java b/forestry_common/apiculture/forestry/apiculture/gui/GuiApiary.java new file mode 100755 index 000000000..af2708dbe --- /dev/null +++ b/forestry_common/apiculture/forestry/apiculture/gui/GuiApiary.java @@ -0,0 +1,72 @@ +/******************************************************************************* + * Copyright 2011-2014 by SirSengir + * + * This work is licensed under a Creative Commons Attribution-NonCommercial-NoDerivs 3.0 Unported License. + * + * To view a copy of this license, visit http://creativecommons.org/licenses/by-nc-nd/3.0/. + ******************************************************************************/ +package forestry.apiculture.gui; + +import net.minecraft.entity.player.InventoryPlayer; + +import forestry.apiculture.gadgets.TileApiary; +import forestry.apiculture.gadgets.TileBeehouse; +import forestry.core.config.Defaults; +import forestry.core.gui.GuiForestry; +import forestry.core.utils.EnumTankLevel; +import forestry.core.utils.StringUtil; +import forestry.core.utils.Utils; + +public class GuiApiary extends GuiForestry { + + public GuiApiary(InventoryPlayer inventory, TileApiary tile) { + super(Defaults.TEXTURE_PATH_GUI + "/apiary.png", new ContainerApiary(inventory, tile, true), tile); + + ySize = 190; + } + + public GuiApiary(InventoryPlayer inventory, TileBeehouse tile) { + super(Defaults.TEXTURE_PATH_GUI + "/alveary.png", new ContainerApiary(inventory, tile, false), tile); + + ySize = 190; + } + + @Override + protected void drawGuiContainerForegroundLayer(int mouseX, int mouseY) { + super.drawGuiContainerForegroundLayer(mouseX, mouseY); + String name = StringUtil.localize("tile.for." + tile.getInventoryName()); + this.fontRendererObj.drawString(name, getCenteredOffset(name), 6, fontColor.get("gui.title")); + } + + @Override + protected void drawGuiContainerBackgroundLayer(float var1, int mouseX, int mouseY) { + super.drawGuiContainerBackgroundLayer(var1, mouseX, mouseY); + + TileBeehouse machine = tile; + drawHealthMeter(guiLeft + 20, guiTop + 37, machine.getHealthScaled(46), Utils.rateTankLevel(machine.getHealthScaled(100))); + } + + private void drawHealthMeter(int x, int y, int height, EnumTankLevel rated) { + int i = 176; + int k = 0; + switch (rated) { + case EMPTY: + break; + case LOW: + i += 4; + break; + case MEDIUM: + i += 8; + break; + case HIGH: + i += 12; + break; + case MAXIMUM: + i += 16; + break; + } + + this.drawTexturedModalRect(x, y + 46 - height, i, k + 46 - height, 4, height); + } + +} diff --git a/forestry_common/apiculture/forestry/apiculture/gui/GuiBeealyzer.java b/forestry_common/apiculture/forestry/apiculture/gui/GuiBeealyzer.java new file mode 100755 index 000000000..91da3e27c --- /dev/null +++ b/forestry_common/apiculture/forestry/apiculture/gui/GuiBeealyzer.java @@ -0,0 +1,321 @@ +/******************************************************************************* + * Copyright 2011-2014 by SirSengir + * + * This work is licensed under a Creative Commons Attribution-NonCommercial-NoDerivs 3.0 Unported License. + * + * To view a copy of this license, visit http://creativecommons.org/licenses/by-nc-nd/3.0/. + ******************************************************************************/ +package forestry.apiculture.gui; + +import java.util.ArrayList; + +import net.minecraft.entity.player.EntityPlayer; +import net.minecraft.item.ItemStack; + +import forestry.api.apiculture.EnumBeeChromosome; +import forestry.api.apiculture.EnumBeeType; +import forestry.api.apiculture.IAlleleBeeEffect; +import forestry.api.apiculture.IBee; +import forestry.api.genetics.AlleleManager; +import forestry.api.genetics.IAlleleFlowers; +import forestry.api.genetics.IAlleleInteger; +import forestry.apiculture.items.ItemBeeGE; +import forestry.apiculture.items.ItemBeealyzer.BeealyzerInventory; +import forestry.core.config.ForestryItem; +import forestry.core.genetics.AlleleArea; +import forestry.core.genetics.AlleleBoolean; +import forestry.core.genetics.AlleleTolerance; +import forestry.core.genetics.ClimateHelper; +import forestry.core.gui.GuiAlyzer; +import forestry.core.utils.StringUtil; +import forestry.core.utils.Vect; +import forestry.plugins.PluginApiculture; + +public class GuiBeealyzer extends GuiAlyzer { + + private ItemStack[] tempProductList; + + public GuiBeealyzer(EntityPlayer player, BeealyzerInventory inventory) { + super(AlleleManager.alleleRegistry.getSpeciesRoot("rootBees"), player, + new ContainerBeealyzer(player.inventory, inventory), inventory, 1, inventory.getSizeInventory()); + + xSize = 196; + ySize = 238; + + ArrayList beeList = new ArrayList(); + ((ItemBeeGE) ForestryItem.beeDroneGE.item()).addCreativeItems(beeList, false); + for (ItemStack beeStack : beeList) + iconStacks.put(PluginApiculture.beeInterface.getMember(beeStack).getIdent(), beeStack); + + breedingTracker = PluginApiculture.beeInterface.getBreedingTracker(player.worldObj, player.getGameProfile().getId()); + } + + @Override + protected void drawGuiContainerBackgroundLayer(float var1, int mouseX, int mouseY) { + super.drawGuiContainerBackgroundLayer(var1, mouseX, mouseY); + + int page = 0; + IBee bee = null; + EnumBeeType beeType = EnumBeeType.DRONE; + for (int k = 1; k < BeealyzerInventory.SLOT_ANALYZE_5 + 1; k++) { + if (k == BeealyzerInventory.SLOT_ENERGY) + continue; + + if (inventory.getStackInSlot(k) == null) + continue; + bee = PluginApiculture.beeInterface.getMember(inventory.getStackInSlot(k)); + beeType = PluginApiculture.beeInterface.getType(inventory.getStackInSlot(k)); + if (bee == null || !bee.isAnalyzed()) + continue; + + page = k; + break; + } + + switch (page) { + case 1: + drawAnalyticsPage1(bee, beeType); + break; + case 2: + drawAnalyticsPage2(bee, beeType); + break; + case 3: + drawAnalyticsPage3(bee, beeType); + break; + case 4: + drawAnalyticsPage4(bee); + break; + case 6: + drawAnalyticsPageClassification(bee); + break; + default: + drawAnalyticsOverview(); + } + + } + + private void drawAnalyticsOverview() { + + startPage(); + + newLine(); + String title = StringUtil.localize("gui.beealyzer").toUpperCase(); + drawCenteredLine(title, 8, 158); + newLine(); + + fontRendererObj.drawSplitString(StringUtil.localize("gui.beealyzer.help"), (int) ((guiLeft + COLUMN_0 + 4) * (1 / factor)), + (int) ((guiTop + 42) * (1 / factor)), (int) (158 * (1 / factor)), fontColor.get("gui.screen")); + newLine(); + newLine(); + newLine(); + newLine(); + + drawLine(StringUtil.localize("gui.beealyzer.overview") + ":", COLUMN_0 + 4); + newLine(); + drawLine("I : " + StringUtil.localize("gui.general"), COLUMN_0 + 4); + newLine(); + drawLine("II : " + StringUtil.localize("gui.environment"), COLUMN_0 + 4); + newLine(); + drawLine("III: " + StringUtil.localize("gui.produce"), COLUMN_0 + 4); + newLine(); + drawLine("IV : " + StringUtil.localize("gui.evolution"), COLUMN_0 + 4); + + newLine(); + + String mode = breedingTracker.getModeName(); + if (mode != null && !mode.isEmpty()) { + newLine(); + String rules = StringUtil.localize("gui.beealyzer.behaviour") + ": " + StringUtil.capitalize(mode); + drawLine(rules, 8 + getCenteredOffset(title, 158), fontColor.get("gui.beealyzer.binomial")); + } + + endPage(); + + } + + private void drawAnalyticsPage1(IBee bee, EnumBeeType type) { + + startPage(COLUMN_0, COLUMN_1, COLUMN_2); + + drawLine(StringUtil.localize("gui.active"), COLUMN_1); + drawLine(StringUtil.localize("gui.inactive"), COLUMN_2); + + newLine(); + newLine(); + + drawSpeciesRow(StringUtil.localize("gui.species"), bee, EnumBeeChromosome.SPECIES); + + drawRow(StringUtil.localize("gui.lifespan"), bee.getGenome().getActiveAllele(EnumBeeChromosome.LIFESPAN.ordinal()).getName(), + bee.getGenome().getInactiveAllele(EnumBeeChromosome.LIFESPAN.ordinal()).getName(), bee, + EnumBeeChromosome.LIFESPAN); + + drawRow(StringUtil.localize("gui.speed"), bee.getGenome().getActiveAllele(EnumBeeChromosome.SPEED.ordinal()).getName(), + bee.getGenome().getInactiveAllele(EnumBeeChromosome.SPEED.ordinal()).getName(), bee, EnumBeeChromosome.SPEED); + + drawRow(StringUtil.localize("gui.pollination"), bee.getGenome().getActiveAllele(EnumBeeChromosome.FLOWERING.ordinal()).getName(), + bee.getGenome().getInactiveAllele(EnumBeeChromosome.FLOWERING.ordinal()).getName(), bee, + EnumBeeChromosome.FLOWERING); + + drawRow(StringUtil.localize("gui.flowers"), StringUtil.localize(bee.getGenome().getFlowerProvider().getDescription()), + StringUtil.localize(((IAlleleFlowers) bee.getGenome().getInactiveAllele(EnumBeeChromosome.FLOWER_PROVIDER.ordinal())).getProvider() + .getDescription()), bee, EnumBeeChromosome.FLOWER_PROVIDER); + + drawLine(StringUtil.localize("gui.fertility"), COLUMN_0); + drawFertilityInfo(bee.getGenome().getFertility(), COLUMN_1, getColorCoding(bee.getGenome().getActiveAllele(EnumBeeChromosome.FERTILITY.ordinal()) + .isDominant()), 0); + drawFertilityInfo(((IAlleleInteger) bee.getGenome().getInactiveAllele(EnumBeeChromosome.FERTILITY.ordinal())).getValue(), COLUMN_2, getColorCoding(bee + .getGenome().getInactiveAllele(EnumBeeChromosome.FERTILITY.ordinal()).isDominant()), 0); + + newLine(); + + int[] areaAr = bee.getGenome().getTerritory(); + Vect area = new Vect(areaAr[0], areaAr[1], areaAr[2]); + drawRow(StringUtil.localize("gui.area"), area.toString(), ((AlleleArea) bee.getGenome().getInactiveAllele(EnumBeeChromosome.TERRITORY.ordinal())) + .getArea().toString(), bee, EnumBeeChromosome.TERRITORY); + + drawRow(StringUtil.localize("gui.effect"), StringUtil.localize(bee.getGenome().getEffect().getName()), + StringUtil.localize(((IAlleleBeeEffect) bee.getGenome().getInactiveAllele(EnumBeeChromosome.EFFECT.ordinal())).getName()), bee, + EnumBeeChromosome.EFFECT); + + newLine(); + + endPage(); + } + + private void drawAnalyticsPage2(IBee bee, EnumBeeType type) { + + startPage(COLUMN_0, COLUMN_1, COLUMN_2); + + drawLine(StringUtil.localize("gui.active"), COLUMN_1); + drawLine(StringUtil.localize("gui.inactive"), COLUMN_2); + + newLine(); + newLine(); + + drawRow(StringUtil.localize("gui.climate"), ClimateHelper.toDisplay(bee.getGenome().getPrimary().getTemperature()), + ClimateHelper.toDisplay(bee.getGenome().getSecondary().getTemperature()), bee, EnumBeeChromosome.SPECIES); + + drawLine(StringUtil.localize("gui.temptol"), COLUMN_0); + drawToleranceInfo(bee.getGenome().getToleranceTemp(), COLUMN_1, + getColorCoding(bee.getGenome().getActiveAllele(EnumBeeChromosome.TEMPERATURE_TOLERANCE.ordinal()).isDominant())); + drawToleranceInfo(((AlleleTolerance) bee.getGenome().getInactiveAllele(EnumBeeChromosome.TEMPERATURE_TOLERANCE.ordinal())).getValue(), COLUMN_2, + getColorCoding(bee.getGenome().getInactiveAllele(EnumBeeChromosome.TEMPERATURE_TOLERANCE.ordinal()).isDominant())); + + newLine(); + + drawRow(StringUtil.localize("gui.humidity"), ClimateHelper.toDisplay(bee.getGenome().getPrimary().getHumidity()), + ClimateHelper.toDisplay(bee.getGenome().getSecondary().getHumidity()), bee, EnumBeeChromosome.SPECIES); + + drawLine(StringUtil.localize("gui.humidtol"), COLUMN_0); + drawToleranceInfo(bee.getGenome().getToleranceHumid(), COLUMN_1, + getColorCoding(bee.getGenome().getActiveAllele(EnumBeeChromosome.HUMIDITY_TOLERANCE.ordinal()).isDominant())); + drawToleranceInfo(((AlleleTolerance) bee.getGenome().getInactiveAllele(EnumBeeChromosome.HUMIDITY_TOLERANCE.ordinal())).getValue(), COLUMN_2, + getColorCoding(bee.getGenome().getInactiveAllele(EnumBeeChromosome.HUMIDITY_TOLERANCE.ordinal()).isDominant())); + + newLine(); + newLine(); + + String yes = StringUtil.localize("yes"); + String no = StringUtil.localize("no"); + + String diurnal0, diurnal1, nocturnal0, nocturnal1; + if(bee.getGenome().getNocturnal()) { + nocturnal0 = diurnal0 = yes; + } else { + nocturnal0 = bee.getGenome().getPrimary().isNocturnal() ? yes : no; + diurnal0 = !bee.getGenome().getPrimary().isNocturnal() ? yes : no; + } + if(((AlleleBoolean) bee.getGenome().getInactiveAllele(EnumBeeChromosome.NOCTURNAL.ordinal())).getValue()) { + nocturnal1 = diurnal1 = yes; + } else { + nocturnal1 = bee.getGenome().getSecondary().isNocturnal() ? yes : no; + diurnal1 = !bee.getGenome().getSecondary().isNocturnal() ? yes : no; + } + + drawLine(StringUtil.localize("gui.diurnal"), COLUMN_0); + drawLine(diurnal0, COLUMN_1, getColorCoding(false)); + drawLine(diurnal1, COLUMN_2, getColorCoding(false)); + newLine(); + + drawLine(StringUtil.localize("gui.nocturnal"), COLUMN_0); + drawLine(nocturnal0, COLUMN_1, getColorCoding(false)); + drawLine(nocturnal1, COLUMN_2, getColorCoding(false)); + newLine(); + + String primary = StringUtil.readableBoolean(bee.getGenome().getTolerantFlyer(), yes, no); + String secondary = StringUtil.readableBoolean(((AlleleBoolean) bee.getGenome().getInactiveAllele(EnumBeeChromosome.TOLERANT_FLYER.ordinal())).getValue(), yes, + no); + + drawRow(StringUtil.localize("gui.flyer"), primary, secondary, bee, EnumBeeChromosome.TOLERANT_FLYER); + + primary = StringUtil.readableBoolean(bee.getGenome().getCaveDwelling(), yes, no); + secondary = StringUtil.readableBoolean(((AlleleBoolean) bee.getGenome().getInactiveAllele(EnumBeeChromosome.CAVE_DWELLING.ordinal())).getValue(), yes, + no); + + drawRow(StringUtil.localize("gui.cave"), primary, secondary, bee, EnumBeeChromosome.CAVE_DWELLING); + + newLine(); + + String displayText; + if (type == EnumBeeType.PRINCESS || type == EnumBeeType.QUEEN) { + displayText = "bees.stock.pristine"; + if (!bee.isNatural()) + displayText = "bees.stock.ignoble"; + displayText = StringUtil.localize(displayText); + // int offset = (int)(((158 - fontRendererObj.getStringWidth(origin)) / 2)*(1/factor)); + drawCenteredLine(displayText, 8, 158, fontColor.get("gui.beealyzer.binomial"));; + } + + if (bee.getGeneration() >= 0) { + newLine(); + + displayText = bee.getGeneration() + " " + StringUtil.localize("gui.beealyzer.generations"); + // offset = (int)(((158 - fontRendererObj.getStringWidth(origin)) / 2)*(1/factor)); + drawCenteredLine(displayText, 8, 158, fontColor.get("gui.beealyzer.binomial")); + } + + endPage(); + } + + private void drawAnalyticsPage3(IBee bee, EnumBeeType type) { + + tempProductList = bee.getProduceList(); + + startPage(COLUMN_0, COLUMN_1, COLUMN_2); + + drawLine(StringUtil.localize("gui.beealyzer.produce") + ":", COLUMN_0); + + newLine(); + + int x = COLUMN_0; + for (ItemStack stack : tempProductList) { + itemRender.renderItemIntoGUI(fontRendererObj, mc.renderEngine, stack, (int) ((guiLeft + x) * (1 / factor)), + (int) ((guiTop + getLineY()) * (1 / factor))); + x += 18; + if (x > adjustToFactor(148)) { + x = COLUMN_0; + newLine(); + } + } + + newLine(); + newLine(); + + drawLine(StringUtil.localize("gui.beealyzer.specialty") + ":", COLUMN_0); + newLine(); + + x = COLUMN_0; + for (ItemStack stack : bee.getSpecialtyList()) { + itemRender.renderItemIntoGUI(fontRendererObj, mc.renderEngine, stack, (int) ((guiLeft + x) * (1 / factor)), + (int) ((guiTop + getLineY()) * (1 / factor))); + x += 18; + if (x > adjustToFactor(148)) { + x = COLUMN_0; + newLine(); + } + } + + endPage(); + } + +} diff --git a/forestry_common/apiculture/forestry/apiculture/gui/GuiHabitatLocator.java b/forestry_common/apiculture/forestry/apiculture/gui/GuiHabitatLocator.java new file mode 100755 index 000000000..c0d46344b --- /dev/null +++ b/forestry_common/apiculture/forestry/apiculture/gui/GuiHabitatLocator.java @@ -0,0 +1,189 @@ +/******************************************************************************* + * Copyright 2011-2014 by SirSengir + * + * This work is licensed under a Creative Commons Attribution-NonCommercial-NoDerivs 3.0 Unported License. + * + * To view a copy of this license, visit http://creativecommons.org/licenses/by-nc-nd/3.0/. + ******************************************************************************/ +package forestry.apiculture.gui; + +import java.util.ArrayList; +import java.util.HashMap; +import java.util.Locale; + +import net.minecraft.entity.player.EntityPlayer; +import net.minecraft.entity.player.InventoryPlayer; +import net.minecraft.util.IIcon; +import net.minecraft.world.biome.BiomeGenBase; + +import org.lwjgl.opengl.GL11; + +import forestry.apiculture.items.ItemBiomefinder.BiomefinderInventory; +import forestry.core.config.Defaults; +import forestry.core.gadgets.TileForestry; +import forestry.core.gui.GuiForestry; +import forestry.core.gui.widgets.Widget; +import forestry.core.proxy.Proxies; +import forestry.core.render.SpriteSheet; +import forestry.core.render.TextureManager; +import forestry.core.utils.StringUtil; + +public class GuiHabitatLocator extends GuiForestry { + + public class HabitatSlot extends Widget { + + private final int slot; + private final String name; + private final String iconIndex; + public boolean isActive = false; + + public HabitatSlot(int slot, String name) { + super(widgetManager, 0, 0); + this.slot = slot; + this.name = name; + this.iconIndex = "habitats/" + name.toLowerCase(Locale.ENGLISH); + } + + @Override + public String getLegacyTooltip(EntityPlayer player) { + return name; + } + + public IIcon getIcon() { + return TextureManager.getInstance().getDefault(iconIndex); + } + + public void setPosition(int x, int y) { + this.xPos = x; + this.yPos = y; + } + + @Override + public void draw(int startX, int startY) { + + if (getIcon() != null) { + GL11.glDisable(GL11.GL_LIGHTING); + + if (!isActive) + GL11.glColor4f(0.2f, 0.2f, 0.2f, 0.2f); + + Proxies.common.bindTexture(SpriteSheet.ITEMS); + manager.gui.drawTexturedModelRectFromIcon(startX + xPos, startY + yPos, getIcon(), 16, 16); + GL11.glEnable(GL11.GL_LIGHTING); + } + } + + } + + private final HabitatSlot[] habitatSlots = new HabitatSlot[] { new HabitatSlot(0, "Ocean"), // ocean + // + + // beach + new HabitatSlot(1, "Plains"), new HabitatSlot(2, "Desert"), // desert + // + + // desert + // hills + new HabitatSlot(3, "Forest"), // forest, forestHills, river + new HabitatSlot(4, "Jungle"), // jungle, jungleHills + new HabitatSlot(5, "Taiga"), // taiga, taigaHills + new HabitatSlot(6, "Hills"), // extremeHills, extremeHillsEdge + new HabitatSlot(7, "Swampland"), new HabitatSlot(8, "Snow"), // Ice + // plains, + // mountains, + // frozen + // rivers, + // frozen + // oceans + new HabitatSlot(9, "Mushroom"), // Ice plains, mountains, frozen + // rivers, frozen oceans + new HabitatSlot(10, "Hell"), new HabitatSlot(11, "End") }; + private final HashMap biomeToHabitat = new HashMap(); + + private int startX; + private int startY; + + public GuiHabitatLocator(InventoryPlayer inventory, BiomefinderInventory item) { + super(Defaults.TEXTURE_PATH_GUI + "/biomefinder.png", new ContainerHabitatLocator(inventory, item), item); + + xSize = 176; + ySize = 184; + + int x; + int y; + for (HabitatSlot slot : habitatSlots) { + + if (slot.slot > 5) { + x = 18 + (slot.slot - 6) * 20; + y = 50; + } else { + x = 18 + slot.slot * 20; + y = 32; + } + + slot.setPosition(x, y); + this.widgetManager.add(slot); + } + + biomeToHabitat.put(BiomeGenBase.ocean.biomeID, habitatSlots[0]); + biomeToHabitat.put(BiomeGenBase.beach.biomeID, habitatSlots[0]); + biomeToHabitat.put(BiomeGenBase.plains.biomeID, habitatSlots[1]); + biomeToHabitat.put(BiomeGenBase.desert.biomeID, habitatSlots[2]); + // biomeToHabitat.put(BiomeGenBase.desertHills.biomeID, + // habitatSlots[2]); // Removed for TFC compatibility + biomeToHabitat.put(BiomeGenBase.forest.biomeID, habitatSlots[3]); + biomeToHabitat.put(BiomeGenBase.forestHills.biomeID, habitatSlots[3]); + biomeToHabitat.put(BiomeGenBase.river.biomeID, habitatSlots[3]); + biomeToHabitat.put(BiomeGenBase.jungle.biomeID, habitatSlots[4]); + biomeToHabitat.put(BiomeGenBase.jungleHills.biomeID, habitatSlots[4]); + biomeToHabitat.put(BiomeGenBase.taiga.biomeID, habitatSlots[5]); + biomeToHabitat.put(BiomeGenBase.taigaHills.biomeID, habitatSlots[5]); + biomeToHabitat.put(BiomeGenBase.extremeHills.biomeID, habitatSlots[6]); + biomeToHabitat.put(BiomeGenBase.extremeHillsEdge.biomeID, habitatSlots[6]); + biomeToHabitat.put(BiomeGenBase.swampland.biomeID, habitatSlots[7]); + biomeToHabitat.put(BiomeGenBase.frozenOcean.biomeID, habitatSlots[8]); + biomeToHabitat.put(BiomeGenBase.frozenRiver.biomeID, habitatSlots[8]); + biomeToHabitat.put(BiomeGenBase.iceMountains.biomeID, habitatSlots[8]); + biomeToHabitat.put(BiomeGenBase.icePlains.biomeID, habitatSlots[8]); + biomeToHabitat.put(BiomeGenBase.mushroomIsland.biomeID, habitatSlots[9]); + biomeToHabitat.put(BiomeGenBase.mushroomIslandShore.biomeID, habitatSlots[9]); + biomeToHabitat.put(BiomeGenBase.hell.biomeID, habitatSlots[10]); + biomeToHabitat.put(BiomeGenBase.sky.biomeID, habitatSlots[11]); + } + + @Override + protected void drawGuiContainerBackgroundLayer(float var1, int mouseX, int mouseY) { + super.drawGuiContainerBackgroundLayer(var1, mouseX, mouseY); + + String str = StringUtil.localize("gui.habitatlocator").toUpperCase(); + fontRendererObj.drawString(str, startX + 8 + getCenteredOffset(str, 138), startY + 16, fontColor.get("gui.screen")); + + str = "(" + StringUtil.localize("gui.closetosearch") + ")"; + fontRendererObj.drawString(str, startX + 8 + getCenteredOffset(str, 138), startY + 76, fontColor.get("gui.table.header")); + + // Reset habitat slots + for (HabitatSlot slot : habitatSlots) + slot.isActive = false; + + // Set according to valid biomes. + ArrayList biomeids = ((ContainerHabitatLocator) inventorySlots).inventory.biomesToSearch; + for (int biomeid : biomeids) { + if (!biomeToHabitat.containsKey(biomeid)) + continue; + + biomeToHabitat.get(biomeid).isActive = true; + } + + for (HabitatSlot slot : habitatSlots) + slot.draw(startX, startY); + GL11.glColor4f(1.0f, 1.0f, 1.0f, 1.0f); // Reset afterwards. + + } + + @Override + public void initGui() { + super.initGui(); + + startX = (this.width - this.xSize) / 2; + startY = (this.height - this.ySize) / 2; + } + +} diff --git a/forestry_common/apiculture/forestry/apiculture/gui/GuiImprinter.java b/forestry_common/apiculture/forestry/apiculture/gui/GuiImprinter.java new file mode 100755 index 000000000..14d30e5ab --- /dev/null +++ b/forestry_common/apiculture/forestry/apiculture/gui/GuiImprinter.java @@ -0,0 +1,127 @@ +/******************************************************************************* + * Copyright 2011-2014 by SirSengir + * + * This work is licensed under a Creative Commons Attribution-NonCommercial-NoDerivs 3.0 Unported License. + * + * To view a copy of this license, visit http://creativecommons.org/licenses/by-nc-nd/3.0/. + ******************************************************************************/ +package forestry.apiculture.gui; + +import java.util.ArrayList; +import java.util.HashMap; + +import net.minecraft.entity.player.InventoryPlayer; +import net.minecraft.item.ItemStack; + +import forestry.api.apiculture.IAlleleBeeSpecies; +import forestry.apiculture.items.ItemBeeGE; +import forestry.apiculture.items.ItemImprinter.ImprinterInventory; +import forestry.core.config.Defaults; +import forestry.core.config.ForestryItem; +import forestry.core.gadgets.TileForestry; +import forestry.core.gui.GuiForestry; +import forestry.core.proxy.Proxies; +import forestry.plugins.PluginApiculture; + +public class GuiImprinter extends GuiForestry { + + private final ImprinterInventory inventory; + private final ContainerImprinter container; + + private int startX; + private int startY; + + private final HashMap iconStacks = new HashMap(); + + public GuiImprinter(InventoryPlayer inventoryplayer, ImprinterInventory inventory) { + super(Defaults.TEXTURE_PATH_GUI + "/imprinter.png", new ContainerImprinter(inventoryplayer, inventory), inventory); + + this.inventory = inventory; + this.container = (ContainerImprinter) inventorySlots; + + xSize = 176; + ySize = 185; + + ArrayList beeList = new ArrayList(); + ((ItemBeeGE) ForestryItem.beeDroneGE.item()).addCreativeItems(beeList, false); + for (ItemStack beeStack : beeList) + iconStacks.put(PluginApiculture.beeInterface.getMember(beeStack).getIdent(), beeStack); + + } + + @Override + protected void drawGuiContainerBackgroundLayer(float var1, int mouseX, int mouseY) { + container.updateContainer(Proxies.common.getRenderWorld()); + super.drawGuiContainerBackgroundLayer(var1, mouseX, mouseY); + + int offset = (138 - fontRendererObj.getStringWidth("GENOME IMPRINTER")) / 2; + fontRendererObj.drawString("GENOME IMPRINTER", startX + 8 + offset, startY + 16, fontColor.get("gui.screen")); + + IAlleleBeeSpecies primary = inventory.getPrimary(); + drawBeeSpeciesIcon(primary, startX + 12, startY + 32); + fontRendererObj.drawString(primary.getName(), startX + 32, startY + 36, fontColor.get("gui.screen")); + + IAlleleBeeSpecies secondary = inventory.getSecondary(); + drawBeeSpeciesIcon(secondary, startX + 12, startY + 52); + fontRendererObj.drawString(secondary.getName(), startX + 32, startY + 56, fontColor.get("gui.screen")); + + String youCheater = "(You Cheater!)"; + offset = (138 - fontRendererObj.getStringWidth(youCheater)) / 2; + fontRendererObj.drawString(youCheater, startX + 8 + offset, startY + 76, fontColor.get("gui.screen")); + + } + + private void drawBeeSpeciesIcon(IAlleleBeeSpecies bee, int x, int y) { + + /* + * GL11.glDisable(GL11.GL_LIGHTING); mc.renderEngine.func_98187_b(Defaults.TEXTURE_BEES); + * + * for (int i = 0; i < ForestryItem.beeDroneGE.getRenderPasses(0); ++i) { + * + * int iconIndex = ForestryItem.beeDroneGE.getIconIndex(iconStacks.get(bee.getUID()), i); int color = ((ItemGE) + * ForestryItem.beeDroneGE).getColorFromItemStack(iconStacks.get(bee.getUID()), i); float colorR = (color >> 16 & 255) / 255.0F; float colorG = (color + * >> 8 & 255) / 255.0F; float colorB = (color & 255) / 255.0F; + * + * GL11.glColor4f(colorR, colorG, colorB, 1.0F); drawTexturedModalRect(x, y, iconIndex % 16 * 16, iconIndex / 16 * 16, 16, 16); + * + * } GL11.glEnable(GL11.GL_LIGHTING); + */ + + } + + private int getHabitatSlotAtPosition(int i, int j) { + int[] xPos = new int[] { 12, 12 }; + int[] yPos = new int[] { 32, 52 }; + + for (int l = 0; l < xPos.length; l++) + if (i >= xPos[l] && i <= xPos[l] + 16 && j >= yPos[l] && j <= yPos[l] + 16) + return l; + + return -1; + } + + @Override + protected void mouseClicked(int i, int j, int k) { + super.mouseClicked(i, j, k); + + int cornerX = (width - xSize) / 2; + int cornerY = (height - ySize) / 2; + + int slot = 0; + if ((slot = getHabitatSlotAtPosition(i - cornerX, j - cornerY)) < 0) + return; + + if (k == 0) + container.advanceSelection(slot, Proxies.common.getRenderWorld()); + else + container.regressSelection(slot, Proxies.common.getRenderWorld()); + } + + @Override + public void initGui() { + super.initGui(); + + startX = (this.width - this.xSize) / 2; + startY = (this.height - this.ySize) / 2; + } +} diff --git a/forestry_common/apiculture/forestry/apiculture/items/ItemAlvearyBlock.java b/forestry_common/apiculture/forestry/apiculture/items/ItemAlvearyBlock.java new file mode 100755 index 000000000..62034381b --- /dev/null +++ b/forestry_common/apiculture/forestry/apiculture/items/ItemAlvearyBlock.java @@ -0,0 +1,24 @@ +/******************************************************************************* + * Copyright 2011-2014 by SirSengir + * + * This work is licensed under a Creative Commons Attribution-NonCommercial-NoDerivs 3.0 Unported License. + * + * To view a copy of this license, visit http://creativecommons.org/licenses/by-nc-nd/3.0/. + ******************************************************************************/ +package forestry.apiculture.items; + +import net.minecraft.block.Block; + +import forestry.core.gadgets.IStructureBlockItem; +import forestry.core.items.ItemForestryBlock; + +/** + * + * @author CovertJaguar + */ +public class ItemAlvearyBlock extends ItemForestryBlock implements IStructureBlockItem { + + public ItemAlvearyBlock(Block block) { + super(block); + } +} diff --git a/forestry_common/apiculture/forestry/apiculture/items/ItemArmorApiarist.java b/forestry_common/apiculture/forestry/apiculture/items/ItemArmorApiarist.java new file mode 100755 index 000000000..71ef94a36 --- /dev/null +++ b/forestry_common/apiculture/forestry/apiculture/items/ItemArmorApiarist.java @@ -0,0 +1,125 @@ +/******************************************************************************* + * Copyright 2011-2014 by SirSengir + * + * This work is licensed under a Creative Commons Attribution-NonCommercial-NoDerivs 3.0 Unported License. + * + * To view a copy of this license, visit http://creativecommons.org/licenses/by-nc-nd/3.0/. + ******************************************************************************/ +package forestry.apiculture.items; + +import net.minecraft.client.renderer.texture.IIconRegister; +import net.minecraft.entity.Entity; +import net.minecraft.entity.player.EntityPlayer; +import net.minecraft.item.ItemArmor; +import net.minecraft.item.ItemStack; +import net.minecraft.util.IIcon; + +import cpw.mods.fml.relauncher.Side; +import cpw.mods.fml.relauncher.SideOnly; + +import forestry.api.apiculture.IArmorApiarist; +import forestry.api.core.IArmorNaturalist; +import forestry.api.core.Tabs; +import forestry.core.config.Defaults; +import forestry.core.config.ForestryItem; +import forestry.core.render.TextureManager; +import forestry.core.utils.StringUtil; + +public class ItemArmorApiarist extends ItemArmor implements IArmorApiarist, IArmorNaturalist { + + public ItemArmorApiarist(int slot) { + super(ArmorMaterial.CLOTH, 0, slot); + this.setMaxDamage(100); + setCreativeTab(Tabs.tabApiculture); + } + + @Override + public String getArmorTexture(ItemStack stack, Entity entity, int slot, String type) { + if (ForestryItem.apiaristLegs.isItemEqual(stack)) + return Defaults.ID + ":" + Defaults.TEXTURE_APIARIST_ARMOR_SECONDARY; + else + return Defaults.ID + ":" + Defaults.TEXTURE_APIARIST_ARMOR_PRIMARY; + } + + @Override + public String getItemStackDisplayName(ItemStack itemstack) { + return StringUtil.localize(getUnlocalizedName(itemstack)); + } + + @SideOnly(Side.CLIENT) + @Override + public void registerIcons(IIconRegister register) { + itemIcon = TextureManager.getInstance().registerTex(register, getUnlocalizedName().replace("item.", "")); + } + + @SideOnly(Side.CLIENT) + @Override + public IIcon getIconFromDamageForRenderPass(int par1, int par2) { + return itemIcon; + } + + @Override + public boolean requiresMultipleRenderPasses() { + return false; + } + + @Override + public int getColorFromItemStack(ItemStack itemstack, int renderPass) { + return 0xffffff; + } + + @Override + public boolean hasColor(ItemStack itemstack) { + return false; + } + + @Override + public boolean protectPlayer(EntityPlayer player, ItemStack armor, String cause, boolean doProtect) { + return true; + } + + @Override + public boolean canSeePollination(EntityPlayer player, ItemStack armor, boolean doSee) { + return armorType == 0; + } + + public static boolean wearsHelmet(EntityPlayer player, String cause, boolean protect) { + ItemStack armorItem = player.inventory.armorInventory[3]; + return armorItem != null && armorItem.getItem() instanceof IArmorApiarist + && ((IArmorApiarist) armorItem.getItem()).protectPlayer(player, armorItem, cause, protect); + } + + public static boolean wearsChest(EntityPlayer player, String cause, boolean protect) { + ItemStack armorItem = player.inventory.armorInventory[2]; + return armorItem != null && armorItem.getItem() instanceof IArmorApiarist + && ((IArmorApiarist) armorItem.getItem()).protectPlayer(player, armorItem, cause, protect); + } + + public static boolean wearsLegs(EntityPlayer player, String cause, boolean protect) { + ItemStack armorItem = player.inventory.armorInventory[1]; + return armorItem != null && armorItem.getItem() instanceof IArmorApiarist + && ((IArmorApiarist) armorItem.getItem()).protectPlayer(player, armorItem, cause, protect); + } + + public static boolean wearsBoots(EntityPlayer player, String cause, boolean protect) { + ItemStack armorItem = player.inventory.armorInventory[0]; + return armorItem != null && armorItem.getItem() instanceof IArmorApiarist + && ((IArmorApiarist) armorItem.getItem()).protectPlayer(player, armorItem, cause, protect); + } + + public static int wearsItems(EntityPlayer player, String cause, boolean protect) { + int count = 0; + + if (wearsHelmet(player, cause, protect)) + count++; + if (wearsChest(player, cause, protect)) + count++; + if (wearsLegs(player, cause, protect)) + count++; + if (wearsBoots(player, cause, protect)) + count++; + + return count; + } + +} diff --git a/forestry_common/apiculture/forestry/apiculture/items/ItemBeeGE.java b/forestry_common/apiculture/forestry/apiculture/items/ItemBeeGE.java new file mode 100755 index 000000000..48482b72d --- /dev/null +++ b/forestry_common/apiculture/forestry/apiculture/items/ItemBeeGE.java @@ -0,0 +1,168 @@ +/******************************************************************************* + * Copyright 2011-2014 by SirSengir + * + * This work is licensed under a Creative Commons Attribution-NonCommercial-NoDerivs 3.0 Unported License. + * + * To view a copy of this license, visit http://creativecommons.org/licenses/by-nc-nd/3.0/. + ******************************************************************************/ +package forestry.apiculture.items; + +import java.util.List; + +import net.minecraft.client.renderer.texture.IIconRegister; +import net.minecraft.creativetab.CreativeTabs; +import net.minecraft.entity.player.EntityPlayer; +import net.minecraft.item.Item; +import net.minecraft.item.ItemStack; +import net.minecraft.nbt.NBTTagCompound; +import net.minecraft.util.IIcon; + +import cpw.mods.fml.relauncher.Side; +import cpw.mods.fml.relauncher.SideOnly; + +import forestry.api.apiculture.EnumBeeChromosome; +import forestry.api.apiculture.EnumBeeType; +import forestry.api.apiculture.IAlleleBeeSpecies; +import forestry.api.apiculture.IBee; +import forestry.api.core.Tabs; +import forestry.api.genetics.AlleleManager; +import forestry.api.genetics.IAllele; +import forestry.api.genetics.IAlleleSpecies; +import forestry.api.genetics.IIndividual; +import forestry.apiculture.genetics.Bee; +import forestry.core.config.Config; +import forestry.core.genetics.ItemGE; +import forestry.core.utils.StringUtil; +import forestry.plugins.PluginApiculture; + +public class ItemBeeGE extends ItemGE { + + EnumBeeType type; + + public ItemBeeGE(EnumBeeType type) { + super(); + this.type = type; + setCreativeTab(Tabs.tabApiculture); + if (type != EnumBeeType.DRONE) + setMaxStackSize(1); + } + + @Override + protected IIndividual getIndividual(ItemStack itemstack) { + return new Bee(itemstack.getTagCompound()); + } + + @Override + protected int getDefaultPrimaryColour() { + return 0xffffff; + } + + @Override + protected int getDefaultSecondaryColour() { + return 0xffdc16; + } + + @Override + public String getItemStackDisplayName(ItemStack itemstack) { + + if (itemstack.getTagCompound() == null) + return StringUtil.localize(type.getName()); + + IBee individual = new Bee(itemstack.getTagCompound()); + return individual.getDisplayName() + StringUtil.localize(type.getName() + ".adj.add") + " " + StringUtil.localize(type.getName()); + } + + @SuppressWarnings({ "rawtypes", "unchecked" }) + @Override + public void addInformation(ItemStack itemstack, EntityPlayer player, List list, boolean flag) { + if(!itemstack.hasTagCompound()) + return; + + if(type != EnumBeeType.DRONE) { + IBee individual = new Bee(itemstack.getTagCompound()); + if (individual.isNatural()) + list.add("\u00A7e\u00A7o" + StringUtil.localize("bees.stock.pristine")); + else + list.add("\u00A7e" + StringUtil.localize("bees.stock.ignoble")); + } + + super.addInformation(itemstack, player, list, flag); + } + + @SuppressWarnings("rawtypes") + @Override + public void getSubItems(Item item, CreativeTabs par2CreativeTabs, List itemList) { + if (type == EnumBeeType.QUEEN) + return; + + addCreativeItems(itemList, true); + } + + @SuppressWarnings({ "rawtypes", "unchecked" }) + public void addCreativeItems(List itemList, boolean hideSecrets) { + + for (IIndividual individual : PluginApiculture.beeInterface.getIndividualTemplates()) { + // Don't show secret bees unless ordered to. + if (hideSecrets && individual.isSecret() && !Config.isDebug) + continue; + + NBTTagCompound nbttagcompound = new NBTTagCompound(); + ItemStack someStack = new ItemStack(this); + individual.writeToNBT(nbttagcompound); + someStack.setTagCompound(nbttagcompound); + itemList.add(someStack); + } + } + + /* RENDERING */ + @Override + public int getColorFromItemStack(ItemStack itemstack, int renderPass) { + if (!itemstack.hasTagCompound()) + return super.getColorFromItemStack(itemstack, renderPass); + + return getColourFromSpecies(PluginApiculture.beeInterface.getMember(itemstack).getGenome().getPrimary(), renderPass); + } + + @Override + public int getColourFromSpecies(IAlleleSpecies species, int renderPass) { + + if (species != null && species instanceof IAlleleBeeSpecies) + return ((IAlleleBeeSpecies) species).getIconColour(renderPass); + else + return 0xffffff; + + } + + @Override + public boolean requiresMultipleRenderPasses() { + return true; + } + + @Override + public int getRenderPasses(int metadata) { + return 3; + } + + /* ICONS */ + @Override + @SideOnly(Side.CLIENT) + public void registerIcons(IIconRegister register) { + for (IAllele allele : AlleleManager.alleleRegistry.getRegisteredAlleles().values()) + if (allele instanceof IAlleleBeeSpecies) + ((IAlleleBeeSpecies) allele).getIconProvider().registerIcons(register); + } + + @SideOnly(Side.CLIENT) + @Override + public IIcon getIcon(ItemStack itemstack, int renderPass) { + return getIconFromSpecies(PluginApiculture.beeInterface.getMember(itemstack).getGenome().getPrimary(), renderPass); + } + + @SideOnly(Side.CLIENT) + public IIcon getIconFromSpecies(IAlleleBeeSpecies species, int renderPass) { + if (species == null) + species = (IAlleleBeeSpecies) PluginApiculture.beeInterface.getDefaultTemplate()[EnumBeeChromosome.SPECIES.ordinal()]; + + return species.getIcon(type, renderPass); + } +} diff --git a/forestry_common/apiculture/forestry/apiculture/items/ItemBeealyzer.java b/forestry_common/apiculture/forestry/apiculture/items/ItemBeealyzer.java new file mode 100755 index 000000000..8980f1365 --- /dev/null +++ b/forestry_common/apiculture/forestry/apiculture/items/ItemBeealyzer.java @@ -0,0 +1,164 @@ +/******************************************************************************* + * Copyright 2011-2014 by SirSengir + * + * This work is licensed under a Creative Commons Attribution-NonCommercial-NoDerivs 3.0 Unported License. + * + * To view a copy of this license, visit http://creativecommons.org/licenses/by-nc-nd/3.0/. + ******************************************************************************/ +package forestry.apiculture.items; + +import net.minecraft.entity.player.EntityPlayer; +import net.minecraft.item.ItemStack; +import net.minecraft.nbt.NBTTagCompound; +import net.minecraft.nbt.NBTTagList; +import net.minecraft.world.World; + +import forestry.api.apiculture.IBee; +import forestry.api.core.ForestryAPI; +import forestry.api.core.Tabs; +import forestry.core.EnumErrorCode; +import forestry.core.config.Config; +import forestry.core.config.ForestryItem; +import forestry.core.interfaces.IErrorSource; +import forestry.core.interfaces.IHintSource; +import forestry.core.items.ItemInventoried; +import forestry.core.network.GuiId; +import forestry.core.proxy.Proxies; +import forestry.core.utils.ItemInventory; +import forestry.plugins.PluginApiculture; + +public class ItemBeealyzer extends ItemInventoried { + + public static class BeealyzerInventory extends ItemInventory implements IErrorSource, IHintSource { + + public static final int SLOT_SPECIMEN = 0; + public static final int SLOT_ANALYZE_1 = 1; + public static final int SLOT_ANALYZE_2 = 2; + public static final int SLOT_ANALYZE_3 = 3; + public static final int SLOT_ANALYZE_4 = 4; + public static final int SLOT_ANALYZE_5 = 6; + public static final int SLOT_ENERGY = 5; + + EntityPlayer player; + + public BeealyzerInventory(EntityPlayer player) { + super(ItemBeealyzer.class, 7); + this.player = player; + } + + public BeealyzerInventory(EntityPlayer player, ItemStack itemStack) { + super(ItemBeealyzer.class, 7, itemStack); + this.player = player; + } + + @Override + public void writeToNBT(NBTTagCompound nbttagcompound) { + + NBTTagList nbttaglist = new NBTTagList(); + for (int i = SLOT_ENERGY; i < SLOT_ENERGY + 1; i++) + if (inventoryStacks[i] != null) { + NBTTagCompound nbttagcompound1 = new NBTTagCompound(); + nbttagcompound1.setByte("Slot", (byte) i); + inventoryStacks[i].writeToNBT(nbttagcompound1); + nbttaglist.appendTag(nbttagcompound1); + } + nbttagcompound.setTag("Items", nbttaglist); + + } + + private boolean isEnergy(ItemStack itemstack) { + if (itemstack == null || itemstack.stackSize <= 0) + return false; + + return ForestryItem.honeyDrop.isItemEqual(itemstack) || ForestryItem.honeydew.isItemEqual(itemstack); + } + + private void tryAnalyze() { + + // Analyzed slot occupied, abort + if (inventoryStacks[SLOT_ANALYZE_1] != null || inventoryStacks[SLOT_ANALYZE_2] != null || inventoryStacks[SLOT_ANALYZE_3] != null + || inventoryStacks[SLOT_ANALYZE_4] != null || inventoryStacks[SLOT_ANALYZE_5] != null) + return; + + // Source slot to analyze empty + if (getStackInSlot(SLOT_SPECIMEN) == null) + return; + + IBee bee = PluginApiculture.beeInterface.getMember(getStackInSlot(SLOT_SPECIMEN)); + // No bee, abort + if (bee == null) + return; + + // Analyze if necessary + if (!bee.isAnalyzed()) { + + // Requires energy + if (!isEnergy(getStackInSlot(SLOT_ENERGY))) + return; + + bee.analyze(); + if(player != null) { + PluginApiculture.beeInterface.getBreedingTracker(player.worldObj, player.getGameProfile().getId()).registerSpecies(bee.getGenome().getPrimary()); + PluginApiculture.beeInterface.getBreedingTracker(player.worldObj, player.getGameProfile().getId()).registerSpecies(bee.getGenome().getSecondary()); + } + + NBTTagCompound nbttagcompound = new NBTTagCompound(); + bee.writeToNBT(nbttagcompound); + getStackInSlot(SLOT_SPECIMEN).setTagCompound(nbttagcompound); + + // Decrease energy + decrStackSize(SLOT_ENERGY, 1); + } + + setInventorySlotContents(SLOT_ANALYZE_1, getStackInSlot(SLOT_SPECIMEN)); + setInventorySlotContents(SLOT_SPECIMEN, null); + } + + @Override + public void markDirty() { + // if (!Proxies.common.isSimulating(player.worldObj)) + // return; + tryAnalyze(); + } + + // / IHINTSOURCE + @Override + public boolean hasHints() { + return Config.hints.get("beealyzer") != null && Config.hints.get("beealyzer").length > 0; + } + + @Override + public String[] getHints() { + return Config.hints.get("beealyzer"); + } + + // / IERRORSOURCE + @Override + public boolean throwsErrors() { + return true; + } + + @Override + public EnumErrorCode getErrorState() { + if (PluginApiculture.beeInterface.isMember(inventoryStacks[SLOT_SPECIMEN]) && !isEnergy(getStackInSlot(SLOT_ENERGY))) + return EnumErrorCode.NOHONEY; + + return EnumErrorCode.OK; + } + } + + public ItemBeealyzer() { + super(); + setMaxStackSize(1); + setCreativeTab(Tabs.tabApiculture); + } + + @Override + public ItemStack onItemRightClick(ItemStack itemstack, World world, EntityPlayer entityplayer) { + if (Proxies.common.isSimulating(world)) + entityplayer.openGui(ForestryAPI.instance, GuiId.BeealyzerGUI.ordinal(), world, (int) entityplayer.posX, (int) entityplayer.posY, + (int) entityplayer.posZ); + + return itemstack; + } +} diff --git a/forestry_common/apiculture/forestry/apiculture/items/ItemBiomefinder.java b/forestry_common/apiculture/forestry/apiculture/items/ItemBiomefinder.java new file mode 100755 index 000000000..e24ba02d2 --- /dev/null +++ b/forestry_common/apiculture/forestry/apiculture/items/ItemBiomefinder.java @@ -0,0 +1,237 @@ +/******************************************************************************* + * Copyright 2011-2014 by SirSengir + * + * This work is licensed under a Creative Commons Attribution-NonCommercial-NoDerivs 3.0 Unported License. + * + * To view a copy of this license, visit http://creativecommons.org/licenses/by-nc-nd/3.0/. + ******************************************************************************/ +package forestry.apiculture.items; + +import java.util.ArrayList; + +import net.minecraft.client.renderer.texture.IIconRegister; +import net.minecraft.client.renderer.texture.TextureAtlasSprite; +import net.minecraft.client.renderer.texture.TextureMap; +import net.minecraft.entity.player.EntityPlayer; +import net.minecraft.item.ItemStack; +import net.minecraft.nbt.NBTTagCompound; +import net.minecraft.nbt.NBTTagList; +import net.minecraft.util.ChunkCoordinates; +import net.minecraft.world.World; +import net.minecraft.world.biome.BiomeGenBase; + +import cpw.mods.fml.relauncher.Side; +import cpw.mods.fml.relauncher.SideOnly; + +import forestry.api.apiculture.IBee; +import forestry.api.core.ForestryAPI; +import forestry.api.core.Tabs; +import forestry.apiculture.render.TextureBiomefinder; +import forestry.core.EnumErrorCode; +import forestry.core.config.Config; +import forestry.core.config.ForestryItem; +import forestry.core.interfaces.IErrorSource; +import forestry.core.interfaces.IHintSource; +import forestry.core.items.ItemInventoried; +import forestry.core.network.GuiId; +import forestry.core.proxy.Proxies; +import forestry.core.utils.ItemInventory; +import forestry.core.utils.Vect; +import forestry.plugins.PluginApiculture; + +public class ItemBiomefinder extends ItemInventoried { + + public static class BiomefinderInventory extends ItemInventory implements IErrorSource, IHintSource { + + public ArrayList biomesToSearch = new ArrayList(); + + private final short energySlot = 2; + private final short specimenSlot = 0; + private final short analyzeSlot = 1; + + public BiomefinderInventory() { + super(ItemBiomefinder.class, 3); + } + + public BiomefinderInventory(ItemStack itemstack) { + super(ItemBiomefinder.class, 3, itemstack); + } + + @Override + public void writeToNBT(NBTTagCompound nbttagcompound) { + + NBTTagList nbttaglist = new NBTTagList(); + for (int i = 2; i < inventoryStacks.length; i++) + if (inventoryStacks[i] != null) { + NBTTagCompound nbttagcompound1 = new NBTTagCompound(); + nbttagcompound1.setByte("Slot", (byte) i); + inventoryStacks[i].writeToNBT(nbttagcompound1); + nbttaglist.appendTag(nbttagcompound1); + } + nbttagcompound.setTag("Items", nbttaglist); + + } + + private boolean isEnergy(ItemStack itemstack) { + if (itemstack == null || itemstack.stackSize <= 0) + return false; + + return ForestryItem.honeyDrop.isItemEqual(itemstack) || ForestryItem.honeydew.isItemEqual(itemstack); + } + + private void tryAnalyze() { + + // Analyzed slot occupied, abort + if (inventoryStacks[analyzeSlot] != null) + return; + + // Source slot to analyze empty + if (getStackInSlot(specimenSlot) == null) + return; + + IBee bee = PluginApiculture.beeInterface.getMember(getStackInSlot(specimenSlot)); + // No bee, abort + if (bee == null) + return; + + // Requires energy + if (!isEnergy(getStackInSlot(energySlot))) + return; + + biomesToSearch = bee.getSuitableBiomeIds(); + + // Decrease energy + decrStackSize(energySlot, 1); + + setInventorySlotContents(analyzeSlot, getStackInSlot(specimenSlot)); + setInventorySlotContents(specimenSlot, null); + } + + @Override + public void markDirty() { + tryAnalyze(); + } + + // / IHINTSOURCE + @Override + public boolean hasHints() { + return Config.hints.get("habitatlocator") != null && Config.hints.get("habitatlocator").length > 0; + } + + @Override + public String[] getHints() { + return Config.hints.get("habitatlocator"); + } + + // / IERRORSOURCE + @Override + public boolean throwsErrors() { + return true; + } + + @Override + public EnumErrorCode getErrorState() { + if (PluginApiculture.beeInterface.isMember(inventoryStacks[specimenSlot]) && !isEnergy(getStackInSlot(energySlot))) + return EnumErrorCode.NOHONEY; + + return EnumErrorCode.OK; + } + + } + + public ItemBiomefinder() { + super(); + setMaxStackSize(1); + setCreativeTab(Tabs.tabApiculture); + } + + @Override + public ItemStack onItemRightClick(ItemStack itemstack, World world, EntityPlayer entityplayer) { + + if (Proxies.common.isSimulating(world)) + entityplayer.openGui(ForestryAPI.instance, GuiId.HabitatLocatorGUI.ordinal(), world, (int) entityplayer.posX, (int) entityplayer.posY, + (int) entityplayer.posZ); + + return itemstack; + } + + public void startBiomeSearch(World world, EntityPlayer player, ArrayList biomesToSearch) { + + ArrayList excludedBiomes = new ArrayList(); + excludedBiomes.add(BiomeGenBase.ocean.biomeID); + excludedBiomes.add(BiomeGenBase.frozenOcean.biomeID); + excludedBiomes.add(BiomeGenBase.beach.biomeID); + biomesToSearch.removeAll(excludedBiomes); + + // If we are in a valid biome, we point to ourself. + BiomeGenBase biome = world.getBiomeGenForCoords((int) player.posX, (int) player.posZ); + if (biomesToSearch.contains(biome.biomeID)) { + Proxies.common.setBiomefinderCoordinates(player, new ChunkCoordinates((int) player.posX, (int) player.posY, (int) player.posZ)); + return; + } + + if (Proxies.common.isSimulating(world) && biomesToSearch.size() > 0) { + ChunkCoordinates target = findNearestBiome(player, biomesToSearch); + Proxies.common.setBiomefinderCoordinates(player, target); + } + + } + + private ChunkCoordinates findNearestBiome(EntityPlayer player, ArrayList biomesToSearch) { + + int loadChunkDistance = 25; + ChunkCoordinates coordinates = null; + Vect pos = new Vect((int) player.posX, (int) player.posY, (int) player.posZ); + for (int i = 0; i < 100; i++) { + // Test direction +X + if ((coordinates = getChunkCoordinates(pos.add(new Vect(10 * i, 0, 0)), player.worldObj, biomesToSearch, i < loadChunkDistance)) != null) + return coordinates; + // Test direction +X+Z + if ((coordinates = getChunkCoordinates(pos.add(new Vect(10 * i, 0, 10 * i)), player.worldObj, biomesToSearch, i < loadChunkDistance)) != null) + return coordinates; + // Test direction +X-Z + if ((coordinates = getChunkCoordinates(pos.add(new Vect(10 * i, 0, -10 * i)), player.worldObj, biomesToSearch, i < loadChunkDistance)) != null) + return coordinates; + + // Test direction -X + if ((coordinates = getChunkCoordinates(pos.add(new Vect(-10 * i, 0, 0)), player.worldObj, biomesToSearch, i < loadChunkDistance)) != null) + return coordinates; + // Test direction -X+Z + if ((coordinates = getChunkCoordinates(pos.add(new Vect(-10 * i, 0, 10 * i)), player.worldObj, biomesToSearch, i < loadChunkDistance)) != null) + return coordinates; + // Test direction -X-Z + if ((coordinates = getChunkCoordinates(pos.add(new Vect(-10 * i, 0, -10 * i)), player.worldObj, biomesToSearch, i < loadChunkDistance)) != null) + return coordinates; + + // Test direction +Z + if ((coordinates = getChunkCoordinates(pos.add(new Vect(0, 0, 10 * i)), player.worldObj, biomesToSearch, i < loadChunkDistance)) != null) + return coordinates; + // Test direction -Z + if ((coordinates = getChunkCoordinates(pos.add(new Vect(0, 0, -10 * i)), player.worldObj, biomesToSearch, i < loadChunkDistance)) != null) + return coordinates; + } + return coordinates; + } + + private ChunkCoordinates getChunkCoordinates(Vect pos, World world, ArrayList biomesToSearch, boolean loadChunks) { + + BiomeGenBase biome = world.getBiomeGenForCoords(pos.x, pos.z); + + if (biomesToSearch.contains(biome.biomeID)) + return new ChunkCoordinates(pos.x, pos.y, pos.z); + + return null; + } + + /* TEXTURES */ + @SideOnly(Side.CLIENT) + @Override + public void registerIcons(IIconRegister register) { + if(register instanceof TextureMap) { + TextureAtlasSprite texture = new TextureBiomefinder(); + ((TextureMap)register).setTextureEntry("forestry:biomefinder", texture); + itemIcon = texture; + } + } + +} diff --git a/forestry_common/apiculture/forestry/apiculture/items/ItemCandleBlock.java b/forestry_common/apiculture/forestry/apiculture/items/ItemCandleBlock.java new file mode 100755 index 000000000..f54bdb40d --- /dev/null +++ b/forestry_common/apiculture/forestry/apiculture/items/ItemCandleBlock.java @@ -0,0 +1,73 @@ +/******************************************************************************* + * Copyright 2011-2014 by SirSengir + * + * This work is licensed under a Creative Commons Attribution-NonCommercial-NoDerivs 3.0 Unported License. + * + * To view a copy of this license, visit http://creativecommons.org/licenses/by-nc-nd/3.0/. + ******************************************************************************/ +package forestry.apiculture.items; + +import net.minecraft.block.Block; +import net.minecraft.item.ItemStack; +import net.minecraft.nbt.NBTTagCompound; +import net.minecraft.util.IIcon; + +import cpw.mods.fml.relauncher.Side; +import cpw.mods.fml.relauncher.SideOnly; + +import forestry.apiculture.gadgets.BlockCandle; +import forestry.core.items.ItemForestryBlock; + +public class ItemCandleBlock extends ItemForestryBlock { + + public ItemCandleBlock(Block block) { + super(block); + } + + @Override + @SideOnly(Side.CLIENT) + public int getColorFromItemStack(ItemStack stack, int pass) { + int value = 0xffffff; + if (pass == 1 && stack.hasTagCompound()) { + NBTTagCompound tag = stack.getTagCompound(); + if (tag.hasKey("colour")) { + value = tag.getInteger("colour"); + } + } + return value; + } + + @Override + public String getUnlocalizedName(ItemStack itemStack) { + String value = "tile.candle"; + if (itemStack.hasTagCompound() && itemStack.getTagCompound().hasKey(BlockCandle.colourTagName)) { + value = value + ".dyed"; + } + + if (BlockCandle.isLit(itemStack)) { + value = value + ".lit"; + } + else { + value = value + ".stump"; + } + return value; + } + + @Override + @SideOnly(Side.CLIENT) + public IIcon getIconFromDamageForRenderPass(int meta, int pass) { + return ((BlockCandle)this.getBlock()).getTextureFromPassAndMeta((meta != 0) ? 8 : 0, pass); + } + + @Override + @SideOnly(Side.CLIENT) + public boolean requiresMultipleRenderPasses() { + return true; + } + + @Override + public int getRenderPasses(int metadata) { + return 2; + } + +} diff --git a/forestry_common/apiculture/forestry/apiculture/items/ItemHiveFrame.java b/forestry_common/apiculture/forestry/apiculture/items/ItemHiveFrame.java new file mode 100755 index 000000000..b2f5c2300 --- /dev/null +++ b/forestry_common/apiculture/forestry/apiculture/items/ItemHiveFrame.java @@ -0,0 +1,95 @@ +/******************************************************************************* + * Copyright 2011-2014 by SirSengir + * + * This work is licensed under a Creative Commons Attribution-NonCommercial-NoDerivs 3.0 Unported License. + * + * To view a copy of this license, visit http://creativecommons.org/licenses/by-nc-nd/3.0/. + ******************************************************************************/ +package forestry.apiculture.items; + +import net.minecraft.item.ItemStack; + +import forestry.api.apiculture.IBee; +import forestry.api.apiculture.IBeeGenome; +import forestry.api.apiculture.IBeeHousing; +import forestry.api.apiculture.IHiveFrame; +import forestry.api.core.Tabs; +import forestry.core.items.ItemForestry; + +public class ItemHiveFrame extends ItemForestry implements IHiveFrame { + + private final float geneticDecay; + + public ItemHiveFrame(int maxDamage, float geneticDecay) { + super(); + setMaxStackSize(1); + setMaxDamage(maxDamage); + this.geneticDecay = geneticDecay; + setCreativeTab(Tabs.tabApiculture); + } + + @Override + public ItemStack frameUsed(IBeeHousing housing, ItemStack frame, IBee queen, int wear) { + frame.setItemDamage(frame.getItemDamage() + wear); + if (frame.getItemDamage() >= frame.getMaxDamage()) + return null; + else + return frame; + } + + @Override + public float getTerritoryModifier(IBeeGenome genome, float currentModifier) { + return 1.0f; + } + + @Override + public float getMutationModifier(IBeeGenome genome, IBeeGenome mate, float currentModifier) { + return 1.0f; + } + + @Override + public float getLifespanModifier(IBeeGenome genome, IBeeGenome mate, float currentModifier) { + return 1.0f; + } + + @Override + public float getProductionModifier(IBeeGenome genome, float currentModifier) { + return currentModifier < 10f ? 2.0f : 1f; + } + + @Override + public float getFloweringModifier(IBeeGenome genome, float currentModifier) { + return 1.0f; + } + + @Override + public float getGeneticDecay(IBeeGenome genome, float currentModifier) { + return this.geneticDecay; + } + + @Override + public boolean isSealed() { + return false; + } + + @Override + public boolean isSelfLighted() { + return false; + } + + @Override + public boolean isSunlightSimulated() { + return false; + } + + @Override + public boolean isHellish() { + return false; + } + + @Override + public boolean isBookEnchantable(ItemStack itemstack1, ItemStack itemstack2) { + return false; + } + +} diff --git a/forestry_common/apiculture/forestry/apiculture/items/ItemHoneycomb.java b/forestry_common/apiculture/forestry/apiculture/items/ItemHoneycomb.java new file mode 100755 index 000000000..1c6ed9e25 --- /dev/null +++ b/forestry_common/apiculture/forestry/apiculture/items/ItemHoneycomb.java @@ -0,0 +1,158 @@ +/******************************************************************************* + * Copyright 2011-2014 by SirSengir + * + * This work is licensed under a Creative Commons Attribution-NonCommercial-NoDerivs 3.0 Unported License. + * + * To view a copy of this license, visit http://creativecommons.org/licenses/by-nc-nd/3.0/. + ******************************************************************************/ +package forestry.apiculture.items; + +import java.util.ArrayList; +import java.util.List; +import java.util.Random; + +import net.minecraft.client.renderer.texture.IIconRegister; +import net.minecraft.creativetab.CreativeTabs; +import net.minecraft.item.Item; +import net.minecraft.item.ItemStack; +import net.minecraft.util.IIcon; + +import cpw.mods.fml.relauncher.Side; +import cpw.mods.fml.relauncher.SideOnly; + +import forestry.api.core.Tabs; +import forestry.core.config.Config; +import forestry.core.config.ForestryItem; +import forestry.core.items.ItemForestry; +import forestry.core.render.TextureManager; +import forestry.core.utils.StringUtil; + +public class ItemHoneycomb extends ItemForestry { + + private static class CombInfo { + + public String name; + public int primaryColor; + public int secondaryColor; + public boolean isSecret = false; + + public CombInfo(String name, int primaryColor, int secondaryColor) { + this.name = name; + this.primaryColor = primaryColor; + this.secondaryColor = secondaryColor; + } + + public CombInfo setIsSecret() { + this.isSecret = true; + return this; + } + } + public CombInfo[] combs = new CombInfo[] { new CombInfo("honey", 0xe8d56a, 0xffa12b), // 0 + new CombInfo("cocoa", 0x674016, 0xffb62b).setIsSecret(), // 1 + new CombInfo("simmering", 0x981919, 0xffb62b), // 2 + new CombInfo("stringy", 0xc8be67, 0xbda93e), // 3 + new CombInfo("frozen", 0xf9ffff, 0xa0ffff), // 4 + new CombInfo("dripping", 0xdc7613, 0xffff00), // 5 + new CombInfo("silky", 0x508907, 0xddff00), // 6 + new CombInfo("parched", 0xdcbe13, 0xffff00), // 7 + new CombInfo("mysterious", 0x161616, 0xe099ff).setIsSecret(), // 8 + new CombInfo("irradiated", 0xeafff3, 0xeeff00).setIsSecret(), // 9 + new CombInfo("powdery", 0xe4e4e4, 0xffffff).setIsSecret(), // 10 + new CombInfo("reddened", 0x4b0000, 0x6200e7).setIsSecret(), // 11 + new CombInfo("darkened", 0x353535, 0x33ebcb).setIsSecret(), // 12 + new CombInfo("omega", 0x191919, 0x6dcff6).setIsSecret(), // 13 + new CombInfo("wheaten", 0xfeff8f, 0xffffff).setIsSecret(), // 14 + new CombInfo("mossy", 0x2a3313, 0x7e9939), // 15 + new CombInfo("mellow", 0x886000, 0xfff960) // 16 + // new CombInfo("", 0xd7bee5, 0xfd58ab), // kindof pinkish + }; + + public ItemHoneycomb() { + super(); + setMaxDamage(0); + setHasSubtypes(true); + setCreativeTab(Tabs.tabApiculture); + } + + @Override + public boolean isDamageable() { + return false; + } + + @Override + public boolean isRepairable() { + return false; + } + + @Override + public String getItemStackDisplayName(ItemStack itemstack) { + if (itemstack.getItemDamage() < 0 || itemstack.getItemDamage() >= combs.length) + return null; + + return StringUtil.localize("item.comb." + combs[itemstack.getItemDamage()].name); + } + + /* ICONS */ + @SideOnly(Side.CLIENT) + private IIcon[] icons; + + @SideOnly(Side.CLIENT) + @Override + public void registerIcons(IIconRegister register) { + icons = new IIcon[2]; + icons[0] = TextureManager.getInstance().registerTex(register, getUnlocalizedName().replace("item.", "") + ".0"); + icons[1] = TextureManager.getInstance().registerTex(register, getUnlocalizedName().replace("item.", "") + ".1"); + } + + @SideOnly(Side.CLIENT) + @Override + public IIcon getIconFromDamageForRenderPass(int i, int j) { + if (j > 0) + return icons[0]; + else + return icons[1]; + } + + @Override + public boolean requiresMultipleRenderPasses() { + return true; + } + + @Override + public int getColorFromItemStack(ItemStack itemstack, int j) { + if (j == 0) + return combs[itemstack.getItemDamage()].primaryColor; + else + return combs[itemstack.getItemDamage()].secondaryColor; + } + + @SuppressWarnings({ "rawtypes", "unchecked" }) + @Override + public void getSubItems(Item item, CreativeTabs par2CreativeTabs, List itemList) { + for (int i = 0; i < combs.length; i++) { + if (!combs[i].isSecret || Config.isDebug) + itemList.add(new ItemStack(this, 1, i)); + } + } + + public int getCombTypeCount() { + return combs.length; + } + + public int getRandomCombType(Random random, boolean includeSecret) { + List validCombs = new ArrayList(getCombTypeCount()); + for (int i = 0; i < combs.length; i++) { + if (!combs[i].isSecret || includeSecret) + validCombs.add(i); + } + + if (validCombs.isEmpty()) + return 0; + else + return validCombs.get(random.nextInt(validCombs.size())); + } + + public static ItemStack getRandomComb(int qty, Random random, boolean includeSecret) { + return ForestryItem.beeComb.getItemStack(qty, ((ItemHoneycomb) ForestryItem.beeComb.item()).getRandomCombType(random, includeSecret)); + } +} diff --git a/forestry_common/apiculture/forestry/apiculture/items/ItemImprinter.java b/forestry_common/apiculture/forestry/apiculture/items/ItemImprinter.java new file mode 100755 index 000000000..6b5f81fa4 --- /dev/null +++ b/forestry_common/apiculture/forestry/apiculture/items/ItemImprinter.java @@ -0,0 +1,226 @@ +/******************************************************************************* + * Copyright 2011-2014 by SirSengir + * + * This work is licensed under a Creative Commons Attribution-NonCommercial-NoDerivs 3.0 Unported License. + * + * To view a copy of this license, visit http://creativecommons.org/licenses/by-nc-nd/3.0/. + ******************************************************************************/ +package forestry.apiculture.items; + +import net.minecraft.entity.player.EntityPlayer; +import net.minecraft.inventory.IInventory; +import net.minecraft.item.ItemStack; +import net.minecraft.nbt.NBTTagCompound; +import net.minecraft.world.World; + +import forestry.api.apiculture.IAlleleBeeSpecies; +import forestry.api.apiculture.IBee; +import forestry.api.core.ForestryAPI; +import forestry.api.core.Tabs; +import forestry.apiculture.genetics.Bee; +import forestry.core.items.ItemForestry; +import forestry.core.network.GuiId; +import forestry.core.proxy.Proxies; +import forestry.plugins.PluginApiculture; + +public class ItemImprinter extends ItemForestry { + + public static class ImprinterInventory implements IInventory { + + private final ItemStack[] inventoryStacks = new ItemStack[2]; + private final short specimenSlot = 0; + private final short imprintedSlot = 1; + + private int primaryIndex = 0; + private int secondaryIndex = 0; + + EntityPlayer player; + + public ImprinterInventory(EntityPlayer player) { + this.player = player; + } + + public void advancePrimary() { + if (primaryIndex < PluginApiculture.beeInterface.getIndividualTemplates().size() - 1) + primaryIndex++; + else + primaryIndex = 0; + } + + public void advanceSecondary() { + if (secondaryIndex < PluginApiculture.beeInterface.getIndividualTemplates().size() - 1) + secondaryIndex++; + else + secondaryIndex = 0; + } + + public void regressPrimary() { + if (primaryIndex > 0) + primaryIndex--; + else + primaryIndex = PluginApiculture.beeInterface.getIndividualTemplates().size() - 1; + } + + public void regressSecondary() { + if (secondaryIndex > 0) + secondaryIndex--; + else + secondaryIndex = PluginApiculture.beeInterface.getIndividualTemplates().size() - 1; + } + + public IAlleleBeeSpecies getPrimary() { + return PluginApiculture.beeInterface.getIndividualTemplates().get(primaryIndex).getGenome().getPrimary(); + } + + public IAlleleBeeSpecies getSecondary() { + return PluginApiculture.beeInterface.getIndividualTemplates().get(secondaryIndex).getGenome().getPrimary(); + } + + public IBee getSelectedBee() { + return new Bee(PluginApiculture.beeInterface.templateAsGenome( + PluginApiculture.beeInterface.getGenomeTemplates().get(PluginApiculture.beeInterface.getIndividualTemplates().get(primaryIndex).getIdent()), + PluginApiculture.beeInterface.getGenomeTemplates().get(PluginApiculture.beeInterface.getIndividualTemplates().get(secondaryIndex).getIdent()))); + } + + public int getPrimaryIndex() { + return primaryIndex; + } + + public int getSecondaryIndex() { + return secondaryIndex; + } + + public void setPrimaryIndex(int index) { + primaryIndex = index; + } + + public void setSecondaryIndex(int index) { + secondaryIndex = index; + } + + private void tryImprint() { + + if (inventoryStacks[specimenSlot] == null) + return; + + // Only imprint bees + if (!PluginApiculture.beeInterface.isMember(inventoryStacks[specimenSlot])) + return; + + // Needs space + if (inventoryStacks[imprintedSlot] != null) + return; + + IBee imprint = getSelectedBee(); + if (imprint == null) + return; + + NBTTagCompound nbttagcompound = new NBTTagCompound(); + imprint.writeToNBT(nbttagcompound); + inventoryStacks[specimenSlot].setTagCompound(nbttagcompound); + + inventoryStacks[imprintedSlot] = inventoryStacks[specimenSlot]; + inventoryStacks[specimenSlot] = null; + } + + @Override + public ItemStack decrStackSize(int i, int j) { + if (inventoryStacks[i] == null) + return null; + + ItemStack product; + if (inventoryStacks[i].stackSize <= j) { + product = inventoryStacks[i]; + inventoryStacks[i] = null; + return product; + } else { + product = inventoryStacks[i].splitStack(j); + if (inventoryStacks[i].stackSize == 0) + inventoryStacks[i] = null; + + return product; + } + } + + @Override + public void markDirty() { + if (!Proxies.common.isSimulating(player.worldObj)) + return; + tryImprint(); + } + + @Override + public void setInventorySlotContents(int i, ItemStack itemstack) { + inventoryStacks[i] = itemstack; + } + + @Override + public ItemStack getStackInSlot(int i) { + return inventoryStacks[i]; + } + + @Override + public int getSizeInventory() { + return inventoryStacks.length; + } + + @Override + public String getInventoryName() { + return "Imprinter"; + } + + @Override + public int getInventoryStackLimit() { + return 64; + } + + @Override + public boolean isUseableByPlayer(EntityPlayer entityplayer) { + return true; + } + + @Override + public void openInventory() { + } + + @Override + public void closeInventory() { + } + + @Override + public ItemStack getStackInSlotOnClosing(int slot) { + if (inventoryStacks[slot] == null) + return null; + ItemStack toReturn = inventoryStacks[slot]; + inventoryStacks[slot] = null; + return toReturn; + } + + @Override + public boolean hasCustomInventoryName() { + return true; + } + + @Override + public boolean isItemValidForSlot(int i, ItemStack itemstack) { + return true; + } + + } + + public ItemImprinter() { + super(); + setCreativeTab(Tabs.tabApiculture); + setMaxStackSize(1); + } + + @Override + public ItemStack onItemRightClick(ItemStack itemstack, World world, EntityPlayer entityplayer) { + if (Proxies.common.isSimulating(world)) + entityplayer.openGui(ForestryAPI.instance, GuiId.ImprinterGUI.ordinal(), world, (int) entityplayer.posX, (int) entityplayer.posY, + (int) entityplayer.posZ); + + return itemstack; + } + +} diff --git a/forestry_common/apiculture/forestry/apiculture/items/ItemWaxCast.java b/forestry_common/apiculture/forestry/apiculture/items/ItemWaxCast.java new file mode 100755 index 000000000..782192e42 --- /dev/null +++ b/forestry_common/apiculture/forestry/apiculture/items/ItemWaxCast.java @@ -0,0 +1,33 @@ +/******************************************************************************* + * Copyright 2011-2014 by SirSengir + * + * This work is licensed under a Creative Commons Attribution-NonCommercial-NoDerivs 3.0 Unported License. + * + * To view a copy of this license, visit http://creativecommons.org/licenses/by-nc-nd/3.0/. + ******************************************************************************/ +package forestry.apiculture.items; + +import net.minecraft.item.ItemStack; + +import forestry.core.interfaces.ICraftingPlan; +import forestry.core.items.ItemForestry; + +public class ItemWaxCast extends ItemForestry implements ICraftingPlan { + + public ItemWaxCast() { + super(); + setMaxStackSize(1); + setMaxDamage(10); + setNoRepair(); + } + + @Override + public ItemStack planUsed(ItemStack plan, ItemStack result) { + plan.setItemDamage(plan.getItemDamage() + result.stackSize); + if (plan.getItemDamage() >= plan.getMaxDamage()) + return null; + else + return plan; + } + +} diff --git a/forestry_common/apiculture/forestry/apiculture/proxy/ClientProxyApiculture.java b/forestry_common/apiculture/forestry/apiculture/proxy/ClientProxyApiculture.java new file mode 100755 index 000000000..e461221b2 --- /dev/null +++ b/forestry_common/apiculture/forestry/apiculture/proxy/ClientProxyApiculture.java @@ -0,0 +1,96 @@ +/******************************************************************************* + * Copyright 2011-2014 by SirSengir + * + * This work is licensed under a Creative Commons Attribution-NonCommercial-NoDerivs 3.0 Unported License. + * + * To view a copy of this license, visit http://creativecommons.org/licenses/by-nc-nd/3.0/. + ******************************************************************************/ +package forestry.apiculture.proxy; + +import net.minecraft.client.particle.EntityFX; +import net.minecraft.world.World; + +import cpw.mods.fml.client.registry.RenderingRegistry; + +import net.minecraftforge.client.MinecraftForgeClient; + +import forestry.apiculture.entities.EntityBee; +import forestry.apiculture.render.BeeItemRenderer; +import forestry.apiculture.render.EntityBeeFX; +import forestry.apiculture.render.ParticleRenderer; +import forestry.apiculture.render.RenderBee; +import forestry.core.config.Config; +import forestry.core.config.ForestryItem; +import forestry.core.interfaces.IBlockRenderer; +import forestry.core.render.RenderAnalyzer; +import forestry.core.render.TextureManager; +import forestry.core.utils.Localization; +import forestry.plugins.PluginApiculture; + +public class ClientProxyApiculture extends ProxyApiculture { + + @Override + public void initializeRendering() { + if(PluginApiculture.fancyRenderedBees) { + RenderingRegistry.registerEntityRenderingHandler(EntityBee.class, new RenderBee()); + + MinecraftForgeClient.registerItemRenderer(ForestryItem.beeDroneGE.item(), new BeeItemRenderer()); + MinecraftForgeClient.registerItemRenderer(ForestryItem.beePrincessGE.item(), new BeeItemRenderer()); + MinecraftForgeClient.registerItemRenderer(ForestryItem.beeQueenGE.item(), new BeeItemRenderer()); + } + } + + @Override + public void addBeeHiveFX(String icon, World world, double xCoord, double yCoord, double zCoord, int color, int areaX, int areaY, int areaZ) { + if (!Config.enableParticleFX) + return; + + EntityFX fx; + + if (world.rand.nextBoolean()) { + fx = new EntityBeeFX(world, xCoord + 0.5D, yCoord + 0.75D, zCoord + 0.5D, 0.0f, 0.0f, 0.0f, color); + } else { + double spawnX = xCoord + world.rand.nextInt(areaX * 2) - areaX; + double spawnY = yCoord + world.rand.nextInt(areaY); + double spawnZ = zCoord + world.rand.nextInt(areaZ * 2) - areaZ; + + fx = new EntityBeeFX(world, spawnX, spawnY, spawnZ, 0.0f, 0.0f, 0.0f, color); + } + + fx.setParticleIcon(TextureManager.getInstance().getDefault(icon)); + ParticleRenderer.getInstance().addEffect(fx); + } + + @Override + public void addBeeSwarmFX(String icon, World world, double xCoord, double yCoord, double zCoord, int color) { + if (!Config.enableParticleFX) + return; + + EntityFX fx; + + if (world.rand.nextBoolean()) + fx = new EntityBeeFX(world, xCoord, yCoord, zCoord, 0.0f, 0.0f, 0.0f, color); + else { + + double spawnX = xCoord + world.rand.nextInt(4) - 2; + double spawnY = yCoord + world.rand.nextInt(4) - 2; + double spawnZ = zCoord + world.rand.nextInt(4) - 2; + + fx = new EntityBeeFX(world, spawnX, spawnY, spawnZ, 0.0f, 0.0f, 0.0f, color); + } + + fx.setParticleIcon(TextureManager.getInstance().getDefault(icon)); + ParticleRenderer.getInstance().addEffect(fx); + } + + @Override + public IBlockRenderer getRendererAnalyzer(String gfxBase) { + return new RenderAnalyzer(gfxBase); + } + + @Override + public void addLocalizations() { + Localization.instance.addLocalization("/lang/forestry/apiculture/"); + } + +} diff --git a/forestry_common/apiculture/forestry/apiculture/proxy/ProxyApiculture.java b/forestry_common/apiculture/forestry/apiculture/proxy/ProxyApiculture.java new file mode 100755 index 000000000..74c627824 --- /dev/null +++ b/forestry_common/apiculture/forestry/apiculture/proxy/ProxyApiculture.java @@ -0,0 +1,31 @@ +/******************************************************************************* + * Copyright 2011-2014 by SirSengir + * + * This work is licensed under a Creative Commons Attribution-NonCommercial-NoDerivs 3.0 Unported License. + * + * To view a copy of this license, visit http://creativecommons.org/licenses/by-nc-nd/3.0/. + ******************************************************************************/ +package forestry.apiculture.proxy; + +import net.minecraft.world.World; + +import forestry.core.interfaces.IBlockRenderer; + +public class ProxyApiculture { + public void addBeeHiveFX(String texture, World world, double xCoord, double yCoord, double zCoord, int color, int areaX, int areaY, int areaZ) { + } + + public void addBeeSwarmFX(String texture, World world, double xCoord, double yCoord, double zCoord, int color) { + } + + public IBlockRenderer getRendererAnalyzer(String string) { + return null; + } + + public void addLocalizations() { + } + + public void initializeRendering() { + } + +} diff --git a/forestry_common/apiculture/forestry/apiculture/render/BeeItemRenderer.java b/forestry_common/apiculture/forestry/apiculture/render/BeeItemRenderer.java new file mode 100755 index 000000000..7c4fdf166 --- /dev/null +++ b/forestry_common/apiculture/forestry/apiculture/render/BeeItemRenderer.java @@ -0,0 +1,223 @@ +/******************************************************************************* + * Copyright 2011-2014 by SirSengir + * + * This work is licensed under a Creative Commons Attribution-NonCommercial-NoDerivs 3.0 Unported License. + * + * To view a copy of this license, visit http://creativecommons.org/licenses/by-nc-nd/3.0/. + ******************************************************************************/ +package forestry.apiculture.render; + +import net.minecraft.client.renderer.OpenGlHelper; +import net.minecraft.client.renderer.RenderHelper; +import net.minecraft.client.renderer.entity.RenderManager; +import net.minecraft.item.ItemStack; + +import net.minecraftforge.client.IItemRenderer; + +import org.lwjgl.opengl.GL11; +import org.lwjgl.opengl.GL12; + +import forestry.api.apiculture.IBee; +import forestry.apiculture.entities.EntityBee; +import forestry.core.proxy.Proxies; +import forestry.plugins.PluginApiculture; + +public class BeeItemRenderer implements IItemRenderer { + + ModelBee model; + EntityBee entity; + + private static float getWingYaw(IBee bee) { + float wingYaw = 1f; + + if(bee.isAlive()) { + long systemTime = System.currentTimeMillis(); + long flapping = systemTime + bee.getIdent().hashCode(); + float flap = (float) (flapping % 1000) / 1000; // 0 to 1 + + wingYaw = getIrregularWingYaw(flapping, flap); + + } + + return wingYaw; + } + + public static float getIrregularWingYaw(long flapping, float flap) { + long irregular = flapping / 1000; + float wingYaw = 1f; + + if(irregular % 11 == 0) { + wingYaw = 0.75f; + } else { + if(irregular % 7 == 0 || irregular % 19 == 0) { + flap *= 8; + flap = flap % 1; + } + wingYaw = getRegularWingYaw(flap); + } + + return wingYaw; + } + + public static float getRegularWingYaw(float flap) { + return flap < 0.5 ? 0.75f + flap : 1.75f - flap; + } + + private IBee initBee(ItemStack item, boolean scaled) { + IBee bee = PluginApiculture.beeInterface.getMember(item); + if(bee == null) + bee = PluginApiculture.beeInterface.templateAsIndividual(PluginApiculture.beeInterface.getDefaultTemplate()); + + if(entity == null) { + entity = new EntityBee(Proxies.common.getClientInstance().theWorld); + } + entity.setSpecies(bee.getGenome().getPrimary()); + entity.setType(PluginApiculture.beeInterface.getType(item)); + /* + if(scaled) + entity.setScale(butterfly.getSize()); + else + entity.setScale(EntityButterfly.DEFAULT_BUTTERFLY_SCALE); + */ + + return bee; + } + + /*private void renderBeeHalo() { + + IIcon background = TextureManager.getInstance().getDefault("habitats/desert"); + float xPos = 1.0f; float yPos = 1.0f; + float width = 1f; float height = 1f; + + Proxies.common.bindTexture(SpriteSheet.ITEMS); + Tessellator tessellator = Tessellator.instance; + tessellator.startDrawingQuads(); + tessellator.addVertexWithUV((double)(xPos + 0), (double)(yPos + height), 0f, (double)background.getMinU(), (double)background.getMaxV()); + tessellator.addVertexWithUV((double)(xPos + width), (double)(yPos + height), 0f, (double)background.getMaxU(), (double)background.getMaxV()); + tessellator.addVertexWithUV((double)(xPos + width), (double)(yPos + 0), 0f, (double)background.getMaxU(), (double)background.getMinV()); + tessellator.addVertexWithUV((double)(xPos + 0), (double)(yPos + 0), 0f, (double)background.getMinU(), (double)background.getMinV()); + tessellator.draw(); + }*/ + + private void renderBeeItem(IBee bee, float translateX, float translateY, float translateZ) { + float yaw = 1; + float pitch = 1; + + GL11.glPushAttrib(GL11.GL_ENABLE_BIT); + GL11.glEnable(GL11.GL_LIGHTING); + GL11.glEnable(GL11.GL_DEPTH_TEST); + GL11.glEnable(GL11.GL_COLOR_MATERIAL); + + GL11.glPushMatrix(); + + GL11.glScalef(2.0f, 2.0f, 2.0f); + GL11.glTranslatef(translateX, translateY, translateZ); + GL11.glColor4f(1.0F, 1.0F, 1.0F, 1.0F); + GL11.glRotatef(-135.0F, 0.0F, 1.0F, 0.0F); + GL11.glRotatef(-((float) Math.atan(pitch / 40.0F)) * 20.0F, 1.0F, 0.0F, 0.0F); + + entity.renderYawOffset = (float) Math.atan(yaw / 40.0F) * 20.0F; + entity.rotationYaw = (float) Math.atan(yaw / 40.0F) * 40.0F; + entity.rotationPitch = -((float) Math.atan(pitch / 40.0F)) * 20.0F; + entity.rotationYawHead = entity.rotationYaw; + + RenderManager.instance.renderEntityWithPosYaw(entity, 0.0D, 0.0D, 0.0D, 0.0F, getWingYaw(bee)); + + GL11.glPopMatrix(); + + RenderHelper.disableStandardItemLighting(); + GL11.glDisable(GL12.GL_RESCALE_NORMAL); + OpenGlHelper.setActiveTexture(OpenGlHelper.lightmapTexUnit); + GL11.glDisable(GL11.GL_TEXTURE_2D); + OpenGlHelper.setActiveTexture(OpenGlHelper.defaultTexUnit); + GL11.glPopAttrib(); + + } + + private void renderBeeInInventory(IBee bee) { + + /* + GL11.glPushMatrix(); + //GL11.glTranslatef(-0.3f, -2.5f, 0f); + GL11.glScalef(-1.0f, 1.0f, 1.0f); + //GL11.glScalef((float)Math.PI / 2, 1.0f, 1.0f); + GL11.glColor4f(1.0F, 1.0F, 1.0F, 1.0F); + GL11.glRotatef(-135.0F, 0.0F, 1.0F, 0.0F); + //GL11.glRotatef(-((float) Math.atan((double) (1 / 40.0F))) * 20.0F, 1.0F, 0.0F, 0.0F); + renderBeeHalo(); + GL11.glPopMatrix(); + */ + + GL11.glPushAttrib(GL11.GL_ENABLE_BIT); + GL11.glEnable(GL11.GL_LIGHTING); + GL11.glEnable(GL11.GL_DEPTH_TEST); + GL11.glEnable(GL11.GL_COLOR_MATERIAL); + RenderHelper.enableStandardItemLighting(); + + GL11.glPushMatrix(); + + GL11.glTranslatef(-0.3f, -2.5f, 0f); + GL11.glScalef(-3.0f, 3.0f, 3.0f); + GL11.glRotatef(32.0F, 0.0F, 1.0F, 0.0F); + GL11.glScalef(1.6f, 1f, 1f); + + GL11.glColor4f(1.0F, 1.0F, 1.0F, 1.0F); + entity.renderYawOffset = 0; + entity.rotationYaw = 0; + entity.rotationPitch = 0; + entity.rotationYawHead = entity.rotationYaw; + + RenderManager.instance.renderEntityWithPosYaw(entity, 0.0D, 0.0D, 0.0D, 0.0F, getWingYaw(bee)); + + GL11.glPopMatrix(); + RenderHelper.disableStandardItemLighting(); + GL11.glDisable(GL12.GL_RESCALE_NORMAL); + OpenGlHelper.setActiveTexture(OpenGlHelper.lightmapTexUnit); + GL11.glDisable(GL11.GL_TEXTURE_2D); + OpenGlHelper.setActiveTexture(OpenGlHelper.defaultTexUnit); + GL11.glPopAttrib(); + } + + @Override + public boolean handleRenderType(ItemStack item, ItemRenderType type) { + switch (type) { + case ENTITY: + return true; + case EQUIPPED: + return true; + case INVENTORY: + return true; + default: + return false; + } + } + + @Override + public boolean shouldUseRenderHelper(ItemRenderType type, ItemStack item, ItemRendererHelper helper) { + switch(helper) { + case ENTITY_BOBBING: + case ENTITY_ROTATION: + return false; + default: + return true; + } + } + + @Override + public void renderItem(ItemRenderType type, ItemStack item, Object... data) { + + switch (type) { + case ENTITY: + renderBeeItem(initBee(item, true), 0f, 0f, 0f); + break; + case EQUIPPED: + renderBeeItem(initBee(item, true), 1.0f, 0f, 0.5f); + break; + case INVENTORY: + renderBeeInInventory(initBee(item, false)); + break; + default: + } + } + +} diff --git a/forestry_common/apiculture/forestry/apiculture/render/BlockCandleRenderer.java b/forestry_common/apiculture/forestry/apiculture/render/BlockCandleRenderer.java new file mode 100755 index 000000000..a4af055d1 --- /dev/null +++ b/forestry_common/apiculture/forestry/apiculture/render/BlockCandleRenderer.java @@ -0,0 +1,151 @@ +/******************************************************************************* + * Copyright 2011-2014 by SirSengir + * + * This work is licensed under a Creative Commons Attribution-NonCommercial-NoDerivs 3.0 Unported License. + * + * To view a copy of this license, visit http://creativecommons.org/licenses/by-nc-nd/3.0/. + ******************************************************************************/ +package forestry.apiculture.render; + +import net.minecraft.block.Block; +import net.minecraft.client.renderer.RenderBlocks; +import net.minecraft.client.renderer.Tessellator; +import net.minecraft.util.IIcon; +import net.minecraft.world.IBlockAccess; + +import cpw.mods.fml.client.registry.ISimpleBlockRenderingHandler; + +import forestry.apiculture.gadgets.BlockCandle; +import forestry.apiculture.gadgets.TileCandle; +import forestry.core.ForestryClient; + +public class BlockCandleRenderer implements ISimpleBlockRenderingHandler { + + @Override + public void renderInventoryBlock(Block block, int metadata, int modelID, RenderBlocks renderer) { + /*BlockCandle bc = (BlockCandle)block; + Tessellator tessellator = Tessellator.instance; + tessellator.startDrawingQuads(); + tessellator.setNormal(0.0F, -1.0F, 0.0F); + IIcon iconA = (bc.isLit(meta)) ? bc. + this.renderTorchAtAngle(block, -0.5D, -0.5D, -0.5D, 0.0D, 0.0D, 0); + tessellator.draw();*/ + } + + @Override + public boolean renderWorldBlock(IBlockAccess world, int x, int y, int z, Block block, int modelId, RenderBlocks renderer) { + if (block.getRenderType() == ForestryClient.candleRenderId) { + this.renderBlockCandle(world, x, y, z, (BlockCandle)block, modelId, renderer); + } + return true; + } + + @Override + public boolean shouldRender3DInInventory(int modelId) { + return false; + } + + @Override + public int getRenderId() { + return ForestryClient.candleRenderId; + } + + public boolean renderBlockCandle(IBlockAccess world, int x, int y, int z, BlockCandle block, int modelId, RenderBlocks renderer) { + int meta = world.getBlockMetadata(x, y, z); + IIcon iconA = block.getTextureFromPassAndMeta(meta, 0); + IIcon iconB = block.getTextureFromPassAndMeta(meta, 1); + meta = meta & 0x7; + TileCandle tc = (TileCandle)world.getTileEntity(x, y, z); + int colour = tc.getColour(); + Tessellator tessellator = Tessellator.instance; + tessellator.setBrightness(world.getLightBrightnessForSkyBlocks(x, y, z, block.getLightValue(world, x, y, z))); + tessellator.setColorOpaque_F(1.0F, 1.0F, 1.0F); + double d0 = 0.4000000059604645D; + double d1 = 0.5D - d0; + double d2 = 0.20000000298023224D; + + if (meta == 1) + { + this.renderCandleAtAngle(iconA, x - d1, y + d2, z, -d0, 0.0D, 0xffffff); + this.renderCandleAtAngle(iconB, x - d1, y + d2, z, -d0, 0.0D, colour); + } + else if (meta == 2) + { + this.renderCandleAtAngle(iconA, x + d1, y + d2, z, d0, 0.0D, 0xffffff); + this.renderCandleAtAngle(iconB, x + d1, y + d2, z, d0, 0.0D, colour); + } + else if (meta == 3) + { + this.renderCandleAtAngle(iconA, x, y + d2, z - d1, 0.0D, -d0, 0xffffff); + this.renderCandleAtAngle(iconB, x, y + d2, z - d1, 0.0D, -d0, colour); + } + else if (meta == 4) + { + this.renderCandleAtAngle(iconA, x, y + d2, z + d1, 0.0D, d0, 0xffffff); + this.renderCandleAtAngle(iconB, x, y + d2, z + d1, 0.0D, d0, colour); + } + else + { + this.renderCandleAtAngle(iconA, x, y, z, 0.0D, 0.0D, 0xffffff); + this.renderCandleAtAngle(iconB, x, y, z, 0.0D, 0.0D, colour); + } + + return true; + } + + public void renderCandleAtAngle(IIcon icon, double x, double y, double z, double par8, double par10, int colour) + { + Tessellator tessellator = Tessellator.instance; + double minU = icon.getMinU(); + double minV = icon.getMinV(); + double maxU = icon.getMaxU(); + double maxV = icon.getMaxV(); + double textureLightTopU = icon.getInterpolatedU(7.0D); + double d10 = icon.getInterpolatedV(6.0D); + double textureLightBottomU = icon.getInterpolatedU(9.0D); + double d12 = icon.getInterpolatedV(8.0D); + //double d13 = (double)icon.getInterpolatedV(7.0D); + double d14 = icon.getInterpolatedV(13.0D); + //double textureLightBottomV = (double)icon.getInterpolatedV(8.0D); + double d16 = icon.getInterpolatedV(15.0D); + x += 0.5D; + z += 0.5D; + double d17 = x - 0.5D; + double d18 = x + 0.5D; + double d19 = z - 0.5D; + double d20 = z + 0.5D; + double d21 = 0.0625D; + double d22 = 0.625D; + tessellator.setColorOpaque_I(colour); + // top quad + tessellator.addVertexWithUV(x + par8 * (1.0D - d22) - d21, y + d22, z + par10 * (1.0D - d22) - d21, textureLightTopU, d10); + tessellator.addVertexWithUV(x + par8 * (1.0D - d22) - d21, y + d22, z + par10 * (1.0D - d22) + d21, textureLightTopU, d12); + tessellator.addVertexWithUV(x + par8 * (1.0D - d22) + d21, y + d22, z + par10 * (1.0D - d22) + d21, textureLightBottomU, d12); + tessellator.addVertexWithUV(x + par8 * (1.0D - d22) + d21, y + d22, z + par10 * (1.0D - d22) - d21, textureLightBottomU, d10); + // -x quad + tessellator.addVertexWithUV(x - d21, y + 1d, d19, minU, minV); + tessellator.addVertexWithUV(x - d21 + par8, y, d19 + par10, minU, maxV); + tessellator.addVertexWithUV(x - d21 + par8, y, d20 + par10, maxU, maxV); + tessellator.addVertexWithUV(x - d21, y + 1d, d20, maxU, minV); + // +x quad + tessellator.addVertexWithUV(x + d21, y + 1.0D, d20, minU, minV); + tessellator.addVertexWithUV(x + par8 + d21, y, d20 + par10, minU, maxV); + tessellator.addVertexWithUV(x + par8 + d21, y, d19 + par10, maxU, maxV); + tessellator.addVertexWithUV(x + d21, y + 1.0D, d19, maxU, minV); + // -z quad + tessellator.addVertexWithUV(d18, y + 1.0D, z - d21, minU, minV); + tessellator.addVertexWithUV(d18 + par8, y, z - d21 + par10, minU, maxV); + tessellator.addVertexWithUV(d17 + par8, y, z - d21 + par10, maxU, maxV); + tessellator.addVertexWithUV(d17, y + 1.0D, z - d21, maxU, minV); + // +z quad + tessellator.addVertexWithUV(d17, y + 1.0D, z + d21, minU, minV); + tessellator.addVertexWithUV(d17 + par8, y, z + d21 + par10, minU, maxV); + tessellator.addVertexWithUV(d18 + par8, y, z + d21 + par10, maxU, maxV); + tessellator.addVertexWithUV(d18, y + 1.0D, z + d21, maxU, minV); + // bottom quad + tessellator.addVertexWithUV(x + d21 + par8, y, z - d21 + par10, textureLightBottomU, d14); + tessellator.addVertexWithUV(x + d21 + par8, y, z + d21 + par10, textureLightBottomU, d16); + tessellator.addVertexWithUV(x - d21 + par8, y, z + d21 + par10, textureLightTopU, d16); + tessellator.addVertexWithUV(x - d21 + par8, y, z - d21 + par10, textureLightTopU, d14); + } +} diff --git a/forestry_common/apiculture/forestry/apiculture/render/EntityBeeFX.java b/forestry_common/apiculture/forestry/apiculture/render/EntityBeeFX.java new file mode 100755 index 000000000..e83e5da90 --- /dev/null +++ b/forestry_common/apiculture/forestry/apiculture/render/EntityBeeFX.java @@ -0,0 +1,84 @@ +/******************************************************************************* + * Copyright 2011-2014 by SirSengir + * + * This work is licensed under a Creative Commons Attribution-NonCommercial-NoDerivs 3.0 Unported License. + * + * To view a copy of this license, visit http://creativecommons.org/licenses/by-nc-nd/3.0/. + ******************************************************************************/ +package forestry.apiculture.render; + +import net.minecraft.client.particle.EntityFX; +import net.minecraft.client.renderer.Tessellator; +import net.minecraft.world.World; + +public class EntityBeeFX extends EntityFX { + public EntityBeeFX(World world, double x, double y, double z, float motionScaleX, float motionScaleY, float motionScaleZ, int color) { + super(world, x, y, z, 0.0D, 0.0D, 0.0D); + + particleRed = (color >> 16 & 255) / 255.0F; + particleGreen = (color >> 8 & 255) / 255.0F; + particleBlue = (color & 255) / 255.0F; + + this.setSize(0.1F, 0.1F); + this.particleScale *= 0.2F; + this.particleMaxAge = (int) (20.0D / (Math.random() * 0.8D + 0.2D)); + this.noClip = true; + + this.motionX *= 0.119999999552965164D; + this.motionY *= 0.119999999552965164D; + this.motionZ *= 0.119999999552965164D; + } + + /** + * Called to update the entity's position/logic. + */ + @Override + public void onUpdate() { + this.prevPosX = this.posX; + this.prevPosY = this.posY; + this.prevPosZ = this.posZ; + this.moveEntity(this.motionX, this.motionY, this.motionZ); + this.motionX *= 1.08D; + this.motionY *= 1.08D; + this.motionZ *= 1.08D; + + if (this.particleMaxAge-- <= 0) + this.setDead(); + } + + @Override + public void renderParticle(Tessellator tessellator, float f, float f1, float f2, float f3, float f4, float f5) { + float minU = 0; + float maxU = 1; + float minV = 0; + float maxV = 1; + + if (this.particleIcon != null) { + minU = particleIcon.getMinU(); + maxU = particleIcon.getMaxU(); + minV = particleIcon.getMinV(); + maxV = particleIcon.getMaxV(); + } + + float f10 = 0.1F * particleScale; + float f11 = (float) ((prevPosX + (posX - prevPosX) * f) - interpPosX); + float f12 = (float) ((prevPosY + (posY - prevPosY) * f) - interpPosY); + float f13 = (float) ((prevPosZ + (posZ - prevPosZ) * f) - interpPosZ); + + tessellator.setColorRGBA_F(particleRed, particleGreen, particleBlue, 1.0F); + tessellator.addVertexWithUV(f11 - f1 * f10 - f4 * f10, f12 - f2 * f10, f13 - f3 * f10 - f5 * f10, maxU, maxV); + tessellator.addVertexWithUV((f11 - f1 * f10) + f4 * f10, f12 + f2 * f10, (f13 - f3 * f10) + f5 * f10, maxU, minV); + tessellator.addVertexWithUV(f11 + f1 * f10 + f4 * f10, f12 + f2 * f10, f13 + f3 * f10 + f5 * f10, minU, minV); + tessellator.addVertexWithUV((f11 + f1 * f10) - f4 * f10, f12 - f2 * f10, (f13 + f3 * f10) - f5 * f10, minU, maxV); + } + + @Override + public int getBrightnessForRender(float partialTicks) { + return 0x0000f0; + } + + @Override + public int getFXLayer() { + return 2; + } +} diff --git a/forestry_common/apiculture/forestry/apiculture/render/ModelAnalyzer.java b/forestry_common/apiculture/forestry/apiculture/render/ModelAnalyzer.java new file mode 100755 index 000000000..78b65f92b --- /dev/null +++ b/forestry_common/apiculture/forestry/apiculture/render/ModelAnalyzer.java @@ -0,0 +1,112 @@ +/******************************************************************************* + * Copyright 2011-2014 by SirSengir + * + * This work is licensed under a Creative Commons Attribution-NonCommercial-NoDerivs 3.0 Unported License. + * + * To view a copy of this license, visit http://creativecommons.org/licenses/by-nc-nd/3.0/. + ******************************************************************************/ +package forestry.apiculture.render; + +import net.minecraft.client.model.ModelBase; +import net.minecraft.client.model.ModelRenderer; +import net.minecraft.util.ResourceLocation; + +import net.minecraftforge.common.util.ForgeDirection; + +import org.lwjgl.opengl.GL11; + +import forestry.core.proxy.Proxies; +import forestry.core.utils.ForestryResource; + +public class ModelAnalyzer extends ModelBase { + + private final ModelRenderer pedestal; + private final ModelRenderer cover; + private final ModelRenderer tower1; + private final ModelRenderer tower2; + + private final ResourceLocation[] textures; + + public ModelAnalyzer(String gfxBase) { + + textures = new ResourceLocation[] { + new ForestryResource(gfxBase + "pedestal.png"), + new ForestryResource(gfxBase + "tower1.png"), + new ForestryResource(gfxBase + "tower2.png"), + }; + + pedestal = new ModelRenderer(this, 0, 0); + pedestal.addBox(-8F, -8F, -8F, 16, 1, 16); + pedestal.setRotationPoint(8, 8, 8); + + cover = new ModelRenderer(this, 0, 0); + cover.addBox(-8F, -8F, -8F, 16, 1, 16); + cover.setRotationPoint(8, 8, 8); + + tower1 = new ModelRenderer(this, 0, 0); + tower1.addBox(-8, -7, -7, 2, 14, 14); + tower1.setRotationPoint(8, 8, 8); + + tower2 = new ModelRenderer(this, 0, 0); + tower2.addBox(6, -7, -7, 2, 14, 14); + tower2.setRotationPoint(8, 8, 8); + + } + + public void render(ForgeDirection orientation, float posX, float posY, float posZ) { + + GL11.glPushMatrix(); + GL11.glDisable(GL11.GL_LIGHTING); + + GL11.glTranslatef(posX, posY, posZ); + float[] angle = { 0, 0, 0 }; + + if (orientation == null) + orientation = ForgeDirection.WEST; + switch (orientation) { + case EAST: + angle[1] = (float) Math.PI / 2; + break; + case WEST: + angle[1] = -(float) Math.PI / 2; + break; + case SOUTH: + break; + case NORTH: + default: + angle[1] = (float) Math.PI; + break; + } + + float factor = (float) (1.0 / 16.0); + + Proxies.common.bindTexture(textures[0]); + + pedestal.rotateAngleX = angle[0]; + pedestal.rotateAngleY = angle[1]; + pedestal.rotateAngleZ = angle[2]; + pedestal.render(factor); + + cover.rotateAngleX = angle[0]; + cover.rotateAngleY = angle[1]; + cover.rotateAngleZ = (float) Math.PI; + cover.render(factor); + + tower1.rotateAngleX = angle[0]; + tower1.rotateAngleY = angle[1]; + tower1.rotateAngleZ = angle[2]; + Proxies.common.bindTexture(textures[1]); + tower1.render(factor); + + tower2.rotateAngleX = angle[0]; + tower2.rotateAngleY = angle[1]; + tower2.rotateAngleZ = angle[2]; + Proxies.common.bindTexture(textures[2]); + tower2.render(factor); + + GL11.glEnable(GL11.GL_LIGHTING); + GL11.glPopMatrix(); + + } + +} diff --git a/forestry_common/apiculture/forestry/apiculture/render/ModelBee.java b/forestry_common/apiculture/forestry/apiculture/render/ModelBee.java new file mode 100755 index 000000000..86a71450f --- /dev/null +++ b/forestry_common/apiculture/forestry/apiculture/render/ModelBee.java @@ -0,0 +1,163 @@ +/******************************************************************************* + * Copyright 2011-2014 by SirSengir + * + * This work is licensed under a Creative Commons Attribution-NonCommercial-NoDerivs 3.0 Unported License. + * + * To view a copy of this license, visit http://creativecommons.org/licenses/by-nc-nd/3.0/. + ******************************************************************************/ +package forestry.apiculture.render; + +import net.minecraft.client.model.ModelBase; +import net.minecraft.client.model.ModelRenderer; +import net.minecraft.entity.Entity; +import net.minecraft.util.MathHelper; + +import org.lwjgl.opengl.GL11; + +import forestry.api.apiculture.EnumBeeType; + +public class ModelBee extends ModelBase { + + //fields + ModelRenderer snout; + ModelRenderer torsoWing; + ModelRenderer rump; + ModelRenderer tail; + ModelRenderer tailEnd; + ModelRenderer bridge; + ModelRenderer eyeRight; + ModelRenderer eyeLeft; + ModelRenderer wingLeft; + ModelRenderer wingRight; + ModelRenderer crownQueen; + ModelRenderer crownPrincess; + + EnumBeeType type = EnumBeeType.DRONE; + + public ModelBee() { + textureWidth = 64; + textureHeight = 32; + + snout = new ModelRenderer(this, 18, 11); + snout.addBox(0F, 0F, 0F, 1, 2, 1); + snout.setRotationPoint(0F, 1F, -2F); + snout.setTextureSize(64, 32); + snout.mirror = true; + setRotation(snout, 0F, 0F, 0F); + torsoWing = new ModelRenderer(this, 28, 14); + torsoWing.addBox(0F, 0F, 0F, 3, 3, 1); + torsoWing.setRotationPoint(-1F, 0F, -1F); + torsoWing.setTextureSize(64, 32); + torsoWing.mirror = true; + setRotation(torsoWing, 0F, 0F, 0F); + rump = new ModelRenderer(this, 10, 14); + rump.addBox(-1F, -1F, 0F, 3, 3, 3); + rump.setRotationPoint(0F, 1F, 1F); + rump.setTextureSize(64, 32); + rump.mirror = true; + setRotation(rump, 0F, 0F, 0F); + tail = new ModelRenderer(this, 4, 14); + tail.addBox(0F, 0F, 0F, 2, 2, 1); + tail.setRotationPoint(-0.5F, 0.5333334F, 4F); + tail.setTextureSize(64, 32); + tail.mirror = true; + setRotation(tail, 0F, 0F, 0F); + tailEnd = new ModelRenderer(this, 0, 14); + tailEnd.addBox(0F, 0F, 0F, 1, 1, 1); + tailEnd.setRotationPoint(0F, 1F, 5F); + tailEnd.setTextureSize(64, 32); + tailEnd.mirror = true; + setRotation(tailEnd, 0F, 0F, 0F); + bridge = new ModelRenderer(this, 22, 14); + bridge.addBox(0F, 0F, 0F, 2, 2, 1); + bridge.setRotationPoint(-0.5F, 0.5F, 0F); + bridge.setTextureSize(64, 32); + bridge.mirror = true; + setRotation(bridge, 0F, 0F, 0F); + eyeRight = new ModelRenderer(this, 22, 9); + eyeRight.addBox(0F, 0F, 0F, 1, 1, 1); + eyeRight.setRotationPoint(-1F, 0F, -2F); + eyeRight.setTextureSize(64, 32); + eyeRight.mirror = true; + setRotation(eyeRight, 0F, 0F, 0F); + eyeLeft = new ModelRenderer(this, 18, 9); + eyeLeft.addBox(0F, 0F, 0F, 1, 1, 1); + eyeLeft.setRotationPoint(1F, 0F, -2F); + eyeLeft.setTextureSize(64, 32); + eyeLeft.mirror = true; + setRotation(eyeLeft, 0F, 0F, 0F); + wingLeft = new ModelRenderer(this, 0, 0); + wingLeft.addBox(0F, 0F, 0F, 3, 1, 6); + wingLeft.setRotationPoint(1F, -0.1F, -0.5F); + wingLeft.setTextureSize(64, 32); + wingLeft.mirror = true; + setRotation(wingLeft, 0F, 0.1396263F, 0F); + wingRight = new ModelRenderer(this, 0, 7); + wingRight.addBox(-3F, 0F, 0F, 3, 1, 6); + wingRight.setRotationPoint(0F, -0.1F, -0.5F); + wingRight.setTextureSize(64, 32); + wingRight.mirror = true; + setRotation(wingRight, 0F, -0.1396263F, 0F); + + crownQueen = new ModelRenderer(this, 0, 17); + crownQueen.addBox(0F, 0F, 0F, 2, 1, 2); + crownQueen.setRotationPoint(-0.5F, -1.5F, -1.5F); + crownQueen.setTextureSize(64, 32); + crownQueen.mirror = true; + setRotation(crownQueen, 0F, 0F, 0F); + + crownPrincess = new ModelRenderer(this, 0, 20); + crownPrincess.addBox(0F, 0F, 0F, 2, 1, 2); + crownPrincess.setRotationPoint(-0.5F, -1.5F, -1.5F); + crownPrincess.setTextureSize(64, 32); + crownPrincess.mirror = true; + setRotation(crownPrincess, 0F, 0F, 0F); + + } + + public void setType(EnumBeeType type) { + this.type = type; + } + + public void render(Entity entity, float f, float f1, float swing, float f3, float f4, float f5) { + super.render(entity, f, f1, swing, f3, f4, f5); + //setRotationAngles(f, f1, f2, f3, f4, f5, entity); + + wingRight.rotateAngleZ = MathHelper.cos(swing * 1.3F) * (float)Math.PI * 0.25F; + wingLeft.rotateAngleZ = -wingRight.rotateAngleZ; + + GL11.glPushMatrix(); + float scale = 0.75f; + GL11.glScalef(scale, scale, scale); + GL11.glTranslatef(0.0F, (12.0f / scale) * f5, 0.0F); + + snout.render(f5); + torsoWing.render(f5); + rump.render(f5); + tail.render(f5); + tailEnd.render(f5); + bridge.render(f5); + eyeRight.render(f5); + eyeLeft.render(f5); + wingLeft.render(f5); + wingRight.render(f5); + + if(type == EnumBeeType.PRINCESS) + crownPrincess.render(f5); + else if(type == EnumBeeType.QUEEN) + crownQueen.render(f5); + + GL11.glPopMatrix(); + } + + 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); + } + +} diff --git a/forestry_common/apiculture/forestry/apiculture/render/ParticleRenderer.java b/forestry_common/apiculture/forestry/apiculture/render/ParticleRenderer.java new file mode 100755 index 000000000..e6f0d882c --- /dev/null +++ b/forestry_common/apiculture/forestry/apiculture/render/ParticleRenderer.java @@ -0,0 +1,159 @@ +/******************************************************************************* + * Copyright 2011-2014 by SirSengir + * + * This work is licensed under a Creative Commons Attribution-NonCommercial-NoDerivs 3.0 Unported License. + * + * To view a copy of this license, visit http://creativecommons.org/licenses/by-nc-nd/3.0/. + ******************************************************************************/ +package forestry.apiculture.render; + +import java.util.ArrayList; +import java.util.Iterator; +import java.util.List; + +import net.minecraft.client.Minecraft; +import net.minecraft.client.particle.EntityFX; +import net.minecraft.client.renderer.ActiveRenderInfo; +import net.minecraft.client.renderer.Tessellator; +import net.minecraft.client.renderer.texture.TextureMap; +import net.minecraft.entity.EntityLivingBase; + +import cpw.mods.fml.common.FMLCommonHandler; +import cpw.mods.fml.common.eventhandler.SubscribeEvent; +import cpw.mods.fml.common.gameevent.TickEvent; +import cpw.mods.fml.common.gameevent.TickEvent.Phase; +import cpw.mods.fml.relauncher.Side; +import cpw.mods.fml.relauncher.SideOnly; + +import net.minecraftforge.client.event.RenderWorldLastEvent; +import net.minecraftforge.common.MinecraftForge; +import net.minecraftforge.event.world.WorldEvent; + +import org.lwjgl.opengl.GL11; + +@SideOnly(Side.CLIENT) +public class ParticleRenderer { + private static final String name = "forestry-particles"; + + // singleton getter >> + + public static synchronized ParticleRenderer getInstance() { + if (instance == null) instance = new ParticleRenderer(); + + return instance; + } + + private static ParticleRenderer instance = null; + + // << singleton getter + + + public synchronized void addEffect(EntityFX particle) { + if (lazyAdd) { + newParticles.add(particle); + } else { + particles.add(particle); + } + } + + + // forge + fml handlers >> + + @SubscribeEvent + public void onRenderWorldLast(RenderWorldLastEvent event) { + render(event.partialTicks); + } + + @SubscribeEvent + public void onWorldUnload(WorldEvent.Unload event) { + if (FMLCommonHandler.instance().getEffectiveSide().isClient()) { + synchronized (this) { + particles.clear(); + } + } + } + + @SubscribeEvent + public void onClientTick(TickEvent.ClientTickEvent event) { + if (event.phase == Phase.END) { + update(); + } + } + + // << forge + fml handlers + + private ParticleRenderer() { + MinecraftForge.EVENT_BUS.register(this); + FMLCommonHandler.instance().bus().register(this); + } + + private synchronized void update() { + Minecraft.getMinecraft().mcProfiler.startSection(name+"-update"); + + lazyAdd = true; + + for (Iterator it = particles.iterator(); it.hasNext(); ) { + EntityFX particle = it.next(); + + particle.onUpdate(); + + if (particle.isDead) { + it.remove(); + } + } + + lazyAdd = false; + particles.addAll(newParticles); + newParticles.clear(); + + Minecraft.getMinecraft().mcProfiler.endSection(); + } + + private synchronized void render(float partialTicks) { + Minecraft.getMinecraft().mcProfiler.startSection(name+"-render"); + + float rotationX = ActiveRenderInfo.rotationX; + float rotationZ = ActiveRenderInfo.rotationZ; + float rotationYZ = ActiveRenderInfo.rotationYZ; + float rotationXY = ActiveRenderInfo.rotationXY; + float rotationXZ = ActiveRenderInfo.rotationXZ; + + EntityLivingBase player = Minecraft.getMinecraft().renderViewEntity; + EntityFX.interpPosX = player.lastTickPosX + (player.posX - player.lastTickPosX) * partialTicks; + EntityFX.interpPosY = player.lastTickPosY + (player.posY - player.lastTickPosY) * partialTicks; + EntityFX.interpPosZ = player.lastTickPosZ + (player.posZ - player.lastTickPosZ) * partialTicks; + + // bind the texture + Minecraft.getMinecraft().renderEngine.bindTexture(TextureMap.locationItemsTexture); + + // save the old gl state + GL11.glPushAttrib(GL11.GL_COLOR_BUFFER_BIT | GL11.GL_DEPTH_BUFFER_BIT); + + // gl states/settings for drawing + GL11.glColor4f(1.0F, 1.0F, 1.0F, 1.0F); + GL11.glDepthMask(false); + GL11.glEnable(GL11.GL_BLEND); + GL11.glBlendFunc(GL11.GL_SRC_ALPHA, GL11.GL_ONE); + GL11.glAlphaFunc(GL11.GL_GREATER, 0.003921569F); + + Tessellator tessellator = Tessellator.instance; + tessellator.startDrawingQuads(); + + for (EntityFX particle : particles) { + tessellator.setBrightness(particle.getBrightnessForRender(partialTicks)); + + particle.renderParticle(tessellator, partialTicks, rotationX, rotationXZ, rotationZ, rotationYZ, rotationXY); + } + + tessellator.draw(); + + // restore previous gl state + GL11.glPopAttrib(); + + Minecraft.getMinecraft().mcProfiler.endSection(); + } + + private boolean lazyAdd = false; + private final List particles = new ArrayList(); + private final List newParticles = new ArrayList(); +} diff --git a/forestry_common/apiculture/forestry/apiculture/render/RenderBee.java b/forestry_common/apiculture/forestry/apiculture/render/RenderBee.java new file mode 100755 index 000000000..798178e0e --- /dev/null +++ b/forestry_common/apiculture/forestry/apiculture/render/RenderBee.java @@ -0,0 +1,39 @@ +/******************************************************************************* + * Copyright 2011-2014 by SirSengir + * + * This work is licensed under a Creative Commons Attribution-NonCommercial-NoDerivs 3.0 Unported License. + * + * To view a copy of this license, visit http://creativecommons.org/licenses/by-nc-nd/3.0/. + ******************************************************************************/ +package forestry.apiculture.render; + +import net.minecraft.client.renderer.entity.RenderLiving; +import net.minecraft.entity.Entity; +import net.minecraft.util.ResourceLocation; + +import forestry.apiculture.entities.EntityBee; + +public class RenderBee extends RenderLiving { + + ModelBee beeModel; + + public RenderBee() { + super(new ModelBee(), 0.15f); + beeModel = (ModelBee)mainModel; + } + + public void renderBee(EntityBee entity, double posX, double posY, double posZ, float par8, float par9) { + beeModel.setType(entity.getType()); + this.doRender(entity, posX, posY, posZ, par8, par9); + } + + @Override + public void doRender(Entity entity, double posX, double posY, double posZ, float par8, float par9) { + renderBee((EntityBee) entity, posX, posY, posZ, par8, par9); + } + + @Override + protected ResourceLocation getEntityTexture(Entity entity) { + return ((EntityBee)entity).getTexture(); + } +} diff --git a/forestry_common/apiculture/forestry/apiculture/render/TextureBiomefinder.java b/forestry_common/apiculture/forestry/apiculture/render/TextureBiomefinder.java new file mode 100755 index 000000000..69e397d78 --- /dev/null +++ b/forestry_common/apiculture/forestry/apiculture/render/TextureBiomefinder.java @@ -0,0 +1,91 @@ +/******************************************************************************* + * Copyright 2011-2014 by SirSengir + * + * This work is licensed under a Creative Commons Attribution-NonCommercial-NoDerivs 3.0 Unported License. + * + * To view a copy of this license, visit http://creativecommons.org/licenses/by-nc-nd/3.0/. + ******************************************************************************/ +package forestry.apiculture.render; + +import net.minecraft.client.Minecraft; +import net.minecraft.client.renderer.texture.TextureAtlasSprite; +import net.minecraft.client.renderer.texture.TextureUtil; +import net.minecraft.util.ChunkCoordinates; +import net.minecraft.world.World; + +public class TextureBiomefinder extends TextureAtlasSprite { + + private static TextureBiomefinder instance; + public static TextureBiomefinder getInstance() { return instance; } + + private ChunkCoordinates targetBiome; + + public double currentAngle; + public double angleDelta; + + public TextureBiomefinder() { + super("biomefinder"); + instance = this; + } + + public void setTargetCoordinates(ChunkCoordinates coordinates) { + this.targetBiome = coordinates; + } + + @Override + public void updateAnimation() { + Minecraft minecraft = Minecraft.getMinecraft(); + + if (minecraft.theWorld != null && minecraft.thePlayer != null) + updateCompass(minecraft.theWorld, minecraft.thePlayer.posX, minecraft.thePlayer.posZ, minecraft.thePlayer.rotationYaw, false, true); + else + updateCompass((World)null, 0.0d, 0.0d, 0.0d, true, true); + } + + public void updateCompass(World world, double playerX, double playerZ, double playerYaw, boolean par8, boolean hasSpin) { + + double targetAngle = 0.0d; + + if(world == null || targetBiome == null) { + // No target has the locator spinning wildly. + targetAngle = Math.random() * Math.PI * 2.0d; + } else { + double xPart = targetBiome.posX - playerX; + double yPart = targetBiome.posZ - playerZ; + targetAngle = (playerYaw - 90.0f) * Math.PI / 180.0d - Math.atan2(yPart, xPart); + } + + if(!hasSpin) { + currentAngle = targetAngle; + } else { + double angleChange; + + for (angleChange = targetAngle - currentAngle; angleChange < -Math.PI; angleChange += (Math.PI * 2D)) + ; + + while (angleChange >= Math.PI) + angleChange -= (Math.PI * 2D); + + if (angleChange < -1.0D) + angleChange = -1.0D; + + if (angleChange > 1.0D) + angleChange = 1.0D; + + this.angleDelta += angleChange * 0.1D; + this.angleDelta *= 0.8D; + this.currentAngle += this.angleDelta; + } + + int i; + + for (i = (int)((this.currentAngle / (Math.PI * 2D) + 1.0d) * this.framesTextureData.size()) % this.framesTextureData.size(); i < 0; i = (i + this.framesTextureData.size()) % this.framesTextureData.size()) + ; + + if (i != this.frameCounter) { + this.frameCounter = i; + TextureUtil.uploadTextureMipmap((int[][])this.framesTextureData.get(this.frameCounter), this.width, this.height, this.originX, this.originY, false, false); + } + + } +} diff --git a/forestry_common/apiculture/forestry/apiculture/trigger/TriggerNoFrames.java b/forestry_common/apiculture/forestry/apiculture/trigger/TriggerNoFrames.java new file mode 100755 index 000000000..7af0d63e3 --- /dev/null +++ b/forestry_common/apiculture/forestry/apiculture/trigger/TriggerNoFrames.java @@ -0,0 +1,44 @@ +/******************************************************************************* + * Copyright 2011-2014 by SirSengir + * + * This work is licensed under a Creative Commons Attribution-NonCommercial-NoDerivs 3.0 Unported License. + * + * To view a copy of this license, visit http://creativecommons.org/licenses/by-nc-nd/3.0/. + ******************************************************************************/ +package forestry.apiculture.trigger; + +import net.minecraft.tileentity.TileEntity; + +import net.minecraftforge.common.util.ForgeDirection; + +import buildcraft.api.gates.ITriggerParameter; + +import forestry.apiculture.gadgets.TileApiary; +import forestry.core.triggers.Trigger; + +public class TriggerNoFrames extends Trigger { + + public TriggerNoFrames() { + super("noFrames"); + } + + /** + * Return true if the tile given in parameter activates the trigger, given the parameters. + */ + @Override + public boolean isTriggerActive(ForgeDirection direction, TileEntity tile, ITriggerParameter parameter) { + + if (!(tile instanceof TileApiary)) + return false; + + for (int i = TileApiary.SLOT_FRAMES_1; i < TileApiary.SLOT_FRAMES_1 + TileApiary.SLOT_FRAMES_COUNT; i++) + if (((TileApiary) tile).getStackInSlot(i) == null) + continue; + else + return false; + + return true; + + } + +} diff --git a/forestry_common/apiculture/forestry/apiculture/worldgen/ComponentVillageBeeHouse.java b/forestry_common/apiculture/forestry/apiculture/worldgen/ComponentVillageBeeHouse.java new file mode 100755 index 000000000..52e2cf883 --- /dev/null +++ b/forestry_common/apiculture/forestry/apiculture/worldgen/ComponentVillageBeeHouse.java @@ -0,0 +1,378 @@ +/******************************************************************************* + * Copyright 2011-2014 by SirSengir + * + * This work is licensed under a Creative Commons Attribution-NonCommercial-NoDerivs 3.0 Unported License. + * + * To view a copy of this license, visit http://creativecommons.org/licenses/by-nc-nd/3.0/. + ******************************************************************************/ +package forestry.apiculture.worldgen; + +import java.util.ArrayList; +import java.util.List; +import java.util.Random; + +import net.minecraft.block.Block; +import net.minecraft.init.Blocks; +import net.minecraft.item.ItemStack; +import net.minecraft.tileentity.TileEntity; +import net.minecraft.world.World; +import net.minecraft.world.biome.BiomeGenBase; +import net.minecraft.world.gen.structure.StructureBoundingBox; +import net.minecraft.world.gen.structure.StructureComponent; +import net.minecraft.world.gen.structure.StructureVillagePieces; + +import net.minecraftforge.common.ChestGenHooks; + +import forestry.api.apiculture.BeeManager; +import forestry.api.apiculture.EnumBeeType; +import forestry.api.apiculture.FlowerManager; +import forestry.api.apiculture.IBee; +import forestry.api.apiculture.IBeeGenome; +import forestry.api.core.EnumHumidity; +import forestry.api.core.EnumTemperature; +import forestry.api.genetics.EnumTolerance; +import forestry.apiculture.gadgets.TileBeehouse; +import forestry.core.config.Defaults; +import forestry.core.config.ForestryBlock; +import forestry.core.config.ForestryItem; +import forestry.core.genetics.ClimateHelper; +import forestry.core.utils.StackUtils; +import forestry.plugins.PluginApiculture; + +public class ComponentVillageBeeHouse extends StructureVillagePieces.House1 { + + protected ItemStack[] buildingBlocks = new ItemStack[] { new ItemStack(ForestryBlock.planks1, 1, 15), new ItemStack(Blocks.log, 1, 0), }; + protected int averageGroundLevel = -1; + protected boolean isInDesert = false; + protected boolean hasChest = false; + + public ComponentVillageBeeHouse() { + // Populate buildingblocks with some defaults so it doesn't explode. + buildingBlocks[0] = new ItemStack(ForestryBlock.planks1); + buildingBlocks[1] = new ItemStack(ForestryBlock.log1); + } + + public ComponentVillageBeeHouse(StructureVillagePieces.Start startPiece, int componentType, Random random, StructureBoundingBox boundingBox, int coordBaseMode) { + super(startPiece, componentType, random, boundingBox, coordBaseMode); + + isInDesert = startPiece.inDesert; + + buildingBlocks[0] = new ItemStack(ForestryBlock.planks1, 1, random.nextInt(16)); + + Block woodBlock; + switch (random.nextInt(4)) { + case 1: + woodBlock = ForestryBlock.log2; + break; + case 2: + woodBlock = ForestryBlock.log3; + break; + case 3: + woodBlock = ForestryBlock.log4; + break; + default: + woodBlock = ForestryBlock.log1; + break; + } + + buildingBlocks[1] = new ItemStack(woodBlock, 1, random.nextInt(4)); + } + + /*@Override + protected void func_143012_a(NBTTagCompound par1nbtTagCompound) { + super.func_143012_a(par1nbtTagCompound); + par1nbtTagCompound.setBoolean("Chest", this.hasChest); + } + + @Override + protected void func_143011_b(NBTTagCompound par1nbtTagCompound) { + super.func_143011_b(par1nbtTagCompound); + this.hasChest = par1nbtTagCompound.getBoolean("Chest"); + }*/ + + @SuppressWarnings("rawtypes") + public static ComponentVillageBeeHouse buildComponent(StructureVillagePieces.Start startPiece, List par1List, Random random, int par3, int par4, int par5, + int par6, int par7) { + StructureBoundingBox bbox = StructureBoundingBox.getComponentToAddBoundingBox(par3, par4, par5, 0, 0, 0, 9, 9, 6, par6); + return canVillageGoDeeper(bbox) && StructureComponent.findIntersecting(par1List, bbox) == null ? new ComponentVillageBeeHouse(startPiece, par7, random, + bbox, par6) : null; + } + + @Override + public boolean addComponentParts(World world, Random random, StructureBoundingBox structBoundingBox) { + + if (this.averageGroundLevel < 0) { + this.averageGroundLevel = this.getAverageGroundLevel(world, structBoundingBox); + if (this.averageGroundLevel < 0) + return true; + + this.boundingBox.offset(0, this.averageGroundLevel - this.boundingBox.maxY + 8 - 1, 0); + } + + this.fillWithBlocks(world, structBoundingBox, 1, 1, 1, 7, 4, 4, Blocks.air, Blocks.air, false); + this.fillWithBlocks(world, structBoundingBox, 2, 1, 6, 8, 4, 10, Blocks.air, Blocks.air, false); + + // Garden + buildGarden(world, structBoundingBox); + + // Garden fence + this.fillWithBlocks(world, structBoundingBox, 1, 1, 6, 1, 1, 10, Blocks.fence, Blocks.fence, false); + this.fillWithBlocks(world, structBoundingBox, 8, 1, 6, 8, 1, 10, Blocks.fence, Blocks.fence, false); + this.fillWithBlocks(world, structBoundingBox, 2, 1, 10, 7, 1, 10, Blocks.fence, Blocks.fence, false); + + // Flowers + plantFlowerGarden(world, structBoundingBox, 2, 1, 5, 7, 1, 9); + + // Apiaries + buildApiaries(world, structBoundingBox, 3, 1, 4, 6, 1, 8); + + // Floor + this.fillWithBlocks(world, structBoundingBox, 1, 0, 1, 7, 0, 4, Blocks.planks, Blocks.planks, false); + + this.fillWithBlocks(world, structBoundingBox, 0, 0, 0, 0, 3, 5, Blocks.cobblestone, Blocks.cobblestone, false); + this.fillWithBlocks(world, structBoundingBox, 8, 0, 0, 8, 3, 5, Blocks.cobblestone, Blocks.cobblestone, false); + this.fillWithBlocks(world, structBoundingBox, 1, 0, 0, 7, 1, 0, Blocks.cobblestone, Blocks.cobblestone, false); + this.fillWithBlocks(world, structBoundingBox, 1, 0, 5, 7, 1, 5, Blocks.cobblestone, Blocks.cobblestone, false); + + this.fillBoxWith(world, structBoundingBox, 1, 2, 0, 7, 3, 0, buildingBlocks[0], false); + this.fillBoxWith(world, structBoundingBox, 1, 2, 5, 7, 3, 5, buildingBlocks[0], false); + this.fillBoxWith(world, structBoundingBox, 0, 4, 1, 8, 4, 1, buildingBlocks[0], false); + this.fillBoxWith(world, structBoundingBox, 0, 4, 4, 8, 4, 4, buildingBlocks[0], false); + this.fillBoxWith(world, structBoundingBox, 0, 5, 2, 8, 5, 3, buildingBlocks[0], false); + + this.placeBlockAtCurrentPosition(world, buildingBlocks[0], 0, 4, 2, structBoundingBox); + this.placeBlockAtCurrentPosition(world, buildingBlocks[0], 0, 4, 3, structBoundingBox); + this.placeBlockAtCurrentPosition(world, buildingBlocks[0], 8, 4, 2, structBoundingBox); + this.placeBlockAtCurrentPosition(world, buildingBlocks[0], 8, 4, 3, structBoundingBox); + + buildRoof(world, structBoundingBox); + + this.placeBlockAtCurrentPosition(world, buildingBlocks[1], 0, 2, 1, structBoundingBox); + this.placeBlockAtCurrentPosition(world, buildingBlocks[1], 0, 2, 4, structBoundingBox); + this.placeBlockAtCurrentPosition(world, buildingBlocks[1], 8, 2, 1, structBoundingBox); + this.placeBlockAtCurrentPosition(world, buildingBlocks[1], 8, 2, 4, structBoundingBox); + + this.placeBlockAtCurrentPosition(world, Blocks.glass_pane, 0, 0, 2, 2, structBoundingBox); + this.placeBlockAtCurrentPosition(world, Blocks.glass_pane, 0, 0, 2, 3, structBoundingBox); + + this.placeBlockAtCurrentPosition(world, Blocks.glass_pane, 0, 8, 2, 2, structBoundingBox); + this.placeBlockAtCurrentPosition(world, Blocks.glass_pane, 0, 8, 2, 3, structBoundingBox); + + // Windows garden side + this.placeBlockAtCurrentPosition(world, Blocks.glass_pane, 0, 2, 2, 5, structBoundingBox); + this.placeBlockAtCurrentPosition(world, Blocks.glass_pane, 0, 3, 2, 5, structBoundingBox); + this.placeBlockAtCurrentPosition(world, Blocks.glass_pane, 0, 4, 2, 5, structBoundingBox); + + this.placeBlockAtCurrentPosition(world, Blocks.glass_pane, 0, 5, 2, 0, structBoundingBox); + this.placeBlockAtCurrentPosition(world, Blocks.glass_pane, 0, 6, 2, 5, structBoundingBox); + + // Table/Bench + if (random.nextInt(10) < 1) { + this.placeBlockAtCurrentPosition(world, new ItemStack(ForestryBlock.core, 1, Defaults.DEFINITION_ESCRITOIRE_META), 1, 1, 3, structBoundingBox); + } + else { + this.placeBlockAtCurrentPosition(world, buildingBlocks[0], 1, 1, 3, structBoundingBox); + } + + this.placeBlockAtCurrentPosition(world, Blocks.air, 0, 2, 1, 0, structBoundingBox); + this.placeBlockAtCurrentPosition(world, Blocks.air, 0, 2, 2, 0, structBoundingBox); + this.placeDoorAtCurrentPosition(world, structBoundingBox, random, 2, 1, 0, this.getMetadataWithOffset(Blocks.wooden_door, 1)); + + if (isAirBlockAtCurrentPosition(world, 2, 0, -1, structBoundingBox) + && !isAirBlockAtCurrentPosition(world, 2, -1, -1, structBoundingBox)) + this.placeBlockAtCurrentPosition(world, Blocks.stone_stairs, + this.getMetadataWithOffset(Blocks.stone_stairs, 3), 2, 0, -1, structBoundingBox); + + this.placeBlockAtCurrentPosition(world, Blocks.air, 0, 6, 1, 5, structBoundingBox); + this.placeBlockAtCurrentPosition(world, Blocks.air, 0, 6, 2, 5, structBoundingBox); + + // Candles / Lighting + this.placeBlockAtCurrentPosition(world, Blocks.torch, 0, 2, 3, 4, structBoundingBox); + this.placeBlockAtCurrentPosition(world, Blocks.torch, 0, 6, 3, 4, structBoundingBox); + this.placeBlockAtCurrentPosition(world, Blocks.torch, 0, 2, 3, 1, structBoundingBox); + this.placeBlockAtCurrentPosition(world, Blocks.torch, 0, 6, 3, 1, structBoundingBox); + + this.placeDoorAtCurrentPosition(world, structBoundingBox, random, 6, 1, 5, this.getMetadataWithOffset(Blocks.wooden_door, 1)); + + for (int i = 0; i < 5; ++i) + for (int j = 0; j < 9; ++j) { + this.clearCurrentPositionBlocksUpwards(world, j, 7, i, structBoundingBox); + this.func_151554_b(world, Blocks.cobblestone, 0, j, -1, i, structBoundingBox); + } + + this.generateStructureChestContents(world, structBoundingBox, random, 7, 1, 4, + ChestGenHooks.getItems(Defaults.CHEST_GEN_HOOK_NATURALIST_CHEST, random), + random.nextInt(4) + random.nextInt(4) + 5); + + spawnVillagers(world, boundingBox, 7, 1, 1, 2); + + return true; + } + + private void buildRoof(World world, StructureBoundingBox structBoundingBox) { + int rotatedMetaDoor = this.getMetadataWithOffset(Blocks.oak_stairs, 3); + int rotatedMetaGarden = this.getMetadataWithOffset(Blocks.oak_stairs, 2); + + for (int i = -1; i <= 2; ++i) + for (int j = 0; j <= 8; ++j) { + this.placeBlockAtCurrentPosition(world, Blocks.oak_stairs, rotatedMetaDoor, j, 4 + i, i, structBoundingBox); + this.placeBlockAtCurrentPosition(world, Blocks.oak_stairs, rotatedMetaGarden, j, 4 + i, 5 - i, structBoundingBox); + } + } + + protected void buildGarden(World world, StructureBoundingBox box) { + + Block ground = Blocks.dirt; + if (isInDesert) + ground = Blocks.sand; + + for (int i = 1; i <= 8; i++) + for (int j = 6; j <= 10; j++) + func_151554_b(world, ground, 0, i, 0, j, box); + } + + protected void plantFlowerGarden(World world, StructureBoundingBox box, int minX, int minY, int minZ, int maxX, int maxY, int maxZ) { + + if (isInDesert) { + placeBlockAtCurrentPosition(world, Blocks.cactus, 0, 4, 1, 7, box); + return; + } + + for (int i = minY; i <= maxY; ++i) + for (int j = minX; j <= maxX; ++j) + for (int k = minZ; k <= maxZ; ++k) + if (world.rand.nextBoolean()) { + int xCoord = this.getXWithOffset(j, k); + int yCoord = this.getYWithOffset(i); + int zCoord = this.getZWithOffset(j, k); + + if (!Blocks.red_flower.canBlockStay(world, xCoord, yCoord, zCoord)) + continue; + + ItemStack flower = FlowerManager.plainFlowers.get(world.rand.nextInt(FlowerManager.plainFlowers.size())); + this.placeBlockAtCurrentPosition(world, flower, j, i, k, box); + } + } + + protected void buildApiaries(World world, StructureBoundingBox box, int minX, int minY, int minZ, int maxX, int maxY, int maxZ) { + populateApiary(world, box, 3, 1, 8); + populateApiary(world, box, 6, 1, 8); + } + + private void populateApiary(World world, StructureBoundingBox box, int x, int y, int z) { + int xCoord = this.getXWithOffset(x, z); + int yCoord = this.getYWithOffset(y); + int zCoord = this.getZWithOffset(x, z); + + if (box.isVecInside(xCoord, yCoord, zCoord) && world.getBlock(xCoord, yCoord, zCoord) != ForestryBlock.apiculture + && world.blockExists(xCoord, yCoord - 1, zCoord)) { + + world.setBlock(xCoord, yCoord, zCoord, ForestryBlock.apiculture, Defaults.DEFINITION_APIARY_META, + Defaults.FLAG_BLOCK_SYNCH); + ForestryBlock.apiculture.onBlockAdded(world, xCoord, yCoord, zCoord); + + TileEntity tile = world.getTileEntity(xCoord, yCoord, zCoord); + if (tile instanceof TileBeehouse) { + TileBeehouse apiary = ((TileBeehouse) tile); + apiary.initialize(); + apiary.setSlotContents(TileBeehouse.SLOT_QUEEN, + PluginApiculture.beeInterface.getMemberStack(getVillageBee(world, xCoord, yCoord, zCoord), EnumBeeType.PRINCESS.ordinal())); + apiary.setSlotContents(TileBeehouse.SLOT_DRONE, + PluginApiculture.beeInterface.getMemberStack(getVillageBee(world, xCoord, yCoord, zCoord), EnumBeeType.DRONE.ordinal())); + + for (int i = TileBeehouse.SLOT_FRAMES_1; i < TileBeehouse.SLOT_FRAMES_1 + TileBeehouse.SLOT_FRAMES_COUNT; i++) { + float roll = world.rand.nextFloat(); + if (roll < 0.2f) + apiary.setSlotContents(i, ForestryItem.frameUntreated.getItemStack()); + else if (roll < 0.4f) + apiary.setSlotContents(i, ForestryItem.frameImpregnated.getItemStack()); + else if (roll < 0.6) + apiary.setSlotContents(i, ForestryItem.frameProven.getItemStack()); + } + + } + } + } + + private IBee getVillageBee(World world, int xCoord, int yCoord, int zCoord) { + + // Get current biome + BiomeGenBase biome = world.getBiomeGenForCoords(xCoord, zCoord); + + ArrayList candidates; + if (BeeManager.villageBees[1] != null && BeeManager.villageBees[1].size() > 0 && world.rand.nextDouble() < 0.2) + candidates = BeeManager.villageBees[1]; + else + candidates = BeeManager.villageBees[0]; + + // Add bees that can live in this environment + ArrayList valid = new ArrayList(); + for (IBeeGenome genome : candidates) + if (checkBiomeHazard(genome, biome.temperature, biome.rainfall)) + valid.add(genome); + + // No valid ones found, return any of the common ones. + if (valid.isEmpty()) + return PluginApiculture.beeInterface.getBee(world, BeeManager.villageBees[0].get(world.rand.nextInt(BeeManager.villageBees[0].size()))); + + return PluginApiculture.beeInterface.getBee(world, valid.get(world.rand.nextInt(valid.size()))); + } + + private boolean checkBiomeHazard(IBeeGenome genome, float temperature, float humidity) { + + EnumTemperature beeTemperature = genome.getPrimary().getTemperature(); + EnumTolerance temperatureTolerance = genome.getToleranceTemp(); + + ArrayList toleratedTemperatures = ClimateHelper.getToleratedTemperature(beeTemperature, temperatureTolerance); + boolean validTemp = false; + + validTemp = toleratedTemperatures.contains(EnumTemperature.getFromValue(temperature)); + + if (!validTemp) + return false; + + EnumHumidity beeHumidity = genome.getPrimary().getHumidity(); + EnumTolerance humidityTolerance = genome.getToleranceHumid(); + + ArrayList toleratedHumidity = ClimateHelper.getToleratedHumidity(beeHumidity, humidityTolerance); + + boolean validHumidity = false; + + validHumidity = toleratedHumidity.contains(EnumHumidity.getFromValue(humidity)); + + return validHumidity; + } + + protected void fillBoxWith(World world, StructureBoundingBox box, int par3, int par4, int par5, int par6, int par7, int par8, ItemStack buildingBlock, + boolean replace) { + + for (int var14 = par4; var14 <= par7; ++var14) + for (int var15 = par3; var15 <= par6; ++var15) + for (int var16 = par5; var16 <= par8; ++var16) + if (!replace || !isAirBlockAtCurrentPosition(world, var15, var14, var16, box)) + this.placeBlockAtCurrentPosition(world, buildingBlock, var15, var14, var16, box); + } + + protected void placeBlockAtCurrentPosition(World world, ItemStack buildingBlock, int par4, int par5, int par6, StructureBoundingBox par7StructureBoundingBox) { + int var8 = this.getXWithOffset(par4, par6); + int var9 = this.getYWithOffset(par5); + int var10 = this.getZWithOffset(par4, par6); + + if (par7StructureBoundingBox.isVecInside(var8, var9, var10)) + world.setBlock(var8, var9, var10, StackUtils.getBlock(buildingBlock), buildingBlock.getItemDamage(), Defaults.FLAG_BLOCK_SYNCH); + } + + @Override + protected int getVillagerType(int villagerCount) { + if (villagerCount <= 0) + return Defaults.ID_VILLAGER_BEEKEEPER; + else + return Defaults.ID_VILLAGER_LUMBERJACK; + } + + private boolean isAirBlockAtCurrentPosition(World world, int x, int y, int z, StructureBoundingBox box) { + // TODO: replace with isAir + return getBlockAtCurrentPosition(world, x, y, z, box) == Blocks.air; + } + +} diff --git a/forestry_common/apiculture/forestry/apiculture/worldgen/HiveDecorator.java b/forestry_common/apiculture/forestry/apiculture/worldgen/HiveDecorator.java new file mode 100755 index 000000000..edfd09248 --- /dev/null +++ b/forestry_common/apiculture/forestry/apiculture/worldgen/HiveDecorator.java @@ -0,0 +1,74 @@ +/******************************************************************************* + * Copyright 2011-2014 by SirSengir + * + * This work is licensed under a Creative Commons Attribution-NonCommercial-NoDerivs 3.0 Unported License. + * + * To view a copy of this license, visit http://creativecommons.org/licenses/by-nc-nd/3.0/. + ******************************************************************************/ +package forestry.apiculture.worldgen; + +import java.util.Random; + +import net.minecraft.world.World; + +import cpw.mods.fml.common.eventhandler.SubscribeEvent; + +import net.minecraftforge.common.util.EnumHelper; +import net.minecraftforge.event.terraingen.PopulateChunkEvent; +import net.minecraftforge.event.terraingen.PopulateChunkEvent.Populate.EventType; +import net.minecraftforge.event.terraingen.TerrainGen; + +/** + * + * @author CovertJaguar + */ +public class HiveDecorator { + + public static final EventType EVENT_TYPE = EnumHelper.addEnum(EventType.class, "FORESTRY_HIVES", new Class[0], new Object[0]); + private static HiveDecorator instance; + private final WorldGenHiveForest forest = new WorldGenHiveForest(); + private final WorldGenHiveJungle jungle = new WorldGenHiveJungle(); + private final WorldGenHiveMeadows meadows = new WorldGenHiveMeadows(); + private final WorldGenHiveParched parched = new WorldGenHiveParched(); + private final WorldGenHiveEnd end = new WorldGenHiveEnd(); + private final WorldGenHiveSnow snow = new WorldGenHiveSnow(); + private final WorldGenHiveSwamp swamp = new WorldGenHiveSwamp(); + + public static HiveDecorator instance() { + if (instance == null) { + instance = new HiveDecorator(); + } + return instance; + } + + private HiveDecorator() { + } + + @SubscribeEvent + public void generate(PopulateChunkEvent.Post event) { + if (!TerrainGen.populate(event.chunkProvider, event.world, event.rand, event.chunkX, event.chunkZ, event.hasVillageGenerated, EVENT_TYPE)) { + return; + } + decorateHives(event.world, event.rand, event.chunkX * 16, event.chunkZ * 16); + } + + private void decorateHives(World world, Random rand, int worldX, int worldZ) { + genHive(world, rand, worldX, worldZ, 42, 3, forest); + genHive(world, rand, worldX, worldZ, 62, 4, jungle); + genHive(world, rand, worldX, worldZ, 42, 1, meadows); + genHive(world, rand, worldX, worldZ, 42, 1, parched); + genHive(world, rand, worldX, worldZ, 42, 4, end); + genHive(world, rand, worldX, worldZ, 42, 2, snow); + genHive(world, rand, worldX, worldZ, 42, 2, swamp); + } + + private void genHive(World world, Random rand, int worldX, int worldZ, int height, int attempts, WorldGenHive gen) { + for (int i = 0; i < attempts; i++) { + int randPosX = worldX + rand.nextInt(16); + int randPosY = height + rand.nextInt(50); + int randPosZ = worldZ + rand.nextInt(16); + if (gen.generate(world, rand, randPosX, randPosY, randPosZ)) + return; + } + } +} diff --git a/forestry_common/apiculture/forestry/apiculture/worldgen/WorldGenHive.java b/forestry_common/apiculture/forestry/apiculture/worldgen/WorldGenHive.java new file mode 100755 index 000000000..3b80ad7cb --- /dev/null +++ b/forestry_common/apiculture/forestry/apiculture/worldgen/WorldGenHive.java @@ -0,0 +1,88 @@ +/******************************************************************************* + * Copyright 2011-2014 by SirSengir + * + * This work is licensed under a Creative Commons Attribution-NonCommercial-NoDerivs 3.0 Unported License. + * + * To view a copy of this license, visit http://creativecommons.org/licenses/by-nc-nd/3.0/. + ******************************************************************************/ +package forestry.apiculture.worldgen; + +import java.util.Random; + +import net.minecraft.block.Block; +import net.minecraft.init.Blocks; +import net.minecraft.world.World; +import net.minecraft.world.gen.feature.WorldGenerator; + +import net.minecraftforge.common.IPlantable; + +import forestry.core.config.Defaults; +import forestry.core.config.ForestryBlock; + +public abstract class WorldGenHive extends WorldGenerator { + + @Override + public abstract boolean generate(World world, Random random, int x, int y, int z); + + protected boolean tryPlaceTreeHive(World world, int x, int y, int z, int meta) { + if (!world.isAirBlock(x, y, z)) + return false; + + Block b = world.getBlock(x, y + 1, z); + if (b == null || !b.isLeaves(world, x, y + 1, z)) + return false; + + if (world.isAirBlock(x, y - 1, z)) { + setHive(world, x, y, z, meta); + return true; + } + return false; + } + + protected boolean tryPlaceGroundHive(World world, int x, int y, int z, int meta, Block... groundBlocks) { + if (!world.isAirBlock(x, y, z)) { + Block block = world.getBlock(x, y, z); + if (block != Blocks.snow_layer && !(block instanceof IPlantable)) + return false; + } + + if (!world.isAirBlock(x, y + 1, z)) + return false; + + if (isAcceptableBlock(world, x, y - 1, z, groundBlocks)) { + setHive(world, x, y, z, meta); + return true; + } + + return false; + } + + private boolean isAcceptableBlock(World world, int x, int y, int z, Block... blocks) { + Block block = world.getBlock(x, y, z); + if (block == null) + return false; + for (Block testBlock : blocks) { + if (block.isReplaceableOreGen(world, x, y, z, testBlock)) + return true; + } + return false; + } + + protected void setHive(World world, int x, int y, int z, int meta) { + boolean placed = world.setBlock(x, y, z, ForestryBlock.beehives, meta, Defaults.FLAG_BLOCK_SYNCH); + if (!placed) + return; + + if (world.getBlock(x, y, z) != ForestryBlock.beehives) + return; + + ForestryBlock.beehives.onBlockAdded(world, x, y, z); + world.markBlockForUpdate(x, y, z); + + postGen(world, x, y, z, meta); + } + + protected void postGen(World world, int x, int y, int z, int meta) { + ForestryBlock.beehives.onBlockPlaced(world, x, y, z, 0, 0.0f, 0.0f, 0.0f, meta); + } +} diff --git a/forestry_common/apiculture/forestry/apiculture/worldgen/WorldGenHiveEnd.java b/forestry_common/apiculture/forestry/apiculture/worldgen/WorldGenHiveEnd.java new file mode 100755 index 000000000..e0c51f334 --- /dev/null +++ b/forestry_common/apiculture/forestry/apiculture/worldgen/WorldGenHiveEnd.java @@ -0,0 +1,27 @@ +/******************************************************************************* + * Copyright 2011-2014 by SirSengir + * + * This work is licensed under a Creative Commons Attribution-NonCommercial-NoDerivs 3.0 Unported License. + * + * To view a copy of this license, visit http://creativecommons.org/licenses/by-nc-nd/3.0/. + ******************************************************************************/ +package forestry.apiculture.worldgen; + +import java.util.Random; + +import net.minecraft.init.Blocks; +import net.minecraft.world.World; +import net.minecraft.world.biome.BiomeGenBase; + +public class WorldGenHiveEnd extends WorldGenHive { + + @Override + public boolean generate(World world, Random random, int x, int y, int z) { + + BiomeGenBase biome = world.getWorldChunkManager().getBiomeGenAt(x, z); + if (biome.biomeID != BiomeGenBase.sky.biomeID) + return false; + + return tryPlaceGroundHive(world, x, y, z, 5, Blocks.end_stone); + } +} diff --git a/forestry_common/apiculture/forestry/apiculture/worldgen/WorldGenHiveForest.java b/forestry_common/apiculture/forestry/apiculture/worldgen/WorldGenHiveForest.java new file mode 100755 index 000000000..f2d6d43b0 --- /dev/null +++ b/forestry_common/apiculture/forestry/apiculture/worldgen/WorldGenHiveForest.java @@ -0,0 +1,31 @@ +/******************************************************************************* + * Copyright 2011-2014 by SirSengir + * + * This work is licensed under a Creative Commons Attribution-NonCommercial-NoDerivs 3.0 Unported License. + * + * To view a copy of this license, visit http://creativecommons.org/licenses/by-nc-nd/3.0/. + ******************************************************************************/ +package forestry.apiculture.worldgen; + +import java.util.Random; + +import net.minecraft.world.World; +import net.minecraft.world.biome.BiomeGenBase; + +import forestry.api.core.EnumHumidity; +import forestry.api.core.EnumTemperature; + +public class WorldGenHiveForest extends WorldGenHive { + + @Override + public boolean generate(World world, Random random, int x, int y, int z) { + + BiomeGenBase biome = world.getWorldChunkManager().getBiomeGenAt(x, z); + if (EnumTemperature.getFromValue(biome.temperature) != EnumTemperature.NORMAL || + EnumHumidity.getFromValue(biome.rainfall) != EnumHumidity.NORMAL) + return false; + + return tryPlaceTreeHive(world, x, y, z, 1); + } + +} diff --git a/forestry_common/apiculture/forestry/apiculture/worldgen/WorldGenHiveJungle.java b/forestry_common/apiculture/forestry/apiculture/worldgen/WorldGenHiveJungle.java new file mode 100755 index 000000000..8edd94056 --- /dev/null +++ b/forestry_common/apiculture/forestry/apiculture/worldgen/WorldGenHiveJungle.java @@ -0,0 +1,30 @@ +/******************************************************************************* + * Copyright 2011-2014 by SirSengir + * + * This work is licensed under a Creative Commons Attribution-NonCommercial-NoDerivs 3.0 Unported License. + * + * To view a copy of this license, visit http://creativecommons.org/licenses/by-nc-nd/3.0/. + ******************************************************************************/ +package forestry.apiculture.worldgen; + +import java.util.Random; + +import net.minecraft.world.World; +import net.minecraft.world.biome.BiomeGenBase; + +import forestry.api.core.EnumHumidity; +import forestry.api.core.EnumTemperature; + +public class WorldGenHiveJungle extends WorldGenHive { + + @Override + public boolean generate(World world, Random random, int x, int y, int z) { + + BiomeGenBase biome = world.getWorldChunkManager().getBiomeGenAt(x, z); + if (EnumTemperature.getFromValue(biome.temperature) != EnumTemperature.WARM + || EnumHumidity.getFromValue(biome.rainfall) != EnumHumidity.DAMP) + return false; + + return tryPlaceTreeHive(world, x, y, z, 4); + } +} diff --git a/forestry_common/apiculture/forestry/apiculture/worldgen/WorldGenHiveMeadows.java b/forestry_common/apiculture/forestry/apiculture/worldgen/WorldGenHiveMeadows.java new file mode 100755 index 000000000..23623a8b9 --- /dev/null +++ b/forestry_common/apiculture/forestry/apiculture/worldgen/WorldGenHiveMeadows.java @@ -0,0 +1,31 @@ +/******************************************************************************* + * Copyright 2011-2014 by SirSengir + * + * This work is licensed under a Creative Commons Attribution-NonCommercial-NoDerivs 3.0 Unported License. + * + * To view a copy of this license, visit http://creativecommons.org/licenses/by-nc-nd/3.0/. + ******************************************************************************/ +package forestry.apiculture.worldgen; + +import java.util.Random; + +import net.minecraft.init.Blocks; +import net.minecraft.world.World; +import net.minecraft.world.biome.BiomeGenBase; + +import forestry.api.core.EnumHumidity; +import forestry.api.core.EnumTemperature; + +public class WorldGenHiveMeadows extends WorldGenHive { + + @Override + public boolean generate(World world, Random random, int x, int y, int z) { + + BiomeGenBase biome = world.getWorldChunkManager().getBiomeGenAt(x, z); + if (EnumTemperature.getFromValue(biome.temperature) != EnumTemperature.NORMAL + || EnumHumidity.getFromValue(biome.rainfall) != EnumHumidity.NORMAL) + return false; + + return tryPlaceGroundHive(world, x, y, z, 2, Blocks.dirt, Blocks.grass); + } +} diff --git a/forestry_common/apiculture/forestry/apiculture/worldgen/WorldGenHiveParched.java b/forestry_common/apiculture/forestry/apiculture/worldgen/WorldGenHiveParched.java new file mode 100755 index 000000000..95ac4f354 --- /dev/null +++ b/forestry_common/apiculture/forestry/apiculture/worldgen/WorldGenHiveParched.java @@ -0,0 +1,31 @@ +/******************************************************************************* + * Copyright 2011-2014 by SirSengir + * + * This work is licensed under a Creative Commons Attribution-NonCommercial-NoDerivs 3.0 Unported License. + * + * To view a copy of this license, visit http://creativecommons.org/licenses/by-nc-nd/3.0/. + ******************************************************************************/ +package forestry.apiculture.worldgen; + +import java.util.Random; + +import net.minecraft.init.Blocks; +import net.minecraft.world.World; +import net.minecraft.world.biome.BiomeGenBase; + +import forestry.api.core.EnumHumidity; +import forestry.api.core.EnumTemperature; + +public class WorldGenHiveParched extends WorldGenHive { + + @Override + public boolean generate(World world, Random random, int x, int y, int z) { + + BiomeGenBase biome = world.getWorldChunkManager().getBiomeGenAt(x, z); + if (EnumTemperature.getFromValue(biome.temperature) != EnumTemperature.HOT + || EnumHumidity.getFromValue(biome.rainfall) != EnumHumidity.ARID) + return false; + + return tryPlaceGroundHive(world, x, y, z, 3, Blocks.sand, Blocks.sandstone); + } +} diff --git a/forestry_common/apiculture/forestry/apiculture/worldgen/WorldGenHiveSnow.java b/forestry_common/apiculture/forestry/apiculture/worldgen/WorldGenHiveSnow.java new file mode 100755 index 000000000..ab6eaf09b --- /dev/null +++ b/forestry_common/apiculture/forestry/apiculture/worldgen/WorldGenHiveSnow.java @@ -0,0 +1,35 @@ +/******************************************************************************* + * Copyright 2011-2014 by SirSengir + * + * This work is licensed under a Creative Commons Attribution-NonCommercial-NoDerivs 3.0 Unported License. + * + * To view a copy of this license, visit http://creativecommons.org/licenses/by-nc-nd/3.0/. + ******************************************************************************/ +package forestry.apiculture.worldgen; + +import java.util.Random; + +import net.minecraft.init.Blocks; +import net.minecraft.world.World; +import net.minecraft.world.biome.BiomeGenBase; + +import forestry.api.core.EnumTemperature; + +public class WorldGenHiveSnow extends WorldGenHive { + + @Override + public boolean generate(World world, Random random, int x, int y, int z) { + + BiomeGenBase biome = world.getWorldChunkManager().getBiomeGenAt(x, z); + if (EnumTemperature.getFromValue(biome.temperature) != EnumTemperature.ICY + && EnumTemperature.getFromValue(biome.temperature) != EnumTemperature.COLD) + return false; + + if (tryPlaceGroundHive(world, x, y, z, 6, Blocks.dirt, Blocks.grass)) { + world.setBlock(x, y + 1, z, Blocks.snow_layer, 0, 0); + return true; + } + + return false; + } +} diff --git a/forestry_common/apiculture/forestry/apiculture/worldgen/WorldGenHiveSwamer.java b/forestry_common/apiculture/forestry/apiculture/worldgen/WorldGenHiveSwamer.java new file mode 100755 index 000000000..dc35f009e --- /dev/null +++ b/forestry_common/apiculture/forestry/apiculture/worldgen/WorldGenHiveSwamer.java @@ -0,0 +1,46 @@ +/******************************************************************************* + * Copyright 2011-2014 by SirSengir + * + * This work is licensed under a Creative Commons Attribution-NonCommercial-NoDerivs 3.0 Unported License. + * + * To view a copy of this license, visit http://creativecommons.org/licenses/by-nc-nd/3.0/. + ******************************************************************************/ +package forestry.apiculture.worldgen; + +import java.util.Random; + +import net.minecraft.item.ItemStack; +import net.minecraft.tileentity.TileEntity; +import net.minecraft.world.World; + +import forestry.apiculture.gadgets.TileSwarm; + +/** + * + * @author CovertJaguar + */ +public class WorldGenHiveSwamer extends WorldGenHive { + + private ItemStack[] bees; + + public WorldGenHiveSwamer(ItemStack[] bees) { + this.bees = bees; + } + + @Override + public boolean generate(World world, Random random, int x, int y, int z) { + if (world.blockExists(x, y, z) && world.isAirBlock(x, y, z) && (!world.isAirBlock(x, y - 1, z) || !world.isAirBlock(x, y + 1, z))) { + setHive(world, x, y, z, 8); + return true; + } + + return false; + } + + @Override + protected void postGen(World world, int x, int y, int z, int meta) { + TileEntity tile = world.getTileEntity(x, y, z); + if (tile instanceof TileSwarm) + ((TileSwarm) tile).setContained(bees); + } +} diff --git a/forestry_common/apiculture/forestry/apiculture/worldgen/WorldGenHiveSwamp.java b/forestry_common/apiculture/forestry/apiculture/worldgen/WorldGenHiveSwamp.java new file mode 100755 index 000000000..f7fbb286f --- /dev/null +++ b/forestry_common/apiculture/forestry/apiculture/worldgen/WorldGenHiveSwamp.java @@ -0,0 +1,31 @@ +/******************************************************************************* + * Copyright 2011-2014 by SirSengir + * + * This work is licensed under a Creative Commons Attribution-NonCommercial-NoDerivs 3.0 Unported License. + * + * To view a copy of this license, visit http://creativecommons.org/licenses/by-nc-nd/3.0/. + ******************************************************************************/ +package forestry.apiculture.worldgen; + +import java.util.Random; + +import net.minecraft.init.Blocks; +import net.minecraft.world.World; +import net.minecraft.world.biome.BiomeGenBase; + +import forestry.api.core.EnumHumidity; +import forestry.api.core.EnumTemperature; + +public class WorldGenHiveSwamp extends WorldGenHive { + + @Override + public boolean generate(World world, Random random, int x, int y, int z) { + + BiomeGenBase biome = world.getWorldChunkManager().getBiomeGenAt(x, z); + if (EnumTemperature.getFromValue(biome.temperature) != EnumTemperature.NORMAL + || EnumHumidity.getFromValue(biome.rainfall) != EnumHumidity.DAMP) + return false; + + return tryPlaceGroundHive(world, x, y, z, 7, Blocks.dirt, Blocks.grass); + } +} diff --git a/forestry_common/apiculture/forestry/plugins/PluginApiculture.java b/forestry_common/apiculture/forestry/plugins/PluginApiculture.java new file mode 100755 index 000000000..792727b8a --- /dev/null +++ b/forestry_common/apiculture/forestry/plugins/PluginApiculture.java @@ -0,0 +1,1218 @@ +/******************************************************************************* + * Copyright 2011-2014 by SirSengir + * + * This work is licensed under a Creative Commons Attribution-NonCommercial-NoDerivs 3.0 Unported License. + * + * To view a copy of this license, visit http://creativecommons.org/licenses/by-nc-nd/3.0/. + ******************************************************************************/ +package forestry.plugins; + +import java.util.ArrayList; +import java.util.logging.Level; +import java.util.logging.Logger; + +import net.minecraft.block.Block; +import net.minecraft.block.material.Material; +import net.minecraft.command.ICommand; +import net.minecraft.init.Blocks; +import net.minecraft.init.Items; +import net.minecraft.item.Item; +import net.minecraft.item.ItemStack; +import net.minecraft.nbt.NBTTagCompound; +import net.minecraft.potion.Potion; +import net.minecraft.util.IIcon; +import net.minecraft.util.WeightedRandomChestContent; + +import cpw.mods.fml.common.FMLCommonHandler; +import cpw.mods.fml.common.SidedProxy; +import cpw.mods.fml.common.event.FMLInterModComms.IMCMessage; +import cpw.mods.fml.common.eventhandler.SubscribeEvent; +import cpw.mods.fml.common.network.IGuiHandler; +import cpw.mods.fml.common.registry.GameData; +import cpw.mods.fml.common.registry.GameRegistry; +import cpw.mods.fml.common.registry.VillagerRegistry; +import cpw.mods.fml.relauncher.Side; +import cpw.mods.fml.relauncher.SideOnly; + +import net.minecraftforge.client.event.TextureStitchEvent; +import net.minecraftforge.common.BiomeDictionary; +import net.minecraftforge.common.ChestGenHooks; +import net.minecraftforge.common.MinecraftForge; +import net.minecraftforge.oredict.OreDictionary; + +import forestry.api.apiculture.BeeManager; +import forestry.api.apiculture.EnumBeeType; +import forestry.api.apiculture.FlowerManager; +import forestry.api.apiculture.IBee; +import forestry.api.apiculture.IBeeGenome; +import forestry.api.apiculture.IBeeRoot; +import forestry.api.apiculture.IHiveDrop; +import forestry.api.core.EnumHumidity; +import forestry.api.core.EnumTemperature; +import forestry.api.core.PluginInfo; +import forestry.api.core.Tabs; +import forestry.api.genetics.AlleleManager; +import forestry.api.genetics.IAllele; +import forestry.api.genetics.IClassification; +import forestry.api.genetics.IClassification.EnumClassLevel; +import forestry.api.recipes.RecipeManagers; +import forestry.apiculture.CommandBeekeepingMode; +import forestry.apiculture.CommandGiveBee; +import forestry.apiculture.FlowerProviderCacti; +import forestry.apiculture.FlowerProviderEnd; +import forestry.apiculture.FlowerProviderGourd; +import forestry.apiculture.FlowerProviderJungle; +import forestry.apiculture.FlowerProviderMushroom; +import forestry.apiculture.FlowerProviderNetherwart; +import forestry.apiculture.FlowerProviderVanilla; +import forestry.apiculture.FlowerProviderWheat; +import forestry.apiculture.GuiHandlerApiculture; +import forestry.apiculture.PacketHandlerApiculture; +import forestry.apiculture.SaveEventHandlerApiculture; +import forestry.apiculture.VillageHandlerApiculture; +import forestry.apiculture.gadgets.BlockAlveary; +import forestry.apiculture.gadgets.BlockBeehives; +import forestry.apiculture.gadgets.BlockCandle; +import forestry.apiculture.gadgets.BlockStump; +import forestry.apiculture.gadgets.StructureLogicAlveary; +import forestry.apiculture.gadgets.TileAlvearyFan; +import forestry.apiculture.gadgets.TileAlvearyHeater; +import forestry.apiculture.gadgets.TileAlvearyHygroregulator; +import forestry.apiculture.gadgets.TileAlvearyPlain; +import forestry.apiculture.gadgets.TileAlvearySieve; +import forestry.apiculture.gadgets.TileAlvearyStabiliser; +import forestry.apiculture.gadgets.TileAlvearySwarmer; +import forestry.apiculture.gadgets.TileApiaristChest; +import forestry.apiculture.gadgets.TileApiary; +import forestry.apiculture.gadgets.TileBeehouse; +import forestry.apiculture.gadgets.TileCandle; +import forestry.apiculture.gadgets.TileSwarm; +import forestry.apiculture.genetics.AlleleBeeSpecies; +import forestry.apiculture.genetics.AlleleEffectAggressive; +import forestry.apiculture.genetics.AlleleEffectCreeper; +import forestry.apiculture.genetics.AlleleEffectExploration; +import forestry.apiculture.genetics.AlleleEffectGlacial; +import forestry.apiculture.genetics.AlleleEffectHeroic; +import forestry.apiculture.genetics.AlleleEffectIgnition; +import forestry.apiculture.genetics.AlleleEffectMiasmic; +import forestry.apiculture.genetics.AlleleEffectMisanthrope; +import forestry.apiculture.genetics.AlleleEffectNone; +import forestry.apiculture.genetics.AlleleEffectPotion; +import forestry.apiculture.genetics.AlleleEffectRadioactive; +import forestry.apiculture.genetics.AlleleEffectRepulsion; +import forestry.apiculture.genetics.AlleleEffectResurrection; +import forestry.apiculture.genetics.AlleleEffectSnowing; +import forestry.apiculture.genetics.AlleleFlowers; +import forestry.apiculture.genetics.Bee; +import forestry.apiculture.genetics.BeeHelper; +import forestry.apiculture.genetics.BeeMutation; +import forestry.apiculture.genetics.BeeTemplates; +import forestry.apiculture.genetics.BeekeepingMode; +import forestry.apiculture.genetics.BranchBees; +import forestry.apiculture.genetics.HiveDrop; +import forestry.apiculture.genetics.JubilanceNone; +import forestry.apiculture.genetics.JubilanceProviderHermit; +import forestry.apiculture.genetics.MutationTimeLimited; +import forestry.apiculture.items.ItemAlvearyBlock; +import forestry.apiculture.items.ItemArmorApiarist; +import forestry.apiculture.items.ItemBeeGE; +import forestry.apiculture.items.ItemBeealyzer; +import forestry.apiculture.items.ItemCandleBlock; +import forestry.apiculture.items.ItemHiveFrame; +import forestry.apiculture.items.ItemHoneycomb; +import forestry.apiculture.items.ItemImprinter; +import forestry.apiculture.items.ItemWaxCast; +import forestry.apiculture.proxy.ProxyApiculture; +import forestry.apiculture.trigger.TriggerNoFrames; +import forestry.apiculture.worldgen.HiveDecorator; +import forestry.core.GameMode; +import forestry.core.config.Config; +import forestry.core.config.Configuration; +import forestry.core.config.Defaults; +import forestry.core.config.ForestryBlock; +import forestry.core.config.ForestryItem; +import forestry.core.config.Property; +import forestry.core.gadgets.BlockBase; +import forestry.core.gadgets.MachineDefinition; +import forestry.core.genetics.Allele; +import forestry.core.interfaces.IOreDictionaryHandler; +import forestry.core.interfaces.IPacketHandler; +import forestry.core.interfaces.ISaveEventHandler; +import forestry.core.items.ItemCrated; +import forestry.core.items.ItemForestry; +import forestry.core.items.ItemForestryBlock; +import forestry.core.items.ItemOverlay; +import forestry.core.items.ItemOverlay.OverlayInfo; +import forestry.core.proxy.Proxies; +import forestry.core.render.EntitySnowFX; +import forestry.core.triggers.Trigger; +import forestry.core.utils.LiquidHelper; +import forestry.core.utils.ShapedRecipeCustom; + +@PluginInfo(pluginID = "Apiculture", name = "Apiculture", author = "SirSengir", url = Defaults.URL, description = "Adds bees, beekeeping and bee products. Affects world generation.") +public class PluginApiculture extends NativePlugin { + + @SidedProxy(clientSide = "forestry.apiculture.proxy.ClientProxyApiculture", serverSide = "forestry.apiculture.proxy.ProxyApiculture") + public static ProxyApiculture proxy; + private static final String CONFIG_CATEGORY = "apiculture"; + private Configuration apicultureConfig; + public static String beekeepingMode = "NORMAL"; + public static int beeCycleTicks = 550; + public static boolean apiarySideSensitive = false; + public static boolean fancyRenderedBees = false; + public static Trigger triggerNoFrames; + private ArrayList forestDrops; + private ArrayList meadowsDrops; + private ArrayList desertDrops; + private ArrayList jungleDrops; + private ArrayList endDrops; + private ArrayList snowDrops; + private ArrayList swampDrops; + private ArrayList swarmDrops; + /** + * See {@link IBeeRoot} for details + */ + public static IBeeRoot beeInterface; + public static MachineDefinition definitionApiary; + public static MachineDefinition definitionChest; + public static MachineDefinition definitionBeehouse; + + @Override + public boolean isAvailable() { + return !Config.disableApiculture; + } + + @SuppressWarnings("unchecked") + @Override + public void preInit() { + super.preInit(); + + MinecraftForge.EVENT_BUS.register(this); + + proxy.addLocalizations(); + + createHiveDropArrays(); + + ForestryBlock.apiculture = new BlockBase(Material.iron); + ForestryBlock.apiculture.setBlockName("for.apiculture").setCreativeTab(Tabs.tabApiculture); + Proxies.common.registerBlock(ForestryBlock.apiculture, ItemForestryBlock.class); + + definitionApiary = ForestryBlock.apiculture.addDefinition(new MachineDefinition(Defaults.DEFINITION_APIARY_META, "forestry.Apiary", TileApiary.class, + ShapedRecipeCustom.createShapedRecipe(new ItemStack(ForestryBlock.apiculture, 1, Defaults.DEFINITION_APIARY_META), new Object[] { "XXX", "#C#", "###", 'X', "slabWood", '#', + "plankWood", 'C', ForestryItem.impregnatedCasing })) + .setFaces(0, 1, 2, 2, 4, 4, 0, 7)); + + definitionChest = ForestryBlock.apiculture.addDefinition(new MachineDefinition(Defaults.DEFINITION_APIARISTCHEST_META, "forestry.ApiaristChest", TileApiaristChest.class, + ShapedRecipeCustom.createShapedRecipe(new ItemStack(ForestryBlock.apiculture, 1, Defaults.DEFINITION_APIARISTCHEST_META), new Object[] { " # ", "XYX", "XXX", '#', Blocks.glass, 'X', + "beeComb", 'Y', Blocks.chest })).setFaces(0, 1, 2, + 3, 4, 4)); + + definitionBeehouse = ForestryBlock.apiculture.addDefinition(new MachineDefinition(Defaults.DEFINITION_BEEHOUSE_META, "forestry.Beehouse", TileBeehouse.class, + ShapedRecipeCustom.createShapedRecipe(new ItemStack(ForestryBlock.apiculture, 1, Defaults.DEFINITION_BEEHOUSE_META), new Object[] { "XXX", "#C#", "###", 'X', "slabWood", '#', + "plankWood", 'C', "beeComb" })) + .setFaces(0, 1, 2, 2, 4, 4, 0, 7)); + + ForestryBlock.beehives = (new BlockBeehives()).setBlockName("beehives"); + Proxies.common.registerBlock(ForestryBlock.beehives, ItemForestryBlock.class); + ForestryBlock.beehives.setHarvestLevel("pickaxe", 1, 0); + ForestryBlock.beehives.setHarvestLevel("scoop", 0, 1); + ForestryBlock.beehives.setHarvestLevel("scoop", 0, 2); + ForestryBlock.beehives.setHarvestLevel("scoop", 0, 3); + ForestryBlock.beehives.setHarvestLevel("scoop", 0, 4); + ForestryBlock.beehives.setHarvestLevel("scoop", 0, 5); + ForestryBlock.beehives.setHarvestLevel("scoop", 0, 6); + ForestryBlock.beehives.setHarvestLevel("scoop", 0, 7); + ForestryBlock.beehives.setHarvestLevel("scoop", 0, 8); + + // Init bee interface + AlleleManager.alleleRegistry.registerSpeciesRoot(PluginApiculture.beeInterface = BeeManager.beeInterface = new BeeHelper()); + BeeManager.villageBees = new ArrayList[] { new ArrayList(), new ArrayList() }; + + // Candles + ForestryBlock.candle = new BlockCandle().setBlockName("candle"); + Proxies.common.registerBlock(ForestryBlock.candle, ItemCandleBlock.class); + ForestryBlock.stump = new BlockStump().setBlockName("stump"); + Proxies.common.registerBlock(ForestryBlock.stump, ItemForestryBlock.class); + + // Alveary and Components + ForestryBlock.alveary = new BlockAlveary().setBlockName("alveary"); + Proxies.common.registerBlock(ForestryBlock.alveary, ItemAlvearyBlock.class); + ForestryBlock.alveary.setHarvestLevel("axe", 0); + + // Add triggers + triggerNoFrames = new TriggerNoFrames(); + + // Create bee alleles + createAlleles(); + + // Register village components with the Structure registry. + VillageHandlerApiculture.registerVillageComponents(); + } + + @Override + public void doInit() { + super.doInit(); + + apicultureConfig = new Configuration(); + + Property property = apicultureConfig.get("apiary.sidesensitive", CONFIG_CATEGORY, apiarySideSensitive); + property.Comment = "set to false if apiaries should output all items regardless of side a pipe is attached to"; + apiarySideSensitive = Boolean.parseBoolean(property.Value); + + property = apicultureConfig.get("render.bees.fancy", CONFIG_CATEGORY, fancyRenderedBees); + property.Comment = "set to true to enable a fancy butterfly-like renderer for bees. (experimental!)"; + fancyRenderedBees = Boolean.parseBoolean(property.Value); + + property = apicultureConfig.get("beekeeping.mode", CONFIG_CATEGORY, "NORMAL"); + property.Comment = "change beekeeping modes here. possible values EASY, NORMAL, HARD, HARDCORE, INSANE. mods may add additional modes."; + beekeepingMode = property.Value.trim(); + Proxies.log.finer("Beekeeping mode read from config: " + beekeepingMode); + + property = apicultureConfig.get("beekeeping.flowers.custom", CONFIG_CATEGORY, ""); + property.Comment = "add additional flower blocks for apiaries here in the format id:meta. separate blocks using ';'. will be treated like vanilla flowers. not recommended for flowers implemented as tile entities."; + parseAdditionalFlowers(property.Value, FlowerManager.plainFlowers); + + property = apicultureConfig.get("species.blacklist", CONFIG_CATEGORY, ""); + property.Comment = "add species to blacklist identified by their uid and seperated with ';'."; + parseBeeBlacklist(property.Value); + + apicultureConfig.save(); + + createMutations(); + registerBeehiveDrops(); + + PluginApiculture.beeInterface.registerBeekeepingMode(BeekeepingMode.easy); + PluginApiculture.beeInterface.registerBeekeepingMode(BeekeepingMode.normal); + PluginApiculture.beeInterface.registerBeekeepingMode(BeekeepingMode.hard); + PluginApiculture.beeInterface.registerBeekeepingMode(BeekeepingMode.hardcore); + PluginApiculture.beeInterface.registerBeekeepingMode(BeekeepingMode.insane); + + // Inducers for swarmer + BeeManager.inducers.put(ForestryItem.royalJelly.getItemStack(), 10); + + registerTemplates(); + + definitionApiary.register(); + definitionBeehouse.register(); + definitionChest.register(); + GameRegistry.registerTileEntity(TileAlvearyPlain.class, "forestry.Alveary"); + GameRegistry.registerTileEntity(TileSwarm.class, "forestry.Swarm"); + GameRegistry.registerTileEntity(TileAlvearySwarmer.class, "forestry.AlvearySwarmer"); + GameRegistry.registerTileEntity(TileAlvearyHeater.class, "forestry.AlvearyHeater"); + GameRegistry.registerTileEntity(TileAlvearyFan.class, "forestry.AlvearyFan"); + GameRegistry.registerTileEntity(TileAlvearyHygroregulator.class, "forestry.AlvearyHygro"); + GameRegistry.registerTileEntity(TileAlvearyStabiliser.class, "forestry.AlvearyStabiliser"); + GameRegistry.registerTileEntity(TileAlvearySieve.class, "forestry.AlvearySieve"); + GameRegistry.registerTileEntity(TileCandle.class, "forestry.Candle"); + + BeeManager.villageBees[0].add(beeInterface.templateAsGenome(BeeTemplates.getForestTemplate())); + BeeManager.villageBees[0].add(beeInterface.templateAsGenome(BeeTemplates.getMeadowsTemplate())); + BeeManager.villageBees[0].add(beeInterface.templateAsGenome(BeeTemplates.getModestTemplate())); + BeeManager.villageBees[0].add(beeInterface.templateAsGenome(BeeTemplates.getMarshyTemplate())); + BeeManager.villageBees[0].add(beeInterface.templateAsGenome(BeeTemplates.getWintryTemplate())); + BeeManager.villageBees[0].add(beeInterface.templateAsGenome(BeeTemplates.getTropicalTemplate())); + + BeeManager.villageBees[1].add(beeInterface.templateAsGenome(BeeTemplates.getForestRainResistTemplate())); + BeeManager.villageBees[1].add(beeInterface.templateAsGenome(BeeTemplates.getCommonTemplate())); + BeeManager.villageBees[1].add(beeInterface.templateAsGenome(BeeTemplates.getValiantTemplate())); + + // Register villager stuff + VillageHandlerApiculture villageHandler = new VillageHandlerApiculture(); + VillagerRegistry.instance().registerVillageCreationHandler(villageHandler); + VillagerRegistry.instance().registerVillagerId(Defaults.ID_VILLAGER_BEEKEEPER); + Proxies.render.registerVillagerSkin(Defaults.ID_VILLAGER_BEEKEEPER, Defaults.TEXTURE_SKIN_BEEKPEEPER); + VillagerRegistry.instance().registerVillageTradeHandler(Defaults.ID_VILLAGER_BEEKEEPER, villageHandler); + + // Register world gen + if (Config.generateBeehives) + MinecraftForge.EVENT_BUS.register(HiveDecorator.instance()); + + proxy.initializeRendering(); + } + + @Override + public void postInit() { + super.postInit(); + registerDungeonLoot(); + + } + + @Override + public IGuiHandler getGuiHandler() { + return new GuiHandlerApiculture(); + } + + @Override + public IPacketHandler getPacketHandler() { + return new PacketHandlerApiculture(); + } + + @Override + protected void registerItems() { + + // / BEES + ForestryItem.beeQueenGE.registerItem((new ItemBeeGE(EnumBeeType.QUEEN)), "beeQueenGE"); + ForestryItem.beeDroneGE.registerItem((new ItemBeeGE(EnumBeeType.DRONE)), "beeDroneGE"); + ForestryItem.beePrincessGE.registerItem((new ItemBeeGE(EnumBeeType.PRINCESS)), "beePrincessGE"); + ForestryItem.beeLarvaeGE.registerItem((new ItemBeeGE(EnumBeeType.LARVAE)), "beeLarvaeGE"); + + ForestryItem.beealyzer.registerItem((new ItemBeealyzer()), "beealyzer"); + // Disabling Habitat Locator, because it's b0rked and seems to flubber up other icons. + /*ForestryItem.biomeFinder = new ItemBiomefinder(Config.getOrCreateItemIdProperty("biomeFinder", Defaults.ID_ITEM_BIOME_FINDER)) + .setUnlocalizedName("biomeFinder");*/ + ForestryItem.imprinter.registerItem((new ItemImprinter()), "imprinter"); + + // / COMB FRAMES + ForestryItem.frameUntreated.registerItem(new ItemHiveFrame(80, 0.9f), "frameUntreated"); + ForestryItem.frameImpregnated.registerItem(new ItemHiveFrame(240, 0.4f), "frameImpregnated"); + ForestryItem.frameProven.registerItem(new ItemHiveFrame(720, 0.3f), "frameProven"); + + // / BEE RESOURCES + ForestryItem.honeyDrop.registerItem(new ItemOverlay(Tabs.tabApiculture, + new OverlayInfo("honey", 0xecb42d, 0xe8c814), new OverlayInfo("charged", 0x800505, 0x9c0707).setIsSecret(), + new OverlayInfo("omega", 0x191919, 0x4a8ca7).setIsSecret()), "honeyDrop"); + OreDictionary.registerOre("dropHoney", ForestryItem.honeyDrop.getItemStack()); + + ForestryItem.pollen.registerItem(new ItemOverlay(Tabs.tabApiculture, + new OverlayInfo("normal", 0xa28a25, 0xa28a25), + new OverlayInfo("crystalline", 0xffffff, 0xc5feff)), + "pollen"); + OreDictionary.registerOre("itemPollen", ForestryItem.pollen.getItemStack()); + + ForestryItem.propolis.registerItem(new ItemOverlay(Tabs.tabApiculture, + new OverlayInfo("normal", 0xc5b24e), new OverlayInfo("sticky", 0xc68e57), new OverlayInfo("pulsating", 0x2ccdb1).setIsSecret(), + new OverlayInfo("silky", 0xddff00)), + "propolis"); + + ForestryItem.honeydew.registerItem(new ItemForestry().setCreativeTab(Tabs.tabApiculture), "honeydew"); + OreDictionary.registerOre("dropHoneydew", ForestryItem.honeydew.getItemStack()); + + ForestryItem.royalJelly.registerItem(new ItemForestry().setCreativeTab(Tabs.tabApiculture), "royalJelly"); + OreDictionary.registerOre("dropRoyalJelly", ForestryItem.royalJelly.getItemStack()); + + ForestryItem.waxCast.registerItem(new ItemWaxCast().setCreativeTab(Tabs.tabApiculture), "waxCast"); + + // / BEE COMBS + ForestryItem.beeComb.registerItem(new ItemHoneycomb(), "beeCombs"); + OreDictionary.registerOre("beeComb", ForestryItem.beeComb.getItemStack(1, Defaults.WILDCARD)); + + // / APIARIST'S CLOTHES + ForestryItem.apiaristHat.registerItem(new ItemArmorApiarist(0), "apiaristHelmet"); + ForestryItem.apiaristChest.registerItem(new ItemArmorApiarist(1), "apiaristChest"); + ForestryItem.apiaristLegs.registerItem(new ItemArmorApiarist(2), "apiaristLegs"); + ForestryItem.apiaristBoots.registerItem(new ItemArmorApiarist(3), "apiaristBoots"); + + } + + @Override + protected void registerBackpackItems() { + } + + @Override + protected void registerCrates() { + ForestryItem.cratedBeeswax.registerItem(new ItemCrated(ForestryItem.beeswax.getItemStack()), "cratedBeeswax"); + ForestryItem.cratedPollen.registerItem(new ItemCrated(ForestryItem.pollen.getItemStack()), "cratedPollen"); + ForestryItem.cratedPropolis.registerItem(new ItemCrated(ForestryItem.propolis.getItemStack()), "cratedPropolis"); + ForestryItem.cratedHoneydew.registerItem(new ItemCrated(ForestryItem.honeydew.getItemStack()), "cratedHoneydew"); + ForestryItem.cratedRoyalJelly.registerItem(new ItemCrated(ForestryItem.royalJelly.getItemStack()), "cratedRoyalJelly"); + + ForestryItem.cratedHoneycombs.registerItem(new ItemCrated(ForestryItem.beeComb.getItemStack(1, 0)), "cratedHoneycombs"); + ForestryItem.cratedCocoaComb.registerItem(new ItemCrated(ForestryItem.beeComb.getItemStack(1, 1)), "cratedCocoaComb"); + ForestryItem.cratedSimmeringCombs.registerItem(new ItemCrated(ForestryItem.beeComb.getItemStack(1, 2)), "cratedSimmeringCombs"); + ForestryItem.cratedStringyCombs.registerItem(new ItemCrated(ForestryItem.beeComb.getItemStack(1, 3)), "cratedStringyCombs"); + ForestryItem.cratedFrozenCombs.registerItem(new ItemCrated(ForestryItem.beeComb.getItemStack(1, 4)), "cratedFrozenCombs"); + ForestryItem.cratedDrippingCombs.registerItem(new ItemCrated(ForestryItem.beeComb.getItemStack(1, 5)), "cratedDrippingCombs"); + + ForestryItem.cratedRefractoryWax.registerItem(new ItemCrated(ForestryItem.refractoryWax.getItemStack()), "cratedRefractoryWax"); + + } + + @Override + protected void registerRecipes() { + + // / APIARIST'S ARMOR + Proxies.common.addRecipe(ForestryItem.apiaristHat.getItemStack(), new Object[] { "###", "# #", '#', + ForestryItem.craftingMaterial.getItemStack(1, 3) }); + Proxies.common.addRecipe(ForestryItem.apiaristChest.getItemStack(), new Object[] { "# #", "###", "###", '#', + ForestryItem.craftingMaterial.getItemStack(1, 3) }); + Proxies.common.addRecipe(ForestryItem.apiaristLegs.getItemStack(), new Object[] { "###", "# #", "# #", '#', + ForestryItem.craftingMaterial.getItemStack(1, 3) }); + Proxies.common.addRecipe(ForestryItem.apiaristBoots.getItemStack(), new Object[] { "# #", "# #", '#', + ForestryItem.craftingMaterial.getItemStack(1, 3) }); + + // / HABITAT LOCATOR + //Proxies.common.addRecipe(ForestryItem.biomeFinder.getItemStack(), + // new Object[] { " X ", "X#X", " X ", '#', Items.redstone, 'X', "ingotBronze" }); + + Proxies.common.addRecipe(ForestryItem.vialCatalyst.getItemStack(3), + "###", "YXY", + '#', ForestryItem.waxCapsule, + 'X', Items.bone, + 'Y', ForestryItem.pollen); + Proxies.common.addRecipe(ForestryItem.vialCatalyst.getItemStack(3), + "###", "YXY", + '#', ForestryItem.canEmpty, + 'X', Items.bone, + 'Y', ForestryItem.pollen); + Proxies.common.addRecipe(ForestryItem.vialCatalyst.getItemStack(), + "###", "YXY", "###", + '#', ForestryItem.honeyDrop, + 'Y', ForestryItem.fertilizerCompound, + 'X', ForestryItem.waxCapsule); + Proxies.common.addRecipe(ForestryItem.vialCatalyst.getItemStack(), + "###", "YXY", "###", + '#', ForestryItem.honeyDrop, + 'Y', ForestryItem.fertilizerCompound, + 'X', ForestryItem.canEmpty); + Proxies.common.addRecipe(ForestryItem.vialCatalyst.getItemStack(), + "###", "YXY", "###", + '#', ForestryItem.honeyDrop, + 'Y', ForestryItem.pollen, + 'X', ForestryItem.waxCapsule); + Proxies.common.addRecipe(ForestryItem.vialCatalyst.getItemStack(), + "###", "YXY", "###", + '#', ForestryItem.honeyDrop, + 'Y', ForestryItem.pollen, + 'X', ForestryItem.canEmpty); + + // Bees + Proxies.common.addRecipe(ForestryItem.scoop.getItemStack(1), + "#X#", "###", " # ", + '#', "stickWood", + 'X', Blocks.wool); + Proxies.common.addRecipe(new ItemStack(Items.slime_ball), + "#X#", "#X#", "#X#", + '#', ForestryItem.propolis, + 'X', ForestryItem.pollen); + Proxies.common.addRecipe(new ItemStack(Items.speckled_melon), + "#X#", "#Y#", "#X#", + '#', ForestryItem.honeyDrop, + 'X', ForestryItem.honeydew, + 'Y', Items.melon); + Proxies.common.addRecipe(ForestryItem.frameUntreated.getItemStack(), + "###", "#S#", "###", + '#', "stickWood", + 'S', Items.string); + Proxies.common.addRecipe(ForestryItem.frameImpregnated.getItemStack(), + "###", "#S#", "###", + '#', ForestryItem.stickImpregnated, + 'S', Items.string); + + // FOOD STUFF + if (ForestryItem.honeyedSlice != null) + Proxies.common.addRecipe(ForestryItem.honeyedSlice.getItemStack(4), + "###", "#X#", "###", + '#', ForestryItem.honeyDrop, + 'X', Items.bread); + if (ForestryItem.honeyPot != null) + Proxies.common.addRecipe(ForestryItem.honeyPot.getItemStack(1), + "# #", " X ", "# #", + '#', ForestryItem.honeyDrop, + 'X', ForestryItem.waxCapsule); + if (ForestryItem.ambrosia != null) + Proxies.common.addRecipe(ForestryItem.ambrosia.getItemStack(), + "#Y#", "XXX", "###", + '#', ForestryItem.honeydew, + 'X', ForestryItem.royalJelly, + 'Y', ForestryItem.waxCapsule); + + // / CAPSULES + Proxies.common.addRecipe(GameMode.getGameMode().getStackSetting("recipe.output.capsule"), "###", '#', ForestryItem.beeswax); + Proxies.common.addRecipe(GameMode.getGameMode().getStackSetting("recipe.output.refractory"), "###", '#', ForestryItem.refractoryWax); + + // / BITUMINOUS PEAT + Proxies.common.addRecipe(ForestryItem.bituminousPeat.getItemStack(), + new Object[] { " # ", "XYX", " # ", '#', "dustAsh", 'X', ForestryItem.peat, 'Y', + ForestryItem.propolis }); + // / TORCHES + Proxies.common.addRecipe(new ItemStack(Blocks.torch, 3), + new Object[] { " # ", " # ", " Y ", '#', ForestryItem.beeswax, 'Y', "stickWood" }); + Proxies.common.addRecipe(ForestryItem.craftingMaterial.getItemStack(1, 1), new Object[] { "# #", " # ", "# #", '#', + ForestryItem.propolis.getItemStack(1, 2) }); + + // / CANDLES + RecipeManagers.carpenterManager.addRecipe(30, LiquidHelper.getLiquid(Defaults.LIQUID_WATER, 600), null, new ItemStack(ForestryBlock.candle, 24), new Object[] { + " X ", "###", "###", '#', ForestryItem.beeswax, 'X', Items.string }); + RecipeManagers.carpenterManager.addRecipe(10, LiquidHelper.getLiquid(Defaults.LIQUID_WATER, 200), null, new ItemStack(ForestryBlock.candle, 6), new Object[] { + "#X#", '#', ForestryItem.beeswax, 'X', ForestryItem.craftingMaterial.getItemStack(1, 2) }); + Proxies.common.addShapelessRecipe(new ItemStack(ForestryBlock.candle), new ItemStack(ForestryBlock.candle)); + Proxies.common.addShapelessRecipe(new ItemStack(ForestryBlock.candle, 1, 1), new ItemStack(ForestryBlock.candle, 1, 1)); + + // / WAX CAST + Proxies.common.addRecipe(ForestryItem.waxCast.getItemStack(), + "###", "# #", "###", + '#', ForestryItem.beeswax); + + // / ALVEARY + Proxies.common.addRecipe(new ItemStack(ForestryBlock.alveary), + "###", "#X#", "###", + 'X', ForestryItem.impregnatedCasing, + '#', ForestryItem.craftingMaterial.getItemStack(1, 6)); + // SWARMER + Proxies.common.addRecipe(new ItemStack(ForestryBlock.alveary, 1, 2), + "#G#", " X ", "#G#", + '#', ForestryItem.tubes.getItemStack(1, 5), + 'X', ForestryBlock.alveary, + 'G', Items.gold_ingot); + // FAN + Proxies.common.addRecipe(new ItemStack(ForestryBlock.alveary, 1, 3), + "I I", " X ", "I#I", + '#', ForestryItem.tubes.getItemStack(1, 4), + 'X', ForestryBlock.alveary, + 'I', Items.iron_ingot); + // HEATER + Proxies.common.addRecipe(new ItemStack(ForestryBlock.alveary, 1, 4), + "#I#", " X ", "YYY", + '#', ForestryItem.tubes.getItemStack(1, 4), + 'X', ForestryBlock.alveary, + 'I', Items.iron_ingot, 'Y', Blocks.stone); + // HYGROREGULATOR + Proxies.common.addRecipe(new ItemStack(ForestryBlock.alveary, 1, 5), + "GIG", "GXG", "GIG", + 'X', ForestryBlock.alveary, + 'I', Items.iron_ingot, + 'G', Blocks.glass); + // STABILISER + Proxies.common.addRecipe(new ItemStack(ForestryBlock.alveary, 1, 6), + "G G", "GXG", "G G", + 'X', ForestryBlock.alveary, + 'G', Items.quartz); + // SIEVE + Proxies.common.addRecipe(new ItemStack(ForestryBlock.alveary, 1, TileAlvearySieve.BLOCK_META), + "III", " X ", "WWW", + 'X', ForestryBlock.alveary, + 'I', Items.iron_ingot, + 'W', ForestryItem.craftingMaterial.getItemStack(1, 3)); + + // / SQUEEZER + RecipeManagers.squeezerManager.addRecipe(10, new ItemStack[] { ForestryItem.honeyDrop.getItemStack() }, LiquidHelper.getLiquid(Defaults.LIQUID_HONEY, 100), + ForestryItem.propolis.getItemStack(), 5); + RecipeManagers.squeezerManager.addRecipe(10, new ItemStack[] { ForestryItem.honeydew.getItemStack() }, LiquidHelper.getLiquid(Defaults.LIQUID_HONEY, 100)); + RecipeManagers.squeezerManager.addRecipe(10, new ItemStack[] { ForestryItem.phosphor.getItemStack(2), new ItemStack(Blocks.sand) }, LiquidHelper.getLiquid(Defaults.LIQUID_LAVA, 2000)); + RecipeManagers.squeezerManager.addRecipe(10, new ItemStack[] { ForestryItem.phosphor.getItemStack(2), new ItemStack(Blocks.dirt) }, LiquidHelper.getLiquid(Defaults.LIQUID_LAVA, 1600)); + + // / CARPENTER + RecipeManagers.carpenterManager.addRecipe(100, LiquidHelper.getLiquid(Defaults.LIQUID_WATER, 2000), null, ForestryItem.beealyzer.getItemStack(), + new Object[] { "X#X", "X#X", "RDR", '#', Blocks.glass_pane, 'X', "ingotTin", 'R', + Items.redstone, 'D', Items.diamond }); + RecipeManagers.carpenterManager.addRecipe( + 50, + LiquidHelper.getLiquid(Defaults.LIQUID_HONEY, 500), + null, + ForestryItem.craftingMaterial.getItemStack(1, 6), + new Object[] { " J ", "###", "WPW", '#', "plankWood", 'J', ForestryItem.royalJelly, + 'W', ForestryItem.beeswax, 'P', ForestryItem.pollen }); + + // / CENTRIFUGE + // Honey combs + RecipeManagers.centrifugeManager.addRecipe(20, ForestryItem.beeComb.getItemStack(1, 0), ForestryItem.beeswax.getItemStack(), ForestryItem.honeyDrop.getItemStack(), 90); + // Cocoa combs + RecipeManagers.centrifugeManager.addRecipe(20, ForestryItem.beeComb.getItemStack(1, 1), ForestryItem.beeswax.getItemStack(), new ItemStack(Items.dye, 1, 3), 50); + // Simmering combs + RecipeManagers.centrifugeManager.addRecipe(20, ForestryItem.beeComb.getItemStack(1, 2), ForestryItem.refractoryWax.getItemStack(), ForestryItem.phosphor.getItemStack(2), 70); + // Stringy combs + RecipeManagers.centrifugeManager.addRecipe(20, ForestryItem.beeComb.getItemStack(1, 3), ForestryItem.propolis.getItemStack(), ForestryItem.honeyDrop.getItemStack(), 40); + // Drippig combs + RecipeManagers.centrifugeManager.addRecipe(20, ForestryItem.beeComb.getItemStack(1, 5), ForestryItem.honeydew.getItemStack(), ForestryItem.honeyDrop.getItemStack(), 40); + // Frozen combs + RecipeManagers.centrifugeManager.addRecipe(20, ForestryItem.beeComb.getItemStack(1, 4), new ItemStack[] { ForestryItem.beeswax.getItemStack(), + ForestryItem.honeyDrop.getItemStack(), new ItemStack(Items.snowball), ForestryItem.pollen.getItemStack(1, 1) }, new int[] { 80, 70, 40, 20 }); + // Silky combs + RecipeManagers.centrifugeManager.addRecipe(20, ForestryItem.beeComb.getItemStack(1, 6), ForestryItem.honeyDrop.getItemStack(), ForestryItem.propolis.getItemStack(1, 3), 80); + // Parched combs + RecipeManagers.centrifugeManager.addRecipe(20, ForestryItem.beeComb.getItemStack(1, 7), ForestryItem.beeswax.getItemStack(), ForestryItem.honeyDrop.getItemStack(), 90); + // Mysterious combs + RecipeManagers.centrifugeManager.addRecipe(20, ForestryItem.beeComb.getItemStack(1, 8), new ItemStack[] { ForestryItem.honeyDrop.getItemStack(), + ForestryItem.propolis.getItemStack(1, 2) }, new int[] { 40, 100 }); + // Irradiated combs + RecipeManagers.centrifugeManager.addRecipe(20, ForestryItem.beeComb.getItemStack(1, 9), new ItemStack[] {}, new int[] {}); + // Powdery combs + RecipeManagers.centrifugeManager.addRecipe(20, ForestryItem.beeComb.getItemStack(1, 10), new ItemStack[] { ForestryItem.honeyDrop.getItemStack(), + ForestryItem.beeswax.getItemStack(), new ItemStack(Items.gunpowder) }, new int[] { 20, 20, 90 }); + // Reddened Combs + RecipeManagers.centrifugeManager.addRecipe(80, ForestryItem.beeComb.getItemStack(1, 11), + new ItemStack[] { ForestryItem.honeyDrop.getItemStack(2, 1) }, new int[] { 100 }); + // Darkened Combs + RecipeManagers.centrifugeManager.addRecipe(80, ForestryItem.beeComb.getItemStack(1, 12), + new ItemStack[] { ForestryItem.honeyDrop.getItemStack(1, 1) }, new int[] { 100 }); + // Omega Combs + RecipeManagers.centrifugeManager.addRecipe(400, ForestryItem.beeComb.getItemStack(1, 13), new ItemStack[] { ForestryItem.honeyDrop.getItemStack(1, 2) }, new int[] { 100 }); + // Wheaten Combs + RecipeManagers.centrifugeManager.addRecipe(20, ForestryItem.beeComb.getItemStack(1, 14), new ItemStack[] { ForestryItem.honeyDrop.getItemStack(), + ForestryItem.beeswax.getItemStack(), new ItemStack(Items.wheat) }, new int[] { 20, 20, 80 }); + // Mossy Combs + RecipeManagers.centrifugeManager.addRecipe(20, ForestryItem.beeComb.getItemStack(1, 15), ForestryItem.beeswax.getItemStack(), ForestryItem.honeyDrop.getItemStack(), 90); + // Mellow Combs + RecipeManagers.centrifugeManager.addRecipe(20, ForestryItem.beeComb.getItemStack(1, 16), new ItemStack[] { ForestryItem.honeydew.getItemStack(), + ForestryItem.beeswax.getItemStack(), new ItemStack(Items.quartz) }, new int[] { 60, 20, 30 }); + + // Silk + RecipeManagers.centrifugeManager.addRecipe(5, ForestryItem.propolis.getItemStack(1, 3), new ItemStack[] { + ForestryItem.craftingMaterial.getItemStack(1, 2), ForestryItem.propolis.getItemStack() }, new int[] { 60, 10 }); + + // / FERMENTER + RecipeManagers.fermenterManager.addRecipe(ForestryItem.honeydew.getItemStack(), 500, 1.0f, LiquidHelper.getLiquid(Defaults.LIQUID_MEAD, 1), + LiquidHelper.getLiquid(Defaults.LIQUID_HONEY, 1)); + + } + + private void registerBeehiveDrops() { + forestDrops.add(new HiveDrop(BeeTemplates.getForestTemplate(), new ItemStack[] { ForestryItem.beeComb.getItemStack(1, 0) }, 80).setIgnobleShare(0.7f)); + forestDrops.add(new HiveDrop(BeeTemplates.getForestRainResistTemplate(), new ItemStack[] { ForestryItem.beeComb.getItemStack(1, 0) }, 8)); + forestDrops.add(new HiveDrop(BeeTemplates.getValiantTemplate(), new ItemStack[] { ForestryItem.beeComb.getItemStack(1, 0) }, 3)); + + meadowsDrops.add(new HiveDrop(BeeTemplates.getMeadowsTemplate(), new ItemStack[] { ForestryItem.beeComb.getItemStack(1, 0) }, 80).setIgnobleShare(0.7f)); + meadowsDrops.add(new HiveDrop(BeeTemplates.getValiantTemplate(), new ItemStack[] { ForestryItem.beeComb.getItemStack(1, 0) }, 3)); + + desertDrops.add(new HiveDrop(BeeTemplates.getModestTemplate(), new ItemStack[] { ForestryItem.beeComb.getItemStack(1, 7) }, 80).setIgnobleShare(0.7f)); + desertDrops.add(new HiveDrop(BeeTemplates.getValiantTemplate(), new ItemStack[] { ForestryItem.beeComb.getItemStack(1, 7) }, 3)); + + jungleDrops.add(new HiveDrop(BeeTemplates.getTropicalTemplate(), new ItemStack[] { ForestryItem.beeComb.getItemStack(1, 6) }, 80).setIgnobleShare(0.7f)); + jungleDrops.add(new HiveDrop(BeeTemplates.getValiantTemplate(), new ItemStack[] { ForestryItem.beeComb.getItemStack(1, 6) }, 3)); + + endDrops.add(new HiveDrop(BeeTemplates.getEnderTemplate(), new ItemStack[] { ForestryItem.beeComb.getItemStack(1, 8) }, 90)); + + snowDrops.add(new HiveDrop(BeeTemplates.getWintryTemplate(), new ItemStack[] { ForestryItem.beeComb.getItemStack(1, 4) }, 80).setIgnobleShare(0.5f)); + snowDrops.add(new HiveDrop(BeeTemplates.getValiantTemplate(), new ItemStack[] { ForestryItem.beeComb.getItemStack(1, 4) }, 3)); + + swampDrops.add(new HiveDrop(BeeTemplates.getMarshyTemplate(), new ItemStack[] { ForestryItem.beeComb.getItemStack(1, 15) }, 80).setIgnobleShare(0.4f)); + swampDrops.add(new HiveDrop(BeeTemplates.getValiantTemplate(), new ItemStack[] { ForestryItem.beeComb.getItemStack(1, 15) }, 3)); + } + + private void registerDungeonLoot() { + int rarity; + if (Config.dungeonLootRare) + rarity = 5; + else + rarity = 10; + + ChestGenHooks.addItem(ChestGenHooks.DUNGEON_CHEST, new WeightedRandomChestContent(getBeeItemFromTemplate(BeeTemplates.getSteadfastTemplate(), EnumBeeType.DRONE), 1, 1, rarity)); + + ItemStack stack = new ItemStack(ForestryBlock.candle); + NBTTagCompound tag = new NBTTagCompound(); + tag.setInteger(BlockCandle.colourTagName, 0xffffff); + stack.setTagCompound(tag); + + ChestGenHooks.addItem(Defaults.CHEST_GEN_HOOK_NATURALIST_CHEST, new WeightedRandomChestContent(stack, 7, 12, 12)); + ChestGenHooks.addItem(Defaults.CHEST_GEN_HOOK_NATURALIST_CHEST, new WeightedRandomChestContent(ForestryItem.scoop.getItemStack(), 1, 1, 8)); + ChestGenHooks.addItem(Defaults.CHEST_GEN_HOOK_NATURALIST_CHEST, new WeightedRandomChestContent(ForestryItem.propolis.getItemStack(), 2, 4, 6)); + ChestGenHooks.addItem(Defaults.CHEST_GEN_HOOK_NATURALIST_CHEST, new WeightedRandomChestContent(ForestryItem.beeComb.getItemStack(), 4, 12, 7)); + ChestGenHooks.addItem(Defaults.CHEST_GEN_HOOK_NATURALIST_CHEST, new WeightedRandomChestContent(ForestryItem.beeComb.getItemStack(1, 4), 2, 10, 7)); + ChestGenHooks.addItem(Defaults.CHEST_GEN_HOOK_NATURALIST_CHEST, new WeightedRandomChestContent(ForestryItem.beeComb.getItemStack(1, 6), 1, 6, 7)); + + ChestGenHooks.addItem(Defaults.CHEST_GEN_HOOK_NATURALIST_CHEST, new WeightedRandomChestContent(getBeeItemFromTemplate(BeeTemplates.getForestRainResistTemplate(), EnumBeeType.PRINCESS), 1, 1, 5)); + ChestGenHooks.addItem(Defaults.CHEST_GEN_HOOK_NATURALIST_CHEST, new WeightedRandomChestContent(getBeeItemFromTemplate(BeeTemplates.getCommonTemplate(), EnumBeeType.DRONE), 1, 2, 8)); + ChestGenHooks.addItem(Defaults.CHEST_GEN_HOOK_NATURALIST_CHEST, new WeightedRandomChestContent(getBeeItemFromTemplate(BeeTemplates.getMeadowsTemplate(), EnumBeeType.PRINCESS), 1, 1, 5)); + } + + private ItemStack getBeeItemFromTemplate(IAllele[] template, EnumBeeType beeType) { + IBee bee = new Bee(PluginApiculture.beeInterface.templateAsGenome(template)); + ItemStack beeItem; + switch (beeType) { + default: + case DRONE: + beeItem = ForestryItem.beeDroneGE.getItemStack(); + break; + case PRINCESS: + beeItem = ForestryItem.beePrincessGE.getItemStack(); + break; + } + NBTTagCompound nbtTagCompound = new NBTTagCompound(); + bee.writeToNBT(nbtTagCompound); + beeItem.setTagCompound(nbtTagCompound); + + return beeItem; + } + + @SuppressWarnings("unchecked") + private void createHiveDropArrays() { + + BeeManager.hiveDrops = new ArrayList[8]; + + forestDrops = new ArrayList(); + BeeManager.hiveDrops[0] = forestDrops; + + meadowsDrops = new ArrayList(); + BeeManager.hiveDrops[1] = meadowsDrops; + + desertDrops = new ArrayList(); + BeeManager.hiveDrops[2] = desertDrops; + + jungleDrops = new ArrayList(); + BeeManager.hiveDrops[3] = jungleDrops; + + endDrops = new ArrayList(); + BeeManager.hiveDrops[4] = endDrops; + + snowDrops = new ArrayList(); + BeeManager.hiveDrops[5] = snowDrops; + + swampDrops = new ArrayList(); + BeeManager.hiveDrops[6] = swampDrops; + + swarmDrops = new ArrayList(); + BeeManager.hiveDrops[7] = swarmDrops; + } + + private void createAlleles() { + + IClassification hymnoptera = AlleleManager.alleleRegistry.createAndRegisterClassification(EnumClassLevel.ORDER, "hymnoptera", "Hymnoptera"); + AlleleManager.alleleRegistry.getClassification("class.insecta").addMemberGroup(hymnoptera); + + IClassification apidae = AlleleManager.alleleRegistry.createAndRegisterClassification(EnumClassLevel.FAMILY, "apidae", "Apidae"); + hymnoptera.addMemberGroup(apidae); + + IClassification honey = new BranchBees("honey", "Apis"); + apidae.addMemberGroup(honey); + IClassification noble = new BranchBees("noble", "Probapis"); + apidae.addMemberGroup(noble); + IClassification industrious = new BranchBees("industrious", "Industrapis"); + apidae.addMemberGroup(industrious); + IClassification heroic = new BranchBees("heroic", "Herapis"); + apidae.addMemberGroup(heroic); + IClassification infernal = new BranchBees("infernal", "Diapis"); + apidae.addMemberGroup(infernal); + IClassification austere = new BranchBees("austere", "Modapis"); + apidae.addMemberGroup(austere); + IClassification end = new BranchBees("end", "Finapis"); + apidae.addMemberGroup(end); + IClassification vengeful = new BranchBees("vengeful", "Punapis"); + apidae.addMemberGroup(vengeful); + IClassification tropical = new BranchBees("tropical", "Caldapis"); + apidae.addMemberGroup(tropical); + IClassification frozen = new BranchBees("frozen", "Coagapis"); + apidae.addMemberGroup(frozen); + IClassification reddened = new BranchBees("reddened", "Rubapis"); + apidae.addMemberGroup(reddened); + IClassification festive = new BranchBees("festive", "Festapis"); + apidae.addMemberGroup(festive); + IClassification agrarian = new BranchBees("agrarian", "Rustapis"); + apidae.addMemberGroup(agrarian); + IClassification boggy = new BranchBees("boggy", "Paludapis"); + apidae.addMemberGroup(boggy); + IClassification monastic = new BranchBees("monastic", "Monapis"); + apidae.addMemberGroup(monastic); + + // / BEES // SPECIES + // Common Branch + Allele.speciesForest = new AlleleBeeSpecies("speciesForest", true, "bees.species.forest", honey, "nigrocincta", 0x19d0ec, 0xffdc16).addProduct( + ForestryItem.beeComb.getItemStack(1, 0), 30); + Allele.speciesMeadows = new AlleleBeeSpecies("speciesMeadows", true, "bees.species.meadows", honey, "florea", 0xef131e, 0xffdc16).addProduct( + ForestryItem.beeComb.getItemStack(1, 0), 30); + Allele.speciesCommon = new AlleleBeeSpecies("speciesCommon", true, "bees.species.common", honey, "cerana", 0xb2b2b2, 0xffdc16).addProduct( + ForestryItem.beeComb.getItemStack(1, 0), 35).setIsSecret(); + Allele.speciesCultivated = new AlleleBeeSpecies("speciesCultivated", true, "bees.species.cultivated", honey, "mellifera", 0x5734ec, 0xffdc16) + .addProduct(ForestryItem.beeComb.getItemStack(1, 0), 40).setIsSecret(); + + // Noble Branch + Allele.speciesNoble = new AlleleBeeSpecies("speciesNoble", false, "bees.species.noble", noble, "nobilis", 0xec9a19, 0xffdc16).addProduct( + ForestryItem.beeComb.getItemStack(1, 5), 20).setIsSecret(); + Allele.speciesMajestic = new AlleleBeeSpecies("speciesMajestic", true, "bees.species.majestic", noble, "regalis", 0x7f0000, 0xffdc16).addProduct( + ForestryItem.beeComb.getItemStack(1, 5), 30).setIsSecret(); + Allele.speciesImperial = new AlleleBeeSpecies("speciesImperial", false, "bees.species.imperial", noble, "imperatorius", 0xa3e02f, 0xffdc16) + .addProduct(ForestryItem.beeComb.getItemStack(1, 5), 20).addProduct(ForestryItem.royalJelly.getItemStack(), 15).setHasEffect().setIsSecret(); + + // Industrious Branch + Allele.speciesDiligent = new AlleleBeeSpecies("speciesDiligent", false, "bees.species.diligent", industrious, "sedulus", 0xc219ec, 0xffdc16) + .addProduct(ForestryItem.beeComb.getItemStack(1, 3), 20).setIsSecret(); + Allele.speciesUnweary = new AlleleBeeSpecies("speciesUnweary", true, "bees.species.unweary", industrious, "assiduus", 0x19ec5a, 0xffdc16).addProduct( + ForestryItem.beeComb.getItemStack(1, 3), 30).setIsSecret(); + Allele.speciesIndustrious = new AlleleBeeSpecies("speciesIndustrious", false, "bees.species.industrious", industrious, "industria", 0xffffff, 0xffdc16) + .addProduct(ForestryItem.beeComb.getItemStack(1, 3), 20).addProduct(ForestryItem.pollen.getItemStack(), 15).setHasEffect().setIsSecret(); + + // Heroic Branch + Allele.speciesSteadfast = new AlleleBeeSpecies("speciesSteadfast", false, "bees.species.steadfast", heroic, "legio", 0x4d2b15, 0xffdc16) + .addProduct(ForestryItem.beeComb.getItemStack(1, 1), 20).setIsSecret().setHasEffect(); + Allele.speciesValiant = new AlleleBeeSpecies("speciesValiant", true, "bees.species.valiant", heroic, "centurio", 0x626bdd, 0xffdc16) + .addProduct(ForestryItem.beeComb.getItemStack(1, 1), 30).addSpecialty(new ItemStack(Items.sugar), 15).setIsSecret(); + Allele.speciesHeroic = new AlleleBeeSpecies("speciesHeroic", false, "bees.species.heroic", heroic, "kraphti", 0xb3d5e4, 0xffdc16) + .addProduct(ForestryItem.beeComb.getItemStack(1, 1), 40).setIsSecret().setHasEffect(); + + // Infernal Branch + Allele.speciesSinister = new AlleleBeeSpecies("speciesSinister", false, "bees.species.sinister", infernal, "caecus", 0xb3d5e4, 0x9a2323) + .addProduct(ForestryItem.beeComb.getItemStack(1, 2), 45).setEntityTexture("sinisterBee").setIsSecret().setTemperature(EnumTemperature.HELLISH).setHumidity(EnumHumidity.ARID); + Allele.speciesFiendish = new AlleleBeeSpecies("speciesFiendish", true, "bees.species.fiendish", infernal, "diabolus", 0xd7bee5, 0x9a2323) + .addProduct(ForestryItem.beeComb.getItemStack(1, 2), 55).addProduct(ForestryItem.ash.getItemStack(), 15).setEntityTexture("sinisterBee").setIsSecret() + .setTemperature(EnumTemperature.HELLISH).setHumidity(EnumHumidity.ARID); + Allele.speciesDemonic = new AlleleBeeSpecies("speciesDemonic", false, "bees.species.demonic", infernal, "draco", 0xf4e400, 0x9a2323) + .addProduct(ForestryItem.beeComb.getItemStack(1, 2), 45).addProduct(new ItemStack(Items.glowstone_dust), 15).setEntityTexture("sinisterBee").setHasEffect().setIsSecret() + .setTemperature(EnumTemperature.HELLISH).setHumidity(EnumHumidity.ARID); + + // Austere Branch + Allele.speciesModest = new AlleleBeeSpecies("speciesModest", false, "bees.species.modest", austere, "modicus", 0xc5be86, 0xffdc16) + .addProduct(ForestryItem.beeComb.getItemStack(1, 7), 20).setTemperature(EnumTemperature.HOT).setHumidity(EnumHumidity.ARID); + Allele.speciesFrugal = new AlleleBeeSpecies("speciesFrugal", true, "bees.species.frugal", austere, "permodestus", 0xe8dcb1, 0xffdc16) + .addProduct(ForestryItem.beeComb.getItemStack(1, 7), 30).setIsSecret().setTemperature(EnumTemperature.HOT).setHumidity(EnumHumidity.ARID); + Allele.speciesAustere = new AlleleBeeSpecies("speciesAustere", false, "bees.species.austere", austere, "correpere", 0xfffac2, 0xffdc16) + .addProduct(ForestryItem.beeComb.getItemStack(1, 7), 20).addSpecialty(ForestryItem.beeComb.getItemStack(1, 10), 50).setHasEffect() + .setIsSecret().setTemperature(EnumTemperature.HOT).setHumidity(EnumHumidity.ARID); + + // / Tropical Branch + Allele.speciesTropical = new AlleleBeeSpecies("speciesTropical", false, "bees.species.tropical", tropical, "mendelia", 0x378020, 0xffdc16) + .addProduct(ForestryItem.beeComb.getItemStack(1, 6), 20).setEntityTexture("tropicalBee").setTemperature(EnumTemperature.WARM).setHumidity(EnumHumidity.DAMP); + Allele.speciesExotic = new AlleleBeeSpecies("speciesExotic", true, "bees.species.exotic", tropical, "darwini", 0x304903, 0xffdc16) + .addProduct(ForestryItem.beeComb.getItemStack(1, 6), 30).setEntityTexture("tropicalBee").setIsSecret().setTemperature(EnumTemperature.WARM).setHumidity(EnumHumidity.DAMP); + Allele.speciesEdenic = new AlleleBeeSpecies("speciesEdenic", false, "bees.species.edenic", tropical, "humboldti", 0x393d0d, 0xffdc16) + .addProduct(ForestryItem.beeComb.getItemStack(1, 6), 20).setEntityTexture("tropicalBee").setHasEffect().setIsSecret().setTemperature(EnumTemperature.WARM) + .setHumidity(EnumHumidity.DAMP); + + // End Branch + Allele.speciesEnded = new AlleleBeeSpecies("speciesEnded", false, "bees.species.ender", end, "notchi", 0xe079fa, 0xd9de9e) + .addProduct(ForestryItem.beeComb.getItemStack(1, 8), 30).setEntityTexture("endBee").setIsSecret().setTemperature(EnumTemperature.COLD); + Allele.speciesSpectral = new AlleleBeeSpecies("speciesSpectral", true, "bees.species.spectral", end, "idolum", 0xa98bed, 0xd9de9e) // 0xa98bed + .addProduct(ForestryItem.beeComb.getItemStack(1, 8), 50).setEntityTexture("endBee").setIsSecret().setTemperature(EnumTemperature.COLD); + Allele.speciesPhantasmal = new AlleleBeeSpecies("speciesPhantasmal", false, "bees.species.phantasmal", end, "lemur", 0xcc00fa, 0xd9de9e) // 0x31023a // + // 0x8bc3ed + .addProduct(ForestryItem.beeComb.getItemStack(1, 8), 40).setEntityTexture("endBee").setIsSecret().setHasEffect().setTemperature(EnumTemperature.COLD); + + // Frozen Branch + Allele.speciesWintry = new AlleleBeeSpecies("speciesWintry", false, "bees.species.wintry", frozen, "brumalis", 0xa0ffc8, 0xdaf5f3).addProduct( + ForestryItem.beeComb.getItemStack(1, 4), 30).setEntityTexture("icyBee").setTemperature(EnumTemperature.ICY); + Allele.speciesIcy = new AlleleBeeSpecies("speciesIcy", true, "bees.species.icy", frozen, "coagulis", 0xa0ffff, 0xdaf5f3) + .addProduct(ForestryItem.beeComb.getItemStack(1, 4), 20).setEntityTexture("icyBee").addProduct(ForestryItem.craftingMaterial.getItemStack(1, 5), 20) + .setTemperature(EnumTemperature.ICY).setIsSecret(); + Allele.speciesGlacial = new AlleleBeeSpecies("speciesGlacial", false, "bees.species.glacial", frozen, "glacialis", 0xefffff, 0xdaf5f3) + .addProduct(ForestryItem.beeComb.getItemStack(1, 4), 20).setEntityTexture("icyBee").addProduct(ForestryItem.craftingMaterial.getItemStack(1, 5), 40) + .setTemperature(EnumTemperature.ICY).setHasEffect().setIsSecret(); + + // Vengeful Branch + Allele.speciesVindictive = new AlleleBeeSpecies("speciesVindictive", false, "bees.species.vindictive", vengeful, "ultio", 0xeafff3, 0xffdc16) + .addProduct(ForestryItem.beeComb.getItemStack(1, 9), 25).setIsSecret().setIsNotCounted(); + Allele.speciesVengeful = new AlleleBeeSpecies("speciesVengeful", false, "bees.species.vengeful", vengeful, "punire", 0xc2de00, 0xffdc16) + .addProduct(ForestryItem.beeComb.getItemStack(1, 9), 40).setIsSecret().setIsNotCounted(); + Allele.speciesAvenging = new AlleleBeeSpecies("speciesAvenging", false, "bees.species.avenging", vengeful, "hostimentum", 0xddff00, 0xffdc16) + .addProduct(ForestryItem.beeComb.getItemStack(1, 9), 40).setIsSecret().setHasEffect().setIsNotCounted(); + + // Reddened Branch (EE) + Allele.speciesDarkened = new AlleleBeeSpecies("speciesDarkened", false, "bees.species.darkened", reddened, "pahimas", 0xd7bee5, 0x260f29) + .addProduct(ForestryItem.beeComb.getItemStack(1, 0), 100).addSpecialty(ForestryItem.beeComb.getItemStack(1, 12), 100) + .setJubilanceProvider(new JubilanceNone()).setIsSecret().setIsNotCounted(); + AlleleManager.alleleRegistry.blacklistAllele(Allele.speciesDarkened.getUID()); + Allele.speciesReddened = new AlleleBeeSpecies("speciesReddened", false, "bees.species.reddened", reddened, "xenophos", 0xf8c1c1, 0x260f29) + .addProduct(ForestryItem.beeComb.getItemStack(1, 0), 100).addSpecialty(ForestryItem.beeComb.getItemStack(1, 11), 100) + .setJubilanceProvider(new JubilanceNone()).setIsSecret().setIsNotCounted(); + AlleleManager.alleleRegistry.blacklistAllele(Allele.speciesReddened.getUID()); + Allele.speciesOmega = new AlleleBeeSpecies("speciesOmega", false, "bees.species.omega", reddened, "slopokis", 0xfeff8f, 0x260f29) + .addProduct(ForestryItem.beeComb.getItemStack(1, 0), 100).addSpecialty(ForestryItem.beeComb.getItemStack(1, 13), 100) + .setJubilanceProvider(new JubilanceNone()).setIsSecret().setIsNotCounted(); + AlleleManager.alleleRegistry.blacklistAllele(Allele.speciesOmega.getUID()); + + // Festive branch + Allele.speciesLeporine = new AlleleBeeSpecies("speciesLeporine", false, "bees.species.leporine", festive, "lepus", 0xfeff8f, 0x3cd757) + .addProduct(ForestryItem.beeComb.getItemStack(1, 6), 30).addProduct(new ItemStack(Items.egg), 10).setIsSecret().setIsNotCounted() + .setHasEffect(); + Allele.speciesMerry = new AlleleBeeSpecies("speciesMerry", false, "bees.species.merry", festive, "feliciter", 0xffffff, 0xd40000) + .addProduct(ForestryItem.beeComb.getItemStack(1, 4), 30).addProduct(ForestryItem.craftingMaterial.getItemStack(1, 5), 20) + .setTemperature(EnumTemperature.ICY).setIsSecret().setIsNotCounted().setHasEffect(); + Allele.speciesTipsy = new AlleleBeeSpecies("speciesTipsy", false, "bees.species.tipsy", festive, "ebrius", 0xffffff, 0xc219ec) + .addProduct(ForestryItem.beeComb.getItemStack(1, 4), 30).addProduct(ForestryItem.craftingMaterial.getItemStack(1, 5), 20) + .setTemperature(EnumTemperature.ICY).setIsSecret().setIsNotCounted().setHasEffect(); + // 35 Solstice + Allele.speciesTricky = new AlleleBeeSpecies("speciesTricky", false, "bees.species.tricky", festive, "libita", 0x49413B, 0xFF6A00) + .addProduct(ForestryItem.beeComb.getItemStack(1, 0), 40).addProduct(new ItemStack(Items.cookie), 15) + .addSpecialty(new ItemStack(Items.skull, 1, 0), 2).addSpecialty(new ItemStack(Items.skull, 1, 2), 2) + .addSpecialty(new ItemStack(Items.skull, 1, 3), 2).addSpecialty(new ItemStack(Items.skull, 1, 4), 2) + .setIsSecret().setIsNotCounted().setHasEffect(); + // 37 Thanksgiving + + // Agrarian branch + Allele.speciesRural = new AlleleBeeSpecies("speciesRural", false, "bees.species.rural", agrarian, "rustico", 0xfeff8f, 0xffdc16).addProduct( + ForestryItem.beeComb.getItemStack(1, 14), 20).setIsSecret(); + // 41 Farmerly + // 42 Agrarian + + // Boggy branch + Allele.speciesMarshy = new AlleleBeeSpecies("speciesMarshy", true, "bees.species.marshy", boggy, "adorasti", 0x546626, 0xffdc16).addProduct( + ForestryItem.beeComb.getItemStack(1, 15), 30).setHumidity(EnumHumidity.DAMP); + // 44 speciesMiry + // 45 speciesBoggy + + // Monastic branch + Allele.speciesMonastic = new AlleleBeeSpecies("speciesMonastic", false, "bees.species.monastic", monastic, "monachus", 0x42371c, 0xfff7b6) + .addProduct(ForestryItem.beeComb.getItemStack(1, 14), 30).addSpecialty(ForestryItem.beeComb.getItemStack(1, 16), 10) + .setJubilanceProvider(new JubilanceProviderHermit()).setIsSecret(); + Allele.speciesSecluded = new AlleleBeeSpecies("speciesSecluded", true, "bees.species.secluded", monastic, "contractus", 0x7b6634, 0xfff7b6) + .addSpecialty(ForestryItem.beeComb.getItemStack(1, 16), 20).setJubilanceProvider(new JubilanceProviderHermit()).setIsSecret(); + Allele.speciesHermitic = new AlleleBeeSpecies("speciesHermitic", false, "bees.species.hermitic", monastic, "anachoreta", 0xffd46c, 0xfff7b6) + .addSpecialty(ForestryItem.beeComb.getItemStack(1, 16), 20).setJubilanceProvider(new JubilanceProviderHermit()).setHasEffect().setIsSecret(); + + // / BEES // FLOWER PROVIDERS 1500 - 1599 + Allele.flowersVanilla = new AlleleFlowers("flowersVanilla", new FlowerProviderVanilla(), true); + Allele.flowersNether = new AlleleFlowers("flowersNether", new FlowerProviderNetherwart()); + Allele.flowersCacti = new AlleleFlowers("flowersCacti", new FlowerProviderCacti()); + Allele.flowersMushrooms = new AlleleFlowers("flowersMushrooms", new FlowerProviderMushroom()); + Allele.flowersEnd = new AlleleFlowers("flowersEnd", new FlowerProviderEnd()); + Allele.flowersJungle = new AlleleFlowers("flowersJungle", new FlowerProviderJungle()); + Allele.flowersSnow = new AlleleFlowers("flowersSnow", new FlowerProviderVanilla(), true); + Allele.flowersWheat = new AlleleFlowers("flowersWheat", new FlowerProviderWheat(), true); + Allele.flowersGourd = new AlleleFlowers("flowersGourd", new FlowerProviderGourd(), true); + + // / BEES // EFFECTS 1800 - 1899 + Allele.effectNone = new AlleleEffectNone("effectNone"); + Allele.effectAggressive = new AlleleEffectAggressive("effectAggressive"); + Allele.effectHeroic = new AlleleEffectHeroic("effectHeroic"); + Allele.effectBeatific = new AlleleEffectPotion("effectBeatific", "beatific", false, Potion.regeneration, 100, true); + Allele.effectMiasmic = new AlleleEffectMiasmic("effectMiasmic"); + Allele.effectMisanthrope = new AlleleEffectMisanthrope("effectMisanthrope"); + Allele.effectGlacial = new AlleleEffectGlacial("effectGlacial"); + Allele.effectRadioactive = new AlleleEffectRadioactive("effectRadioactive"); + Allele.effectCreeper = new AlleleEffectCreeper("effectCreeper"); + Allele.effectIgnition = new AlleleEffectIgnition("effectIgnition"); + Allele.effectExploration = new AlleleEffectExploration("effectExploration"); + Allele.effectFestiveEaster = new AlleleEffectNone("effectFestiveEaster"); + Allele.effectSnowing = new AlleleEffectSnowing("effectSnowing"); + Allele.effectDrunkard = new AlleleEffectPotion("effectDrunkard", "drunkard", false, Potion.confusion, 100, false); + Allele.effectReanimation = new AlleleEffectResurrection("effectReanimation", "reanimation", AlleleEffectResurrection.getReanimationList()); + Allele.effectResurrection = new AlleleEffectResurrection("effectResurrection", "resurrection", AlleleEffectResurrection.getResurrectionList()); + Allele.effectRepulsion = new AlleleEffectRepulsion("effectRepulsion"); + + } + + private void createMutations() { + // / MUTATIONS + BeeTemplates.commonA = new BeeMutation(Allele.speciesForest, Allele.speciesMeadows, BeeTemplates.getCommonTemplate(), 15); + + BeeTemplates.commonB = new BeeMutation(Allele.speciesModest, Allele.speciesForest, BeeTemplates.getCommonTemplate(), 15); + BeeTemplates.commonC = new BeeMutation(Allele.speciesModest, Allele.speciesMeadows, BeeTemplates.getCommonTemplate(), 15); + + BeeTemplates.commonD = new BeeMutation(Allele.speciesWintry, Allele.speciesForest, BeeTemplates.getCommonTemplate(), 15); + BeeTemplates.commonE = new BeeMutation(Allele.speciesWintry, Allele.speciesMeadows, BeeTemplates.getCommonTemplate(), 15); + BeeTemplates.commonF = new BeeMutation(Allele.speciesWintry, Allele.speciesModest, BeeTemplates.getCommonTemplate(), 15); + + BeeTemplates.commonG = new BeeMutation(Allele.speciesTropical, Allele.speciesForest, BeeTemplates.getCommonTemplate(), 15); + BeeTemplates.commonH = new BeeMutation(Allele.speciesTropical, Allele.speciesMeadows, BeeTemplates.getCommonTemplate(), 15); + BeeTemplates.commonI = new BeeMutation(Allele.speciesTropical, Allele.speciesModest, BeeTemplates.getCommonTemplate(), 15); + BeeTemplates.commonJ = new BeeMutation(Allele.speciesTropical, Allele.speciesWintry, BeeTemplates.getCommonTemplate(), 15); + + BeeTemplates.commonK = new BeeMutation(Allele.speciesMarshy, Allele.speciesForest, BeeTemplates.getCommonTemplate(), 15); + BeeTemplates.commonL = new BeeMutation(Allele.speciesMarshy, Allele.speciesMeadows, BeeTemplates.getCommonTemplate(), 15); + BeeTemplates.commonM = new BeeMutation(Allele.speciesMarshy, Allele.speciesModest, BeeTemplates.getCommonTemplate(), 15); + BeeTemplates.commonN = new BeeMutation(Allele.speciesMarshy, Allele.speciesWintry, BeeTemplates.getCommonTemplate(), 15); + BeeTemplates.commonO = new BeeMutation(Allele.speciesMarshy, Allele.speciesTropical, BeeTemplates.getCommonTemplate(), 15); + + BeeTemplates.cultivatedA = new BeeMutation(Allele.speciesCommon, Allele.speciesForest, BeeTemplates.getCultivatedTemplate(), 12); + BeeTemplates.cultivatedB = new BeeMutation(Allele.speciesCommon, Allele.speciesMeadows, BeeTemplates.getCultivatedTemplate(), 12); + BeeTemplates.cultivatedC = new BeeMutation(Allele.speciesCommon, Allele.speciesModest, BeeTemplates.getCultivatedTemplate(), 12); + BeeTemplates.cultivatedD = new BeeMutation(Allele.speciesCommon, Allele.speciesWintry, BeeTemplates.getCultivatedTemplate(), 12); + BeeTemplates.cultivatedE = new BeeMutation(Allele.speciesCommon, Allele.speciesTropical, BeeTemplates.getCultivatedTemplate(), 12); + BeeTemplates.cultivatedF = new BeeMutation(Allele.speciesCommon, Allele.speciesMarshy, BeeTemplates.getCultivatedTemplate(), 12); + + BeeTemplates.nobleA = new BeeMutation(Allele.speciesCommon, Allele.speciesCultivated, BeeTemplates.getNobleTemplate(), 10); + BeeTemplates.majesticA = new BeeMutation(Allele.speciesNoble, Allele.speciesCultivated, BeeTemplates.getMajesticTemplate(), 8); + BeeTemplates.imperialA = new BeeMutation(Allele.speciesNoble, Allele.speciesMajestic, BeeTemplates.getImperialTemplate(), 8); + + BeeTemplates.diligentA = new BeeMutation(Allele.speciesCommon, Allele.speciesCultivated, BeeTemplates.getDiligentTemplate(), 10); + BeeTemplates.unwearyA = new BeeMutation(Allele.speciesDiligent, Allele.speciesCultivated, BeeTemplates.getUnwearyTemplate(), 8); + BeeTemplates.industriousA = new BeeMutation(Allele.speciesDiligent, Allele.speciesUnweary, BeeTemplates.getIndustriousTemplate(), 8); + + BeeTemplates.heroicA = new BeeMutation(Allele.speciesSteadfast, Allele.speciesValiant, BeeTemplates.getHeroicTemplate(), 6) + .restrictBiomeType(BiomeDictionary.Type.FOREST).enableStrictBiomeCheck(); + + BeeTemplates.sinisterA = new BeeMutation(Allele.speciesModest, Allele.speciesCultivated, BeeTemplates.getSinisterTemplate(), 60) + .restrictBiomeType(BiomeDictionary.Type.NETHER); + BeeTemplates.sinisterB = new BeeMutation(Allele.speciesTropical, Allele.speciesCultivated, BeeTemplates.getSinisterTemplate(), 60) + .restrictBiomeType(BiomeDictionary.Type.NETHER); + BeeTemplates.fiendishA = new BeeMutation(Allele.speciesSinister, Allele.speciesCultivated, BeeTemplates.getFiendishTemplate(), 40) + .restrictBiomeType(BiomeDictionary.Type.NETHER); + BeeTemplates.fiendishB = new BeeMutation(Allele.speciesSinister, Allele.speciesModest, BeeTemplates.getFiendishTemplate(), 40) + .restrictBiomeType(BiomeDictionary.Type.NETHER); + BeeTemplates.fiendishC = new BeeMutation(Allele.speciesSinister, Allele.speciesTropical, BeeTemplates.getFiendishTemplate(), 40) + .restrictBiomeType(BiomeDictionary.Type.NETHER); + BeeTemplates.demonicA = new BeeMutation(Allele.speciesSinister, Allele.speciesFiendish, BeeTemplates.getDemonicTemplate(), 25) + .restrictBiomeType(BiomeDictionary.Type.NETHER); + + // Austere branch + BeeTemplates.frugalA = new BeeMutation(Allele.speciesModest, Allele.speciesSinister, BeeTemplates.getFrugalTemplate(), 16).setTemperatureRainfall(1.9f, + 2.0f, 0.0f, 0.1f); + BeeTemplates.frugalB = new BeeMutation(Allele.speciesModest, Allele.speciesFiendish, BeeTemplates.getFrugalTemplate(), 10).setTemperatureRainfall(1.9f, + 2.0f, 0.0f, 0.1f); + BeeTemplates.austereA = new BeeMutation(Allele.speciesModest, Allele.speciesFrugal, BeeTemplates.getAustereTemplate(), 8).setTemperatureRainfall(1.9f, + 2.0f, 0.0f, 0.1f); + + // Tropical branch + BeeTemplates.exoticA = new BeeMutation(Allele.speciesAustere, Allele.speciesTropical, BeeTemplates.getExoticTemplate(), 12); + BeeTemplates.edenicA = new BeeMutation(Allele.speciesExotic, Allele.speciesTropical, BeeTemplates.getEdenicTemplate(), 8); + + // Wintry branch + BeeTemplates.icyA = new BeeMutation(Allele.speciesIndustrious, Allele.speciesWintry, BeeTemplates.getIcyTemplate(), 12).setTemperature(0f, 0.15f); + BeeTemplates.glacialA = new BeeMutation(Allele.speciesIcy, Allele.speciesWintry, BeeTemplates.getGlacialTemplate(), 8).setTemperature(0f, 0.15f); + + // Festive branch + BeeTemplates.leporineA = new MutationTimeLimited(Allele.speciesMeadows, Allele.speciesForest, BeeTemplates.getLeporineTemplate(), 10, + new MutationTimeLimited.DayMonth(29, 3), new MutationTimeLimited.DayMonth(15, 4)).setIsSecret(); + BeeTemplates.merryA = new MutationTimeLimited(Allele.speciesWintry, Allele.speciesForest, BeeTemplates.getMerryTemplate(), 10, + new MutationTimeLimited.DayMonth(21, 12), new MutationTimeLimited.DayMonth(27, 12)).setIsSecret(); + BeeTemplates.tipsyA = new MutationTimeLimited(Allele.speciesWintry, Allele.speciesMeadows, BeeTemplates.getTipsyTemplate(), 10, + new MutationTimeLimited.DayMonth(27, 12), new MutationTimeLimited.DayMonth(2, 1)).setIsSecret(); + BeeTemplates.trickyA = new MutationTimeLimited(Allele.speciesSinister, Allele.speciesCommon, BeeTemplates.getTrickyTemplate(), 10, + new MutationTimeLimited.DayMonth(15, 10), new MutationTimeLimited.DayMonth(3, 11)).setIsSecret(); + + // Agrarian branch + BeeTemplates.ruralA = new BeeMutation(Allele.speciesMeadows, Allele.speciesDiligent, BeeTemplates.getRuralTemplate(), 12) + .restrictBiomeType(BiomeDictionary.Type.PLAINS).enableStrictBiomeCheck(); + + // Monastic branch + BeeTemplates.secludedA = new BeeMutation(Allele.speciesMonastic, Allele.speciesAustere, BeeTemplates.getSecludedTemplate(), 12); + BeeTemplates.hermiticA = new BeeMutation(Allele.speciesMonastic, Allele.speciesSecluded, BeeTemplates.getHermiticTemplate(), 8); + + // End branch + BeeTemplates.spectralA = new BeeMutation(Allele.speciesHermitic, Allele.speciesEnded, BeeTemplates.getSpectralTemplate(), 4); + BeeTemplates.phantasmalA = new BeeMutation(Allele.speciesSpectral, Allele.speciesEnded, BeeTemplates.getPhantasmalTemplate(), 2); + + // Vindictive branch + BeeTemplates.vindictiveA = new BeeMutation(Allele.speciesMonastic, Allele.speciesDemonic, BeeTemplates.getVindictiveTemplate(), 4).setIsSecret(); + + BeeTemplates.vengefulA = new BeeMutation(Allele.speciesDemonic, Allele.speciesVindictive, BeeTemplates.getVengefulTemplate(), 8).setIsSecret(); + BeeTemplates.vengefulB = new BeeMutation(Allele.speciesMonastic, Allele.speciesVindictive, BeeTemplates.getVengefulTemplate(), 8).setIsSecret(); + BeeTemplates.avengingA = new BeeMutation(Allele.speciesVengeful, Allele.speciesVindictive, BeeTemplates.getAvengingTemplate(), 4); + } + + private void registerTemplates() { + beeInterface.registerTemplate(BeeTemplates.getForestTemplate()); + beeInterface.registerTemplate(BeeTemplates.getMeadowsTemplate()); + beeInterface.registerTemplate(BeeTemplates.getCommonTemplate()); + beeInterface.registerTemplate(BeeTemplates.getCultivatedTemplate()); + beeInterface.registerTemplate(BeeTemplates.getNobleTemplate()); + beeInterface.registerTemplate(BeeTemplates.getMajesticTemplate()); + beeInterface.registerTemplate(BeeTemplates.getImperialTemplate()); + beeInterface.registerTemplate(BeeTemplates.getDiligentTemplate()); + beeInterface.registerTemplate(BeeTemplates.getUnwearyTemplate()); + beeInterface.registerTemplate(BeeTemplates.getIndustriousTemplate()); + beeInterface.registerTemplate(BeeTemplates.getSteadfastTemplate()); + beeInterface.registerTemplate(BeeTemplates.getValiantTemplate()); + beeInterface.registerTemplate(BeeTemplates.getHeroicTemplate()); + beeInterface.registerTemplate(BeeTemplates.getSinisterTemplate()); + beeInterface.registerTemplate(BeeTemplates.getFiendishTemplate()); + beeInterface.registerTemplate(BeeTemplates.getDemonicTemplate()); + beeInterface.registerTemplate(BeeTemplates.getModestTemplate()); + beeInterface.registerTemplate(BeeTemplates.getFrugalTemplate()); + beeInterface.registerTemplate(BeeTemplates.getAustereTemplate()); + beeInterface.registerTemplate(BeeTemplates.getTropicalTemplate()); + beeInterface.registerTemplate(BeeTemplates.getExoticTemplate()); + beeInterface.registerTemplate(BeeTemplates.getEdenicTemplate()); + beeInterface.registerTemplate(BeeTemplates.getWintryTemplate()); + beeInterface.registerTemplate(BeeTemplates.getIcyTemplate()); + beeInterface.registerTemplate(BeeTemplates.getGlacialTemplate()); + beeInterface.registerTemplate(BeeTemplates.getVindictiveTemplate()); + beeInterface.registerTemplate(BeeTemplates.getVengefulTemplate()); + beeInterface.registerTemplate(BeeTemplates.getAvengingTemplate()); + beeInterface.registerTemplate(BeeTemplates.getDarkenedTemplate()); + beeInterface.registerTemplate(BeeTemplates.getReddenedTemplate()); + beeInterface.registerTemplate(BeeTemplates.getOmegaTemplate()); + beeInterface.registerTemplate(BeeTemplates.getRuralTemplate()); + beeInterface.registerTemplate(BeeTemplates.getLeporineTemplate()); + beeInterface.registerTemplate(BeeTemplates.getMerryTemplate()); + beeInterface.registerTemplate(BeeTemplates.getTipsyTemplate()); + beeInterface.registerTemplate(BeeTemplates.getTrickyTemplate()); + beeInterface.registerTemplate(BeeTemplates.getMarshyTemplate()); + beeInterface.registerTemplate(BeeTemplates.getMonasticTemplate()); + beeInterface.registerTemplate(BeeTemplates.getSecludedTemplate()); + beeInterface.registerTemplate(BeeTemplates.getHermiticTemplate()); + beeInterface.registerTemplate(BeeTemplates.getEnderTemplate()); + beeInterface.registerTemplate(BeeTemplates.getSpectralTemplate()); + beeInterface.registerTemplate(BeeTemplates.getPhantasmalTemplate()); + } + + private void parseAdditionalFlowers(String list, ArrayList target) { + String[] parts = list.split("[;]+"); + + for (String part : parts) { + if (part.isEmpty()) + continue; + + String[] ident = part.split("[:]+"); + + if (ident.length != 1 && ident.length != 2) { + Proxies.log.warning("Failed to add flower of (" + part + ") to vanilla flower provider since it isn't formatted properly."); + continue; + } + + Item item = GameData.itemRegistry.getObject(ident[0]); + + if (item == null) { + Block block = GameData.blockRegistry.getObject(ident[0]); + + if (block == null || block == Blocks.air || Item.getItemFromBlock(block) == null) { + Proxies.log.warning("Failed to add flower of (" + part + ") to vanilla flower provider since it couldn't be found."); + continue; + } + + item = Item.getItemFromBlock(block); + } + + int meta = ident.length > 1 ? Integer.parseInt(ident[1]) : 0; + + Proxies.log.finer("Adding flower of (" + part + ") to vanilla flower provider."); + target.add(new ItemStack(item, 1, meta)); + } + } + + private void parseBeeBlacklist(String list) { + String[] items = list.split("[;]+"); + + for (String item : items) { + if (item.isEmpty()) + continue; + + FMLCommonHandler.instance().getFMLLogger().debug("Blacklisting bee species identified by " + item); + AlleleManager.alleleRegistry.blacklistAllele(item); + } + } + + @Override + public ISaveEventHandler getSaveEventHandler() { + return new SaveEventHandlerApiculture(); + } + + @Override + public IOreDictionaryHandler getDictionaryHandler() { + return null; + } + + @Override + public ICommand[] getConsoleCommands() { + return new ICommand[] { new CommandBeekeepingMode(), new CommandGiveBee(EnumBeeType.DRONE), new CommandGiveBee(EnumBeeType.PRINCESS), + new CommandGiveBee(EnumBeeType.QUEEN), }; + } + + @Override + public boolean processIMCMessage(IMCMessage message) { + if (message.key.equals("add-candle-lighting-id")) { + ItemStack value = message.getItemStackValue(); + if (value != null) { + ((BlockCandle) ForestryBlock.candle).addItemToLightingList(value.getItem()); + } else { + Logger.getLogger("Forestry").log(Level.WARNING, + "Recieved an invalid 'add-candle-lighting-id' request from mod %s. Please contact the author and report this issue.", + message.getSender()); + } + return true; + } + else if (message.key.equals("add-alveary-slab") && message.isStringMessage()) { + try { + Block block = GameData.blockRegistry.getObject(message.getStringValue()); + + if (block == null || block == Blocks.air) { + Logger.getLogger("Forestry").log(Level.WARNING, + "Recieved an invalid 'add-alveary-slab' request from mod %s. Please contact the author and report this issue.", + message.getSender()); + } else { + StructureLogicAlveary.slabBlocks.add(block); + } + } catch (Exception e) { + } + } + return super.processIMCMessage(message); + } + + @SubscribeEvent + @SideOnly(Side.CLIENT) + public void textureHook(TextureStitchEvent.Pre event) { + if (event.map.getTextureType() == 1) { + EntitySnowFX.icons = new IIcon[3]; + for (int i = 0; i < EntitySnowFX.icons.length; i++) { + EntitySnowFX.icons[i] = event.map.registerIcon("forestry:particles/snow." + (i + 1)); + } + } + } +} diff --git a/forestry_common/apiculture/forestry/plugins/PluginEE.java b/forestry_common/apiculture/forestry/plugins/PluginEE.java new file mode 100755 index 000000000..1b99e8a71 --- /dev/null +++ b/forestry_common/apiculture/forestry/plugins/PluginEE.java @@ -0,0 +1,92 @@ +/******************************************************************************* + * Copyright 2011-2014 by SirSengir + * + * This work is licensed under a Creative Commons Attribution-NonCommercial-NoDerivs 3.0 Unported License. + * + * To view a copy of this license, visit http://creativecommons.org/licenses/by-nc-nd/3.0/. + ******************************************************************************/ +package forestry.plugins; + +import java.lang.reflect.Field; + +import net.minecraft.block.Block; +import net.minecraft.item.ItemStack; + +import net.minecraftforge.common.BiomeDictionary; + +import forestry.api.core.IPlugin; +import forestry.api.core.PluginInfo; +import forestry.api.genetics.AlleleManager; +import forestry.api.genetics.IMutation; +import forestry.apiculture.genetics.AlleleBeeSpecies; +import forestry.apiculture.genetics.BeeTemplates; +import forestry.apiculture.genetics.IJubilanceProvider; +import forestry.apiculture.genetics.JubilanceReqRes; +import forestry.apiculture.genetics.MutationEMC; +import forestry.core.config.Config; +import forestry.core.config.Defaults; +import forestry.core.genetics.Allele; +import forestry.core.proxy.Proxies; + +@PluginInfo(pluginID = "EqEx2", name = "Equivalent Exchange 2", author = "SirSengir", url = Defaults.URL, description = "Compatibility plugin for Equivalent Exchange 2. Enables the Omega branch of bees. Requires Apiculture to be enabled.") +public class PluginEE implements IPlugin { + + public IMutation darkenedA; + public IMutation reddenedA; + public IMutation omegaA; + + public ItemStack eeBlock1; + public ItemStack eeBlock2; + + public Class eeRelay2Class; + public Class eeRelay3Class; + public Field eeRelay2EMCField; + public Field eeRelay3EMCField; + + @Override + public boolean isAvailable() { + return Proxies.common.isModLoaded("mod_EE") && !Config.disableApiculture; + } + + @Override + public void postInit() { + + try { + + eeBlock1 = new ItemStack((Block) Class.forName("ee.EEBlock").getField("eeStone").get(null), 1, 8); + eeBlock2 = new ItemStack((Block) Class.forName("ee.EEBlock").getField("eeStone").get(null), 1, 9); + eeRelay2Class = Class.forName("ee.TileRelay2"); + eeRelay2EMCField = eeRelay2Class.getField("scaledEnergy"); + eeRelay3Class = Class.forName("ee.TileRelay3"); + eeRelay3EMCField = eeRelay3Class.getField("scaledEnergy"); + + } catch (Exception ex) { + Proxies.log.fine("Necessary block/classes from EE were not found"); + return; + } + + IJubilanceProvider jubilanceProviderDarkened = new JubilanceReqRes(eeBlock1); + IJubilanceProvider jubilanceProviderReddened = new JubilanceReqRes(eeBlock2); + + ((AlleleBeeSpecies) AlleleManager.alleleRegistry.getAllele("forestry.speciesDarkened")).jubilanceProvider = jubilanceProviderDarkened; + ((AlleleBeeSpecies) AlleleManager.alleleRegistry.getAllele("forestry.speciesReddened")).jubilanceProvider = jubilanceProviderReddened; + ((AlleleBeeSpecies) AlleleManager.alleleRegistry.getAllele("forestry.speciesOmega")).jubilanceProvider = jubilanceProviderReddened; + + darkenedA = new MutationEMC(Allele.speciesModest, Allele.speciesWintry, BeeTemplates.getDarkenedTemplate(), 100, eeBlock1, eeRelay2Class, + eeRelay2EMCField, 139264); + reddenedA = new MutationEMC(Allele.speciesDarkened, Allele.speciesTropical, BeeTemplates.getReddenedTemplate(), 100, eeBlock2, eeRelay3Class, + eeRelay3EMCField, 466944); + omegaA = new MutationEMC(Allele.speciesDarkened, Allele.speciesReddened, BeeTemplates.getOmegaTemplate(), 100, eeBlock2, eeRelay3Class, + eeRelay3EMCField, 933888).restrictBiomeType(BiomeDictionary.Type.NETHER).restrictBiomeType(BiomeDictionary.Type.DESERT); + + } + + @Override + public void preInit() { + } + + @Override + public void doInit() { + } + +} diff --git a/forestry_common/arboriculture/forestry/arboriculture/CommandSpawnForest.java b/forestry_common/arboriculture/forestry/arboriculture/CommandSpawnForest.java new file mode 100755 index 000000000..88c35192d --- /dev/null +++ b/forestry_common/arboriculture/forestry/arboriculture/CommandSpawnForest.java @@ -0,0 +1,44 @@ +/******************************************************************************* + * Copyright 2011-2014 by SirSengir + * + * This work is licensed under a Creative Commons Attribution-NonCommercial-NoDerivs 3.0 Unported License. + * + * To view a copy of this license, visit http://creativecommons.org/licenses/by-nc-nd/3.0/. + ******************************************************************************/ +package forestry.arboriculture; + +import net.minecraft.command.ICommandSender; +import net.minecraft.entity.player.EntityPlayer; +import net.minecraft.world.gen.feature.WorldGenerator; + +import forestry.api.world.ITreeGenData; +import forestry.arboriculture.genetics.TreeTemplates; +import forestry.arboriculture.worldgen.WorldGenBalsa; +import forestry.core.utils.CommandMC; +import forestry.plugins.PluginArboriculture; + +public class CommandSpawnForest extends CommandMC { + + public String getCommandName() { + return "spawnforest"; + } + + public String getCommandUsage(ICommandSender sender) { + return "/" + getCommandName() + " "; + } + + public void processCommand(ICommandSender sender, String[] arguments) { + + EntityPlayer player = this.getPlayerFromName(sender.getCommandSenderName()); + + int x = (int) player.posX - 16; + int y = (int) (player.posY); + int z = (int) player.posZ - 16; + + WorldGenerator gen = new WorldGenBalsa((ITreeGenData) PluginArboriculture.treeInterface.getTree(player.worldObj, + TreeTemplates.templateAsGenome(PluginArboriculture.treeInterface.getTemplate("treeBalsa")))); + + for (int i = 0; i < 16; i++) + gen.generate(player.worldObj, player.worldObj.rand, x + player.worldObj.rand.nextInt(32), y, z + player.worldObj.rand.nextInt(32)); + } +} diff --git a/forestry_common/arboriculture/forestry/arboriculture/CommandSpawnTree.java b/forestry_common/arboriculture/forestry/arboriculture/CommandSpawnTree.java new file mode 100755 index 000000000..8fd1f1d6e --- /dev/null +++ b/forestry_common/arboriculture/forestry/arboriculture/CommandSpawnTree.java @@ -0,0 +1,47 @@ +/******************************************************************************* + * Copyright 2011-2014 by SirSengir + * + * This work is licensed under a Creative Commons Attribution-NonCommercial-NoDerivs 3.0 Unported License. + * + * To view a copy of this license, visit http://creativecommons.org/licenses/by-nc-nd/3.0/. + ******************************************************************************/ +package forestry.arboriculture; + +import net.minecraft.command.ICommandSender; +import net.minecraft.entity.player.EntityPlayer; +import net.minecraft.world.gen.feature.WorldGenerator; + +import forestry.api.world.ITreeGenData; +import forestry.arboriculture.genetics.TreeTemplates; +import forestry.arboriculture.worldgen.WorldGenBalsa; +import forestry.core.utils.CommandMC; +import forestry.plugins.PluginArboriculture; + +public class CommandSpawnTree extends CommandMC { + + public CommandSpawnTree() { + } + + public String getCommandName() { + return "spawntree"; + } + + public String getCommandUsage(ICommandSender sender) { + return "/" + getCommandName() + " "; + } + + public void processCommand(ICommandSender sender, String[] arguments) { + + EntityPlayer player = this.getPlayerFromName(sender.getCommandSenderName()); + + int x = (int) player.posX; + int y = (int) (player.posY); + int z = (int) player.posZ; + + WorldGenerator gen = new WorldGenBalsa((ITreeGenData) PluginArboriculture.treeInterface.getTree(player.worldObj, + TreeTemplates.templateAsGenome(PluginArboriculture.treeInterface.getTemplate("treeBalsa")))); + + gen.generate(player.worldObj, player.worldObj.rand, x, y, z); + + } +} diff --git a/forestry_common/arboriculture/forestry/arboriculture/CommandTreekeepingMode.java b/forestry_common/arboriculture/forestry/arboriculture/CommandTreekeepingMode.java new file mode 100755 index 000000000..88bec26a1 --- /dev/null +++ b/forestry_common/arboriculture/forestry/arboriculture/CommandTreekeepingMode.java @@ -0,0 +1,241 @@ +/******************************************************************************* + * Copyright 2011-2014 by SirSengir + * + * This work is licensed under a Creative Commons Attribution-NonCommercial-NoDerivs 3.0 Unported License. + * + * To view a copy of this license, visit http://creativecommons.org/licenses/by-nc-nd/3.0/. + ******************************************************************************/ +package forestry.arboriculture; + +import java.io.BufferedWriter; +import java.io.File; +import java.io.FileOutputStream; +import java.io.OutputStreamWriter; +import java.text.DateFormat; +import java.util.ArrayList; +import java.util.Collection; +import java.util.Date; +import java.util.List; +import java.util.Locale; + +import net.minecraft.command.CommandException; +import net.minecraft.command.ICommand; +import net.minecraft.command.ICommandSender; +import net.minecraft.command.WrongUsageException; +import net.minecraft.entity.player.EntityPlayer; +import net.minecraft.world.World; + +import forestry.api.arboriculture.IAlleleTreeSpecies; +import forestry.api.arboriculture.IArboristTracker; +import forestry.api.arboriculture.ITreekeepingMode; +import forestry.api.genetics.AlleleManager; +import forestry.api.genetics.IAllele; +import forestry.core.config.Defaults; +import forestry.core.config.Version; +import forestry.core.proxy.Proxies; +import forestry.core.utils.CommandMC; +import forestry.core.utils.StringUtil; +import forestry.plugins.PluginArboriculture; + +public class CommandTreekeepingMode extends CommandMC { + + String[] modeStrings; + + public CommandTreekeepingMode() { + modeStrings = new String[PluginArboriculture.treeInterface.getTreekeepingModes().size()]; + for (int i = 0; i < PluginArboriculture.treeInterface.getTreekeepingModes().size(); i++) + modeStrings[i] = PluginArboriculture.treeInterface.getTreekeepingModes().get(i).getName(); + } + + @Override + public int compareTo(Object arg0) { + return this.getCommandName().compareTo(((ICommand) arg0).getCommandName()); + } + + @Override + public String getCommandName() { + return "treekeeping"; + } + + @Override + public String getCommandUsage(ICommandSender var1) { + return "/" + this.getCommandName() + " help"; + } + + @SuppressWarnings("rawtypes") + @Override + public List getCommandAliases() { + return null; + } + + @Override + public void processCommand(ICommandSender sender, String[] arguments) { + + if (arguments.length <= 0) + throw new WrongUsageException("Type '" + this.getCommandUsage(sender) + "' for help."); + + if (arguments[0].matches("list")) + listModes(sender, arguments); + else if (arguments[0].matches("info")) + listModeInfo(sender, arguments); + else if (arguments[0].matches("set")) { + if (arguments.length <= 1) + throw new WrongUsageException("/" + this.getCommandName() + " set [] "); + + World world = getWorld(sender, arguments); + String desired = arguments[arguments.length - 1]; + + ITreekeepingMode mode = PluginArboriculture.treeInterface.getTreekeepingMode(desired); + if (mode == null) + throw new CommandException("A treekeeping mode called '%s' is not available.", desired); + + PluginArboriculture.treeInterface.setTreekeepingMode(world, mode.getName()); + notifyAdmins(sender, "Treekeeping mode set to %s.", mode.getName()); + + } else if (arguments[0].matches("save")) { + if (arguments.length <= 1) + throw new WrongUsageException("/" + this.getCommandName() + " save "); + + saveStatistics(sender, arguments); + } else if (arguments[0].matches("help")) { + sendChatMessage(sender, "Format: '/" + this.getCommandName() + " '"); + sendChatMessage(sender, "Available commands:"); + sendChatMessage(sender, "- list []: lists current and available treekeeping modes."); + sendChatMessage(sender, "- info : information on treekeeping mode."); + sendChatMessage(sender, "- set [] : set treekeeping mode for world."); + sendChatMessage(sender, "- save [] : save treekeeping statistics for the given player."); + } + } + + private void saveStatistics(ICommandSender sender, String[] arguments) { + + String newLine = System.getProperty("line.separator"); + World world = getWorld(sender, arguments); + + String player = arguments[1]; + Collection statistics = new ArrayList(); + + statistics.add(String.format("Treekeeping statistics for %s on %s:", player, DateFormat.getInstance().format(new Date()))); + statistics.add(""); + statistics.add("MODE: " + PluginArboriculture.treeInterface.getTreekeepingMode(world).getName()); + statistics.add(""); + + IArboristTracker tracker = PluginArboriculture.treeInterface.getBreedingTracker(world, player); + if (tracker == null) + statistics.add("No statistics found."); + else { + statistics.add("BRED:"); + statistics.add("-----"); + statistics.add(""); + + Collection species = new ArrayList(); + for (IAllele allele : AlleleManager.alleleRegistry.getRegisteredAlleles().values()) + if (allele instanceof IAlleleTreeSpecies) + species.add((IAlleleTreeSpecies) allele); + + statistics.add(String.format("SPECIES (%s):", species.size())); + statistics.add("-------------"); + statistics.add(""); + + for (IAlleleTreeSpecies allele : species) + statistics.add(generateSpeciesListEntry(allele, tracker)); + } + + File file = new File(Proxies.common.getForestryRoot(), "config/" + Defaults.MOD.toLowerCase(Locale.ENGLISH) + "/stats/" + player + ".log"); + try { + + if (file.getParentFile() != null) + file.getParentFile().mkdirs(); + + if (!file.exists() && !file.createNewFile()) { + sendChatMessage(sender, "Log file could not be created. Failed to save statistics."); + return; + } + + if (!file.canWrite()) { + sendChatMessage(sender, "Cannot write to log file. Failed to save statistics."); + return; + } + + FileOutputStream fileout = new FileOutputStream(file); + BufferedWriter writer = new BufferedWriter(new OutputStreamWriter(fileout, "UTF-8")); + + writer.write("# " + Defaults.MOD + newLine + "# " + Version.getVersion() + newLine); + + for (String line : statistics) + writer.write(line + newLine); + + writer.close(); + + } catch (Exception ex) { + sendChatMessage(sender, "Write operation threw an exception. Failed to save statistics."); + ex.printStackTrace(); + } + + sendChatMessage(sender, "Saved statistics for player " + player); + } + + private String generateSpeciesListEntry(IAlleleTreeSpecies species, IArboristTracker tracker) { + String discovered = "[ ]"; + if (tracker.isDiscovered(species)) + discovered = "[ X ]"; + String blacklisted = "[ ]"; + if (AlleleManager.alleleRegistry.isBlacklisted(species.getUID())) + blacklisted = "[ BL ]"; + String notcounted = "[ ]"; + if (!species.isCounted()) + notcounted = "[ NC ]"; + + return String.format("%s %s %s\t%-40s %-20s %-20s", discovered, blacklisted, notcounted, species.getUID(), species.getName(), species.getAuthority()); + } + + private void listModes(ICommandSender sender, String[] arguments) { + World world = getWorld(sender, arguments); + + sendChatMessage(sender, "Current: " + PluginArboriculture.treeInterface.getTreekeepingMode(world).getName() + " (#" + world.getWorldInfo().getSaveVersion() + + ")"); + + String help = ""; + for (ITreekeepingMode mode : PluginArboriculture.treeInterface.getTreekeepingModes()) { + if (!help.isEmpty()) + help += ", "; + help += mode.getName(); + } + sendChatMessage(sender, "Available modes: " + help); + return; + } + + private void listModeInfo(ICommandSender sender, String[] arguments) { + if (arguments.length <= 1) + throw new WrongUsageException("/" + this.getCommandName() + " info "); + + ITreekeepingMode found = null; + for (ITreekeepingMode mode : PluginArboriculture.treeInterface.getTreekeepingModes()) + if (mode.getName().equalsIgnoreCase(arguments[1])) { + found = mode; + break; + } + + if (found == null) + throw new CommandException("No treekeeping mode called '%s' is available.", arguments[1]); + + sendChatMessage(sender, "\u00A7aMode: " + found.getName()); + for (String desc : found.getDescription()) + sendChatMessage(sender, StringUtil.localize(desc)); + } + + @Override + public boolean canCommandSenderUseCommand(ICommandSender sender) { + if (sender instanceof EntityPlayer) + return Proxies.common.isOp((EntityPlayer) sender); + else + return sender.canCommandSenderUseCommand(4, getCommandName()); + } + + @SuppressWarnings("rawtypes") + @Override + public List addTabCompletionOptions(ICommandSender sender, String[] incomplete) { + return getListOfStringsMatchingLastWord(incomplete, modeStrings); + } + +} diff --git a/forestry_common/arboriculture/forestry/arboriculture/EventHandlerArboriculture.java b/forestry_common/arboriculture/forestry/arboriculture/EventHandlerArboriculture.java new file mode 100755 index 000000000..ed9bd0ea4 --- /dev/null +++ b/forestry_common/arboriculture/forestry/arboriculture/EventHandlerArboriculture.java @@ -0,0 +1,49 @@ +/******************************************************************************* + * Copyright 2011-2014 by SirSengir + * + * This work is licensed under a Creative Commons Attribution-NonCommercial-NoDerivs 3.0 Unported License. + * + * To view a copy of this license, visit http://creativecommons.org/licenses/by-nc-nd/3.0/. + ******************************************************************************/ +package forestry.arboriculture; + +import net.minecraft.tileentity.TileEntity; + +import cpw.mods.fml.common.eventhandler.Event.Result; +import cpw.mods.fml.common.eventhandler.SubscribeEvent; + +import net.minecraftforge.event.entity.player.BonemealEvent; + +import forestry.api.genetics.IFruitBearer; +import forestry.arboriculture.gadgets.TileFruitPod; +import forestry.arboriculture.gadgets.TileSapling; +import forestry.core.proxy.Proxies; + +public class EventHandlerArboriculture { + + @SubscribeEvent + public void handleBonemeal(BonemealEvent event) { + + if (!Proxies.common.isSimulating(event.world)) + return; + + TileEntity tile = event.world.getTileEntity(event.x, event.y, event.z); + if (tile instanceof TileSapling) { + int result = ((TileSapling) tile).tryGrow(true); + if (result == 1 || result == 2) + event.setResult(Result.ALLOW); + } else if (tile instanceof IFruitBearer) { + IFruitBearer bearer = (IFruitBearer) tile; + if (bearer.getRipeness() <= 1.0f) { + bearer.addRipeness(1.0f); + event.setResult(Result.ALLOW); + } + } else if(tile instanceof TileFruitPod) { + if(((TileFruitPod)tile).canMature()) { + ((TileFruitPod)tile).mature(); + event.setResult(Result.ALLOW); + } + } + } + +} diff --git a/forestry_common/arboriculture/forestry/arboriculture/FruitProviderNone.java b/forestry_common/arboriculture/forestry/arboriculture/FruitProviderNone.java new file mode 100755 index 000000000..57e6f55ff --- /dev/null +++ b/forestry_common/arboriculture/forestry/arboriculture/FruitProviderNone.java @@ -0,0 +1,127 @@ +/******************************************************************************* + * Copyright 2011-2014 by SirSengir + * + * This work is licensed under a Creative Commons Attribution-NonCommercial-NoDerivs 3.0 Unported License. + * + * To view a copy of this license, visit http://creativecommons.org/licenses/by-nc-nd/3.0/. + ******************************************************************************/ +package forestry.arboriculture; + +import java.util.HashMap; + +import net.minecraft.client.renderer.texture.IIconRegister; +import net.minecraft.item.ItemStack; +import net.minecraft.world.IBlockAccess; +import net.minecraft.world.World; + +import cpw.mods.fml.relauncher.Side; +import cpw.mods.fml.relauncher.SideOnly; + +import forestry.api.arboriculture.IFruitProvider; +import forestry.api.arboriculture.ITreeGenome; +import forestry.api.genetics.IFruitFamily; +import forestry.core.render.TextureManager; + +public class FruitProviderNone implements IFruitProvider { + + private static class OverlayType { + public final String ident; + public final short texUID; + + public OverlayType(String ident, short texUID) { + this.ident = ident; + this.texUID = texUID; + } + } + + private static HashMap overlayTypes = new HashMap(); + static { + overlayTypes.put("berries", new OverlayType("berries", (short) 1000)); + overlayTypes.put("pomes", new OverlayType("pomes", (short) 1001)); + overlayTypes.put("nuts", new OverlayType("nuts", (short) 1002)); + overlayTypes.put("citrus", new OverlayType("citrus", (short) 1003)); + overlayTypes.put("plums", new OverlayType("plums", (short) 1004)); + } + + String key; + IFruitFamily family = null; + + int ripeningPeriod = 10; + + OverlayType overlay = null; + + public FruitProviderNone(String key, IFruitFamily family) { + this.key = key; + this.family = family; + } + + public IFruitProvider setOverlay(String ident) { + overlay = overlayTypes.get(ident); + return this; + } + + @Override + public IFruitFamily getFamily() { + return family; + } + + @Override + public ItemStack[] getFruits(ITreeGenome genome, World world, int x, int y, int z, int ripeningTime) { + return new ItemStack[0]; + } + + @Override + public boolean requiresFruitBlocks() { + return false; + } + + @Override + public boolean trySpawnFruitBlock(ITreeGenome genome, World world, int x, int y, int z) { + return false; + } + + @Override + public int getColour(ITreeGenome genome, IBlockAccess world, int x, int y, int z, int ripeningTime) { + return 0xffffff; + } + + @Override + public boolean markAsFruitLeaf(ITreeGenome genome, World world, int x, int y, int z) { + return false; + } + + @Override + public int getRipeningPeriod() { + return ripeningPeriod; + } + + @Override + public ItemStack[] getProducts() { + return new ItemStack[0]; + } + + @Override + public ItemStack[] getSpecialty() { + return new ItemStack[0]; + } + + @Override + public String getDescription() { + return "fruits." + key; + } + + @Override + public short getIconIndex(ITreeGenome genome, IBlockAccess world, int x, int y, int z, int ripeningTime, boolean fancy) { + if(overlay != null) + return overlay.texUID; + else + return -1; + } + + @Override + @SideOnly(Side.CLIENT) + public void registerIcons(IIconRegister register) { + if (overlay != null) + TextureManager.getInstance().registerTexUID(register, overlay.texUID, "leaves/fruits." + overlay.ident); + } +} diff --git a/forestry_common/arboriculture/forestry/arboriculture/FruitProviderPod.java b/forestry_common/arboriculture/forestry/arboriculture/FruitProviderPod.java new file mode 100755 index 000000000..2e99a4bff --- /dev/null +++ b/forestry_common/arboriculture/forestry/arboriculture/FruitProviderPod.java @@ -0,0 +1,103 @@ +/******************************************************************************* + * Copyright 2011-2014 by SirSengir + * + * This work is licensed under a Creative Commons Attribution-NonCommercial-NoDerivs 3.0 Unported License. + * + * To view a copy of this license, visit http://creativecommons.org/licenses/by-nc-nd/3.0/. + ******************************************************************************/ +package forestry.arboriculture; + +import java.util.Locale; + +import net.minecraft.client.renderer.texture.IIconRegister; +import net.minecraft.init.Blocks; +import net.minecraft.item.ItemStack; +import net.minecraft.world.IBlockAccess; +import net.minecraft.world.World; + +import cpw.mods.fml.relauncher.Side; +import cpw.mods.fml.relauncher.SideOnly; + +import forestry.api.arboriculture.EnumTreeChromosome; +import forestry.api.arboriculture.IAlleleFruit; +import forestry.api.arboriculture.ITreeGenome; +import forestry.api.genetics.IFruitFamily; +import forestry.core.render.TextureManager; +import forestry.core.utils.BlockUtil; +import forestry.plugins.PluginArboriculture; + +public class FruitProviderPod extends FruitProviderNone { + + public static enum EnumPodType { + COCOA((short) 2000, (short) 2001, (short) 2002), DATES((short) 2010, (short) 2011, (short) 2012), + PAPAYA((short)2013, (short)2014, (short)2015);//, COCONUT((short)2016, (short)2017, (short)2018); + + public final short[] uids; + + private EnumPodType(short stage1, short stage2, short stage3) { + uids = new short[] { stage1, stage2, stage3 }; + } + } + + private static ItemStack[] DUMMY = new ItemStack[0]; + + private final EnumPodType type; + private final ItemStack[] drop; + + public FruitProviderPod(String key, IFruitFamily family, EnumPodType type, ItemStack... dropOnMature) { + super(key, family); + this.type = type; + this.drop = dropOnMature; + } + + @Override + public boolean requiresFruitBlocks() { + return true; + } + + @Override + public ItemStack[] getFruits(ITreeGenome genome, World world, int x, int y, int z, int ripeningTime) { + if (drop == null || drop.length == 0) + return DUMMY; + + if (ripeningTime >= 2) { + ItemStack[] dropping = new ItemStack[drop.length]; + for (int i = 0; i < drop.length; i++) + dropping[i] = drop[i].copy(); + return dropping; + } + + return DUMMY; + } + + @Override + public boolean trySpawnFruitBlock(ITreeGenome genome, World world, int x, int y, int z) { + + if (world.rand.nextFloat() > genome.getSappiness()) + return false; + + if (type == EnumPodType.COCOA) + return BlockUtil.tryPlantPot(world, x, y, z, Blocks.cocoa); + else { + return PluginArboriculture.treeInterface.setFruitBlock(world, (IAlleleFruit) genome.getActiveAllele(EnumTreeChromosome.FRUITS.ordinal()), + genome.getSappiness(), type.uids, x, y, z); + } + } + + @Override + public short getIconIndex(ITreeGenome genome, IBlockAccess world, int x, int y, int z, int ripeningTime, boolean fancy) { + return type.uids[0]; + } + + @Override + @SideOnly(Side.CLIENT) + public void registerIcons(IIconRegister register) { + if (type == EnumPodType.COCOA) + return; + + TextureManager.getInstance().registerTexUID(register, type.uids[0], "pods/" + type.toString().toLowerCase(Locale.ENGLISH) + ".0"); + TextureManager.getInstance().registerTexUID(register, type.uids[1], "pods/" + type.toString().toLowerCase(Locale.ENGLISH) + ".1"); + TextureManager.getInstance().registerTexUID(register, type.uids[2], "pods/" + type.toString().toLowerCase(Locale.ENGLISH) + ".2"); + } + +} diff --git a/forestry_common/arboriculture/forestry/arboriculture/FruitProviderRandom.java b/forestry_common/arboriculture/forestry/arboriculture/FruitProviderRandom.java new file mode 100755 index 000000000..d9b76d464 --- /dev/null +++ b/forestry_common/arboriculture/forestry/arboriculture/FruitProviderRandom.java @@ -0,0 +1,73 @@ +/******************************************************************************* + * Copyright 2011-2014 by SirSengir + * + * This work is licensed under a Creative Commons Attribution-NonCommercial-NoDerivs 3.0 Unported License. + * + * To view a copy of this license, visit http://creativecommons.org/licenses/by-nc-nd/3.0/. + ******************************************************************************/ +package forestry.arboriculture; + +import java.util.ArrayList; +import java.util.HashMap; +import java.util.Map; + +import net.minecraft.item.ItemStack; +import net.minecraft.world.IBlockAccess; +import net.minecraft.world.World; + +import forestry.api.arboriculture.ITreeGenome; +import forestry.api.genetics.IFruitFamily; +import forestry.plugins.PluginArboriculture; + +/** + * Simple fruit provider which drops from any leaf block according to yield and either marks all leave blocks as fruit leaves or none. + */ +public class FruitProviderRandom extends FruitProviderNone { + + HashMap products = new HashMap(); + int colour = 0xffffff; + + public FruitProviderRandom(String key, IFruitFamily family, ItemStack product, float modifier) { + super(key, family); + products.put(product, modifier); + } + + public FruitProviderRandom setColour(int colour) { + this.colour = colour; + return this; + } + + @Override + public int getColour(ITreeGenome genome, IBlockAccess world, int x, int y, int z, int ripeningTime) { + return colour; + } + + @Override + public ItemStack[] getFruits(ITreeGenome genome, World world, int x, int y, int z, int ripeningTime) { + ArrayList product = new ArrayList(); + + float modeYieldMod = PluginArboriculture.treeInterface.getTreekeepingMode(world).getYieldModifier(genome, 1f); + + for (Map.Entry entry : products.entrySet()) + if (world.rand.nextFloat() <= genome.getYield() * modeYieldMod * entry.getValue()) + product.add(entry.getKey().copy()); + + return product.toArray(new ItemStack[0]); + } + + @Override + public ItemStack[] getProducts() { + return products.keySet().toArray(new ItemStack[0]); + } + + @Override + public ItemStack[] getSpecialty() { + return new ItemStack[0]; + } + + @Override + public boolean markAsFruitLeaf(ITreeGenome genome, World world, int x, int y, int z) { + return true; + } + +} diff --git a/forestry_common/arboriculture/forestry/arboriculture/FruitProviderRipening.java b/forestry_common/arboriculture/forestry/arboriculture/FruitProviderRipening.java new file mode 100755 index 000000000..75dbf9e84 --- /dev/null +++ b/forestry_common/arboriculture/forestry/arboriculture/FruitProviderRipening.java @@ -0,0 +1,104 @@ +/******************************************************************************* + * Copyright 2011-2014 by SirSengir + * + * This work is licensed under a Creative Commons Attribution-NonCommercial-NoDerivs 3.0 Unported License. + * + * To view a copy of this license, visit http://creativecommons.org/licenses/by-nc-nd/3.0/. + ******************************************************************************/ +package forestry.arboriculture; + +import java.util.ArrayList; +import java.util.HashMap; +import java.util.Map; + +import net.minecraft.item.ItemStack; +import net.minecraft.world.IBlockAccess; +import net.minecraft.world.World; + +import forestry.api.arboriculture.ITreeGenome; +import forestry.api.genetics.IFruitFamily; +import forestry.plugins.PluginArboriculture; + +public class FruitProviderRipening extends FruitProviderNone { + + HashMap products = new HashMap(); + + int colourRipe = 0xffffff; + int colourCallow = 0xffffff; + + int diffR, diffG, diffB = 0; + + public FruitProviderRipening(String key, IFruitFamily family, ItemStack product, float modifier) { + super(key, family); + products.put(product, modifier); + } + + public FruitProviderRipening setColours(int ripe, int callow) { + colourRipe = ripe; + colourCallow = callow; + + diffR = (ripe >> 16 & 255) - (callow >> 16 & 255); + diffG = (ripe >> 8 & 255) - (callow >> 8 & 255); + diffB = (ripe & 255) - (callow & 255); + + return this; + } + + public FruitProviderRipening setRipeningPeriod(int period) { + ripeningPeriod = period; + return this; + } + + private float getRipeningStage(int ripeningTime) { + if (ripeningTime >= ripeningPeriod) + return 1.0f; + + return (float) ripeningTime / ripeningPeriod; + } + + @Override + public ItemStack[] getFruits(ITreeGenome genome, World world, int x, int y, int z, int ripeningTime) { + ArrayList product = new ArrayList(); + + float stage = getRipeningStage(ripeningTime); + if (stage < 0.5f) + return new ItemStack[0]; + + float modeYieldMod = PluginArboriculture.treeInterface.getTreekeepingMode(world).getYieldModifier(genome, 1f); + + for (Map.Entry entry : products.entrySet()) + if (world.rand.nextFloat() <= genome.getYield() * entry.getValue() * modeYieldMod * 5.0f * stage) + product.add(entry.getKey().copy()); + + return product.toArray(new ItemStack[0]); + } + + @Override + public ItemStack[] getProducts() { + return products.keySet().toArray(new ItemStack[0]); + } + + @Override + public ItemStack[] getSpecialty() { + return new ItemStack[0]; + } + + @Override + public boolean markAsFruitLeaf(ITreeGenome genome, World world, int x, int y, int z) { + return true; + } + + @Override + public int getColour(ITreeGenome genome, IBlockAccess world, int x, int y, int z, int ripeningTime) { + float stage = getRipeningStage(ripeningTime); + + int r = (colourCallow >> 16 & 255) + (int) (diffR * stage); + int g = (colourCallow >> 8 & 255) + (int) (diffG * stage); + int b = (colourCallow & 255) + (int) (diffB * stage); + + // System.out.println(String.format("Calcultated rgb %s/%s/%s from %s and %s, resulting in %s", + // r, g, b, colourCallow, stage, (r & 255) << 16 | (g & 255) << 8 | b & 255)); + return (r & 255) << 16 | (g & 255) << 8 | b & 255; + } + +} diff --git a/forestry_common/arboriculture/forestry/arboriculture/GuiHandlerArboriculture.java b/forestry_common/arboriculture/forestry/arboriculture/GuiHandlerArboriculture.java new file mode 100755 index 000000000..48e13daaf --- /dev/null +++ b/forestry_common/arboriculture/forestry/arboriculture/GuiHandlerArboriculture.java @@ -0,0 +1,74 @@ +/******************************************************************************* + * Copyright 2011-2014 by SirSengir + * + * This work is licensed under a Creative Commons Attribution-NonCommercial-NoDerivs 3.0 Unported License. + * + * To view a copy of this license, visit http://creativecommons.org/licenses/by-nc-nd/3.0/. + ******************************************************************************/ +package forestry.arboriculture; + +import net.minecraft.entity.player.EntityPlayer; +import net.minecraft.item.ItemStack; +import net.minecraft.world.World; + +import forestry.arboriculture.genetics.TreeHelper; +import forestry.arboriculture.gui.ContainerTreealyzer; +import forestry.arboriculture.gui.GuiTreealyzer; +import forestry.arboriculture.items.ItemTreealyzer.TreealyzerInventory; +import forestry.core.GuiHandlerBase; +import forestry.core.network.GuiId; + +public class GuiHandlerArboriculture extends GuiHandlerBase { + + @Override + public Object getServerGuiElement(int id, EntityPlayer player, World world, int x, int y, int z) { + int cleanId = decodeGuiID(id); + + if (cleanId >= GuiId.values().length) + return null; + + switch (GuiId.values()[cleanId]) { + + case ArboristChestGUI: + return this.getNaturalistChestContainer(TreeHelper.UID, player, world, x, y, z, decodeGuiData(id)); + + case TreealyzerGUI: + ItemStack equipped = getEquippedItem(player); + if (equipped == null) + return null; + + return new ContainerTreealyzer(player.inventory, new TreealyzerInventory(player, equipped)); + + default: + return null; + + } + + } + + @Override + public Object getClientGuiElement(int id, EntityPlayer player, World world, int x, int y, int z) { + int cleanId = decodeGuiID(id); + + if (cleanId >= GuiId.values().length) + return null; + + switch (GuiId.values()[cleanId]) { + + case ArboristChestGUI: + return this.getNaturalistChestGui(TreeHelper.UID, player, world, x, y, z, decodeGuiData(id)); + + case TreealyzerGUI: + ItemStack equipped = getEquippedItem(player); + if (equipped == null) + return null; + + return new GuiTreealyzer(player, new TreealyzerInventory(player, equipped)); + + default: + return null; + + } + + } +} diff --git a/forestry_common/arboriculture/forestry/arboriculture/IWoodTyped.java b/forestry_common/arboriculture/forestry/arboriculture/IWoodTyped.java new file mode 100755 index 000000000..dcfc0e454 --- /dev/null +++ b/forestry_common/arboriculture/forestry/arboriculture/IWoodTyped.java @@ -0,0 +1,14 @@ +/******************************************************************************* + * Copyright 2011-2014 by SirSengir + * + * This work is licensed under a Creative Commons Attribution-NonCommercial-NoDerivs 3.0 Unported License. + * + * To view a copy of this license, visit http://creativecommons.org/licenses/by-nc-nd/3.0/. + ******************************************************************************/ +package forestry.arboriculture; + +public interface IWoodTyped { + WoodType getWoodType(int meta); + + String getBlockKind(); +} diff --git a/forestry_common/arboriculture/forestry/arboriculture/PacketHandlerArboriculture.java b/forestry_common/arboriculture/forestry/arboriculture/PacketHandlerArboriculture.java new file mode 100755 index 000000000..1d09ff5a7 --- /dev/null +++ b/forestry_common/arboriculture/forestry/arboriculture/PacketHandlerArboriculture.java @@ -0,0 +1,50 @@ +/******************************************************************************* + * Copyright 2011-2014 by SirSengir + * + * This work is licensed under a Creative Commons Attribution-NonCommercial-NoDerivs 3.0 Unported License. + * + * To view a copy of this license, visit http://creativecommons.org/licenses/by-nc-nd/3.0/. + ******************************************************************************/ +package forestry.arboriculture; + +import java.io.DataInputStream; + +import net.minecraft.entity.player.EntityPlayer; +import net.minecraft.tileentity.TileEntity; + +import forestry.arboriculture.gadgets.TileLeaves; +import forestry.arboriculture.network.PacketLeafUpdate; +import forestry.core.interfaces.IPacketHandler; +import forestry.core.network.ILocatedPacket; +import forestry.core.network.PacketIds; +import forestry.core.proxy.Proxies; + +public class PacketHandlerArboriculture implements IPacketHandler { + + @Override + public void onPacketData(int packetID, DataInputStream data, EntityPlayer player) { + try { + + switch (packetID) { + case PacketIds.LEAF_UPDATE: + PacketLeafUpdate packet = new PacketLeafUpdate(); + packet.readData(data); + onLeafUpdate(packet); + break; + } + + } catch(Exception ex) { + ex.printStackTrace(); + } + } + + private void onLeafUpdate(PacketLeafUpdate packet) { + + TileEntity tile = ((ILocatedPacket) packet).getTarget(Proxies.common.getRenderWorld()); + if (tile instanceof TileLeaves) + ((TileLeaves) tile).fromPacket(packet); + + } + + +} diff --git a/forestry_common/arboriculture/forestry/arboriculture/VillageHandlerArboriculture.java b/forestry_common/arboriculture/forestry/arboriculture/VillageHandlerArboriculture.java new file mode 100755 index 000000000..251d94d81 --- /dev/null +++ b/forestry_common/arboriculture/forestry/arboriculture/VillageHandlerArboriculture.java @@ -0,0 +1,55 @@ +/******************************************************************************* + * Copyright 2011-2014 by SirSengir + * + * This work is licensed under a Creative Commons Attribution-NonCommercial-NoDerivs 3.0 Unported License. + * + * To view a copy of this license, visit http://creativecommons.org/licenses/by-nc-nd/3.0/. + ******************************************************************************/ +package forestry.arboriculture; + +import java.util.Random; + +import net.minecraft.block.Block; +import net.minecraft.entity.passive.EntityVillager; +import net.minecraft.init.Items; +import net.minecraft.item.ItemStack; +import net.minecraft.village.MerchantRecipe; +import net.minecraft.village.MerchantRecipeList; + +import cpw.mods.fml.common.registry.VillagerRegistry.IVillageTradeHandler; + +import forestry.api.arboriculture.EnumGermlingType; +import forestry.core.config.ForestryBlock; +import forestry.core.config.ForestryItem; +import forestry.plugins.PluginArboriculture; + +public class VillageHandlerArboriculture implements IVillageTradeHandler { + + @SuppressWarnings("unchecked") + @Override + public void manipulateTradesForVillager(EntityVillager villager, MerchantRecipeList recipeList, Random random) { + recipeList.add(new MerchantRecipe(new ItemStack(Items.emerald, 8), PluginArboriculture.treeInterface.getMemberStack( + PluginArboriculture.treeInterface.getTree(villager.worldObj, + PluginArboriculture.treeInterface.templateAsGenome(PluginArboriculture.treeInterface.getRandomTemplate(random))), + EnumGermlingType.SAPLING.ordinal()))); + + recipeList.add(new MerchantRecipe(new ItemStack(Items.emerald, 2), ForestryItem.grafterProven.getItemStack())); + + WoodType sells = WoodType.VALUES[random.nextInt(WoodType.VALUES.length)]; + Block plankBlock; + int meta; + if(!sells.hasPlank) { + plankBlock = ForestryBlock.planks1; + meta = 0; + } else if(sells.ordinal() > 15) { + plankBlock = ForestryBlock.planks2; + meta = sells.ordinal() - 16; + } else { + plankBlock = ForestryBlock.planks1; + meta = sells.ordinal(); + } + + recipeList.add(new MerchantRecipe(new ItemStack(Items.emerald, 1), new ItemStack(plankBlock, 32, meta))); + } + +} diff --git a/forestry_common/arboriculture/forestry/arboriculture/WoodType.java b/forestry_common/arboriculture/forestry/arboriculture/WoodType.java new file mode 100755 index 000000000..6f6f32476 --- /dev/null +++ b/forestry_common/arboriculture/forestry/arboriculture/WoodType.java @@ -0,0 +1,90 @@ +/******************************************************************************* + * Copyright 2011-2014 by SirSengir + * + * This work is licensed under a Creative Commons Attribution-NonCommercial-NoDerivs 3.0 Unported License. + * + * To view a copy of this license, visit http://creativecommons.org/licenses/by-nc-nd/3.0/. + ******************************************************************************/ +package forestry.arboriculture; + +import java.util.Locale; + +import net.minecraft.client.renderer.texture.IIconRegister; +import net.minecraft.nbt.NBTTagCompound; +import net.minecraft.util.IIcon; + +import cpw.mods.fml.relauncher.Side; +import cpw.mods.fml.relauncher.SideOnly; + +import forestry.core.render.TextureManager; + +public enum WoodType { + LARCH, TEAK, ACACIA, LIME, CHESTNUT, WENGE, BAOBAB, SEQUOIA(4.0f), KAPOK, EBONY, MAHOGANY, BALSA(1.0f), WILLOW, WALNUT, GREENHEART(7.5f), CHERRY, MAHOE, POPLAR, PALM, PAPAYA, PINE( + 3.0f), PLUM, MAPLE, CITRUS, GIGANTEUM(2.0f, false); + + public static final WoodType[] VALUES = values(); + private final float hardness; + public final boolean hasPlank; + + private WoodType() { + this(2.0f, true); + } + + private WoodType(float hardness) { + this(hardness, true); + } + + private WoodType(float hardness, boolean hasPlank) { + this.hardness = hardness; + this.hasPlank = hasPlank; + } + + @SideOnly(Side.CLIENT) + private static IIcon[][] icons; + + @SideOnly(Side.CLIENT) + public static void registerIcons(IIconRegister register) { + icons = new IIcon[3][VALUES.length]; + for (int i = 0; i < VALUES.length; i++) + icons[0][i] = TextureManager.getInstance().registerTex(register, "wood/planks." + VALUES[i].toString().toLowerCase(Locale.ENGLISH)); + for (int i = 0; i < VALUES.length; i++) + icons[1][i] = TextureManager.getInstance().registerTex(register, "wood/bark." + VALUES[i].toString().toLowerCase(Locale.ENGLISH)); + for (int i = 0; i < VALUES.length; i++) + icons[2][i] = TextureManager.getInstance().registerTex(register, "wood/heart." + VALUES[i].toString().toLowerCase(Locale.ENGLISH)); + } + + @SideOnly(Side.CLIENT) + public IIcon getPlankIcon() { + return icons[0][ordinal()]; + } + + @SideOnly(Side.CLIENT) + public IIcon getBarkIcon() { + return icons[1][ordinal()]; + } + + @SideOnly(Side.CLIENT) + public IIcon getHeartIcon() { + return icons[2][ordinal()]; + } + + public float getHardness() { + return hardness; + } + + public void saveToCompound(NBTTagCompound compound) { + compound.setInteger("WoodType", this.ordinal()); + } + + public static WoodType getFromCompound(NBTTagCompound compound) { + + if (compound != null) { + int typeOrdinal = compound.getInteger("WoodType"); + if (typeOrdinal < WoodType.VALUES.length) + return WoodType.VALUES[typeOrdinal]; + } + + return WoodType.LARCH; + } + +} diff --git a/forestry_common/arboriculture/forestry/arboriculture/WorldGenHelper.java b/forestry_common/arboriculture/forestry/arboriculture/WorldGenHelper.java new file mode 100755 index 000000000..fc5e97c91 --- /dev/null +++ b/forestry_common/arboriculture/forestry/arboriculture/WorldGenHelper.java @@ -0,0 +1,34 @@ +/******************************************************************************* + * Copyright 2011-2014 by SirSengir + * + * This work is licensed under a Creative Commons Attribution-NonCommercial-NoDerivs 3.0 Unported License. + * + * To view a copy of this license, visit http://creativecommons.org/licenses/by-nc-nd/3.0/. + ******************************************************************************/ +package forestry.arboriculture; + +import java.util.ArrayList; + +import net.minecraft.world.gen.feature.WorldGenerator; + +import forestry.api.arboriculture.ITree; +import forestry.api.genetics.IIndividual; +import forestry.api.world.IWorldGenInterface; +import forestry.plugins.PluginArboriculture; + +public class WorldGenHelper implements IWorldGenInterface { + + @SuppressWarnings("unchecked") + @Override + public Class[] getTreeGenerators(String ident) { + + ArrayList> generators = new ArrayList>(); + for (IIndividual tree : PluginArboriculture.treeInterface.getIndividualTemplates()) + if (tree.getIdent().equals(ident)) + for (Class generator : ((ITree)tree).getGenome().getPrimary().getGeneratorClasses()) + generators.add(generator); + + return generators.toArray(new Class[0]); + } + +} diff --git a/forestry_common/arboriculture/forestry/arboriculture/gadgets/BlockArbFence.java b/forestry_common/arboriculture/forestry/arboriculture/gadgets/BlockArbFence.java new file mode 100755 index 000000000..31d2fdd23 --- /dev/null +++ b/forestry_common/arboriculture/forestry/arboriculture/gadgets/BlockArbFence.java @@ -0,0 +1,136 @@ +/******************************************************************************* + * Copyright 2011-2014 by SirSengir + * + * This work is licensed under a Creative Commons Attribution-NonCommercial-NoDerivs 3.0 Unported License. + * + * To view a copy of this license, visit http://creativecommons.org/licenses/by-nc-nd/3.0/. + ******************************************************************************/ +package forestry.arboriculture.gadgets; + +import java.util.List; + +import net.minecraft.block.Block; +import net.minecraft.block.BlockFence; +import net.minecraft.block.material.Material; +import net.minecraft.client.renderer.texture.IIconRegister; +import net.minecraft.creativetab.CreativeTabs; +import net.minecraft.item.Item; +import net.minecraft.item.ItemStack; +import net.minecraft.util.IIcon; +import net.minecraft.world.IBlockAccess; +import net.minecraft.world.World; + +import cpw.mods.fml.relauncher.Side; +import cpw.mods.fml.relauncher.SideOnly; + +import net.minecraftforge.common.util.ForgeDirection; + +import forestry.api.core.Tabs; +import forestry.arboriculture.IWoodTyped; +import forestry.arboriculture.WoodType; +import forestry.plugins.PluginArboriculture; + +public class BlockArbFence extends BlockFence implements IWoodTyped { + + public static enum FenceCat { + CAT0, CAT1 + } + + private final FenceCat cat; + + public BlockArbFence(FenceCat cat) { + super("", Material.wood); + this.cat = cat; + setHardness(2.0F); + setResistance(5.0F); + setStepSound(soundTypeWood); + setCreativeTab(Tabs.tabArboriculture); + } + + @SuppressWarnings({ "rawtypes", "unchecked" }) + @Override + public void getSubBlocks(Item item, CreativeTabs par2CreativeTabs, List itemList) { + int count = (cat == FenceCat.CAT0 ? 16 : 8); + for (int i = 0; i < count; i++) + itemList.add(new ItemStack(this, 1, i)); + } + + @Override + public int damageDropped(int meta) { + return meta; + } + + @Override + public boolean canPlaceTorchOnTop(World world, int x, int y, int z) { + return true; + } + + @Override + public boolean canConnectFenceTo(IBlockAccess world, int x, int y, int z) { + if (!isFence(world, x, y, z)) { + Block block = world.getBlock(x, y, z); + return block != null && block.getMaterial().isOpaque() && block.renderAsNormalBlock() ? block.getMaterial() != Material.gourd : false; + } else + return true; + } + + @Override + public int getRenderType() { + return PluginArboriculture.modelIdFences; + } + + /* ICONS */ + @SideOnly(Side.CLIENT) + @Override + public void registerBlockIcons(IIconRegister register) { + WoodType.registerIcons(register); + } + + @SideOnly(Side.CLIENT) + @Override + public IIcon getIcon(int side, int meta) { + return getWoodType(meta).getPlankIcon(); + } + + public boolean isFence(IBlockAccess world, int x, int y, int z) { + Block block = world.getBlock(x, y, z); + if (PluginArboriculture.validFences.contains(block)) + return true; + + return false; + } + + /* PROPERTIES */ + @Override + public boolean isWood(IBlockAccess world, int x, int y, int z) { + return true; + } + + @Override + public int getFlammability(IBlockAccess world, int x, int y, int z, ForgeDirection face) { + return 20; + } + + @Override + public boolean isFlammable(IBlockAccess world, int x, int y, int z, ForgeDirection face) { + return true; + } + + @Override + public int getFireSpreadSpeed(IBlockAccess world, int x, int y, int z, ForgeDirection face) { + return 5; + } + + @Override + public WoodType getWoodType(int meta) { + if(cat.ordinal() * 16 + meta < WoodType.VALUES.length) + return WoodType.VALUES[cat.ordinal() * 16 + meta]; + else + return WoodType.LARCH; + } + + @Override + public String getBlockKind() { + return "fences"; + } +} diff --git a/forestry_common/arboriculture/forestry/arboriculture/gadgets/BlockArbStairs.java b/forestry_common/arboriculture/forestry/arboriculture/gadgets/BlockArbStairs.java new file mode 100755 index 000000000..8a45dcf9a --- /dev/null +++ b/forestry_common/arboriculture/forestry/arboriculture/gadgets/BlockArbStairs.java @@ -0,0 +1,130 @@ +/******************************************************************************* + * Copyright 2011-2014 by SirSengir + * + * This work is licensed under a Creative Commons Attribution-NonCommercial-NoDerivs 3.0 Unported License. + * + * To view a copy of this license, visit http://creativecommons.org/licenses/by-nc-nd/3.0/. + ******************************************************************************/ +package forestry.arboriculture.gadgets; + +import java.util.ArrayList; +import java.util.List; + +import net.minecraft.block.Block; +import net.minecraft.block.BlockStairs; +import net.minecraft.client.renderer.texture.IIconRegister; +import net.minecraft.creativetab.CreativeTabs; +import net.minecraft.entity.player.EntityPlayer; +import net.minecraft.item.Item; +import net.minecraft.item.ItemStack; +import net.minecraft.nbt.NBTTagCompound; +import net.minecraft.tileentity.TileEntity; +import net.minecraft.util.IIcon; +import net.minecraft.world.IBlockAccess; +import net.minecraft.world.World; + +import cpw.mods.fml.relauncher.Side; +import cpw.mods.fml.relauncher.SideOnly; + +import forestry.api.core.Tabs; +import forestry.arboriculture.WoodType; +import forestry.core.proxy.Proxies; +import forestry.core.utils.StackUtils; + +public class BlockArbStairs extends BlockStairs { + + public BlockArbStairs(Block par2Block, int par3) { + super(par2Block, par3); + setCreativeTab(Tabs.tabArboriculture); + setHardness(2.0F); + setResistance(5.0F); + } + + public static TileStairs getStairTile(IBlockAccess world, int x, int y, int z) { + TileEntity tile = world.getTileEntity(x, y, z); + if (!(tile instanceof TileStairs)) + return null; + + return (TileStairs) tile; + } + + @SuppressWarnings({ "rawtypes", "unchecked" }) + @Override + @SideOnly(Side.CLIENT) + public void getSubBlocks(Item item, CreativeTabs tab, List list) { + for (WoodType type : WoodType.VALUES) { + if(!type.hasPlank) + continue; + ItemStack stack = new ItemStack(item, 1, 0); + NBTTagCompound compound = new NBTTagCompound(); + type.saveToCompound(compound); + stack.setTagCompound(compound); + list.add(stack); + } + } + + @Override + public boolean removedByPlayer(World world, EntityPlayer player, int x, int y, int z) { + int meta = world.getBlockMetadata(x, y, z); + if (Proxies.common.isSimulating(world) && canHarvestBlock(player, meta)) + if (!player.capabilities.isCreativeMode) { + // Handle TE'd beehives + TileEntity tile = world.getTileEntity(x, y, z); + + if (tile instanceof TileStairs) { + TileStairs stairs = (TileStairs) tile; + + ItemStack stack = new ItemStack(this, 1, 0); + NBTTagCompound compound = new NBTTagCompound(); + stairs.getType().saveToCompound(compound); + stack.setTagCompound(compound); + StackUtils.dropItemStackAsEntity(stack, world, x, y, z); + } + } + + return world.setBlockToAir(x, y, z); + } + + @Override + public void breakBlock(World world, int x, int y, int z, Block block, int meta) { + world.removeTileEntity(x, y, z); + super.breakBlock(world, x, y, z, block, meta); + } + + @Override + public ArrayList getDrops(World world, int x, int y, int z, int metadata, int fortune) { + return new ArrayList(); + } + + @Override + public boolean hasTileEntity(int meta) { + return true; + } + + @Override + public TileEntity createTileEntity(World world, int meta) { + return new TileStairs(); + } + + /* ICONS */ + @SideOnly(Side.CLIENT) + @Override + public void registerBlockIcons(IIconRegister register) { + WoodType.registerIcons(register); + } + + @SideOnly(Side.CLIENT) + @Override + public IIcon getIcon(IBlockAccess world, int x, int y, int z, int side) { + TileStairs stairs = getStairTile(world, x, y, z); + if (stairs != null && stairs.getType() != null) + return stairs.getType().getPlankIcon(); + else + return WoodType.LARCH.getPlankIcon(); + } + + @Override + public boolean getUseNeighborBrightness() { + return true; + } +} diff --git a/forestry_common/arboriculture/forestry/arboriculture/gadgets/BlockFruitPod.java b/forestry_common/arboriculture/forestry/arboriculture/gadgets/BlockFruitPod.java new file mode 100755 index 000000000..502748fa5 --- /dev/null +++ b/forestry_common/arboriculture/forestry/arboriculture/gadgets/BlockFruitPod.java @@ -0,0 +1,136 @@ +/******************************************************************************* + * Copyright 2011-2014 by SirSengir + * + * This work is licensed under a Creative Commons Attribution-NonCommercial-NoDerivs 3.0 Unported License. + * + * To view a copy of this license, visit http://creativecommons.org/licenses/by-nc-nd/3.0/. + ******************************************************************************/ +package forestry.arboriculture.gadgets; + +import java.util.ArrayList; +import java.util.Random; + +import net.minecraft.block.Block; +import net.minecraft.block.BlockCocoa; +import net.minecraft.client.renderer.texture.IIconRegister; +import net.minecraft.entity.player.EntityPlayer; +import net.minecraft.item.ItemStack; +import net.minecraft.tileentity.TileEntity; +import net.minecraft.util.IIcon; +import net.minecraft.world.IBlockAccess; +import net.minecraft.world.World; + +import cpw.mods.fml.relauncher.Side; +import cpw.mods.fml.relauncher.SideOnly; + +import forestry.core.proxy.Proxies; +import forestry.core.render.TextureManager; +import forestry.core.utils.BlockUtil; +import forestry.core.utils.StackUtils; +import forestry.plugins.PluginArboriculture; + +public class BlockFruitPod extends BlockCocoa { + + public BlockFruitPod() { + super(); + } + + public static TileFruitPod getPodTile(IBlockAccess world, int x, int y, int z) { + TileEntity tile = world.getTileEntity(x, y, z); + if (!(tile instanceof TileFruitPod)) + return null; + + return (TileFruitPod) tile; + } + + @Override + public void updateTick(World world, int x, int y, int z, Random rand) { + + if (!canBlockStay(world, x, y, z)) { + dropBlockAsItem(world, x, y, z, world.getBlockMetadata(x, y, z), 0); + world.setBlockToAir(x, y, z); + return; + } + + TileFruitPod tile = getPodTile(world, x, y, z); + if (tile == null) + return; + + tile.onBlockTick(); + } + + @Override + public boolean removedByPlayer(World world, EntityPlayer player, int x, int y, int z) { + if(Proxies.common.isSimulating(world)) { + TileFruitPod tile = getPodTile(world, x, y, z); + if (tile != null) { + for(ItemStack drop : tile.getDrop()) { + StackUtils.dropItemStackAsEntity(drop, world, x, y, z); + } + } + } + + return super.removedByPlayer(world, player, x, y, z); + } + + @Override + public ArrayList getDrops(World world, int x, int y, int z, int metadata, int fortune) { + return new ArrayList(); + } + + @Override + public boolean canBlockStay(World world, int x, int y, int z) { + return BlockUtil.getDirectionalMetadata(world, x, y, z) >= 0; + } + + @Override + public void breakBlock(World world, int x, int y, int z, Block block, int meta) { + world.removeTileEntity(x, y, z); + super.breakBlock(world, x, y, z, block, meta); + } + + @Override + public boolean hasTileEntity(int meta) { + return true; + } + + @Override + public TileEntity createTileEntity(World world, int meta) { + return new TileFruitPod(); + } + + /* ICONS */ + @SideOnly(Side.CLIENT) + private static IIcon defaultIcon; + + @SideOnly(Side.CLIENT) + @Override + public void registerBlockIcons(IIconRegister register) { + defaultIcon = TextureManager.getInstance().registerTex(register, "pods/papaya.2"); + } + + @SideOnly(Side.CLIENT) + @Override + public IIcon getIcon(int par1, int par2) { + return defaultIcon; + } + + @SideOnly(Side.CLIENT) + @Override + public IIcon getIcon(IBlockAccess world, int x, int y, int z, int side) { + TileFruitPod pod = getPodTile(world, x, y, z); + if (pod != null) { + IIcon podIcon = pod.getIcon(world.getBlockMetadata(x, y, z), side); + if (podIcon != null) + return podIcon; + } + + return defaultIcon; + } + + @Override + public int getRenderType() { + return PluginArboriculture.modelIdPods; + } + +} diff --git a/forestry_common/arboriculture/forestry/arboriculture/gadgets/BlockLeaves.java b/forestry_common/arboriculture/forestry/arboriculture/gadgets/BlockLeaves.java new file mode 100755 index 000000000..a92e92855 --- /dev/null +++ b/forestry_common/arboriculture/forestry/arboriculture/gadgets/BlockLeaves.java @@ -0,0 +1,334 @@ +/******************************************************************************* + * Copyright 2011-2014 by SirSengir + * + * This work is licensed under a Creative Commons Attribution-NonCommercial-NoDerivs 3.0 Unported License. + * + * To view a copy of this license, visit http://creativecommons.org/licenses/by-nc-nd/3.0/. + ******************************************************************************/ +package forestry.arboriculture.gadgets; + +import java.util.ArrayList; +import java.util.Random; + +import net.minecraft.block.Block; +import net.minecraft.block.material.Material; +import net.minecraft.client.renderer.texture.IIconRegister; +import net.minecraft.entity.player.EntityPlayer; +import net.minecraft.item.ItemStack; +import net.minecraft.tileentity.TileEntity; +import net.minecraft.util.IIcon; +import net.minecraft.world.ColorizerFoliage; +import net.minecraft.world.IBlockAccess; +import net.minecraft.world.World; + +import cpw.mods.fml.relauncher.Side; +import cpw.mods.fml.relauncher.SideOnly; + +import net.minecraftforge.common.util.ForgeDirection; + +import forestry.api.arboriculture.EnumGermlingType; +import forestry.api.arboriculture.IToolGrafter; +import forestry.api.arboriculture.ITree; +import forestry.api.core.IToolScoop; +import forestry.api.lepidopterology.EnumFlutterType; +import forestry.api.lepidopterology.IButterfly; +import forestry.core.config.Defaults; +import forestry.core.proxy.Proxies; +import forestry.core.render.TextureManager; +import forestry.core.utils.StackUtils; +import forestry.plugins.PluginArboriculture; +import forestry.plugins.PluginLepidopterology; + +public class BlockLeaves extends BlockTreeContainer { + + int[] adjacentTreeBlocks; + + public BlockLeaves() { + super(Material.leaves); + this.setTickRandomly(true); + this.setHardness(0.2F); + this.setLightOpacity(1); + this.setStepSound(soundTypeGrass); + } + + public static TileLeaves getLeafTile(IBlockAccess world, int x, int y, int z) { + TileEntity tile = world.getTileEntity(x, y, z); + if (!(tile instanceof TileLeaves)) + return null; + + return (TileLeaves) tile; + } + + @Override + public TileEntity createNewTileEntity(World world, int meta) { + return new TileLeaves(); + } + + /* DROP HANDLING */ + @Override + public boolean removedByPlayer(World world, EntityPlayer player, int x, int y, int z) { + int metadata = world.getBlockMetadata(x, y, z); + + if (Proxies.common.isSimulating(world) && canHarvestBlock(player, metadata)) { + + ItemStack held = player.inventory.getCurrentItem(); + if (held != null && held.getItem() instanceof IToolGrafter) { + float saplingModifier = 1.0f; + saplingModifier = ((IToolGrafter) held.getItem()).getSaplingModifier(held, world, player, x, y, z); + held.damageItem(1, player); + if(held.stackSize <= 0) + player.destroyCurrentEquippedItem(); + + spawnLeafDrops(world, x, y, z, metadata, saplingModifier, false); + } + } + + return world.setBlockToAir(x, y, z); + } + + @Override + public void breakBlock(World world, int x, int y, int z, Block block, int metadata) { + + byte offset = 1; + int shift = offset + 1; + + if (world.checkChunksExist(x - shift, y - shift, z - shift, x + shift, y + shift, z + shift)) + for (int i = -offset; i <= offset; ++i) + for (int j = -offset; j <= offset; ++j) + for (int k = -offset; k <= offset; ++k) { + Block neighborBlock = world.getBlock(x + i, y + j, z + k); + neighborBlock.beginLeavesDecay(world, x + i, y + j, z + k); + } + + spawnLeafDrops(world, x, y, z, metadata, 1.0f, true); + super.breakBlock(world, x, y, z, block, metadata); + } + + @Override + public ArrayList getDrops(World world, int x, int y, int z, int metadata, int fortune) { + return StackUtils.EMPTY_STACK_LIST; + } + + private void removeLeaves(World world, int x, int y, int z) { + this.spawnLeafDrops(world, x, y, z, world.getBlockMetadata(x, y, z), 1.0f, true); + world.setBlockToAir(x, y, z); + } + + private void spawnLeafDrops(World world, int x, int y, int z, int metadata, float saplingModifier, boolean doFruitDrop) { + for (ItemStack drop : getLeafDrop(world, x, y, z, metadata, saplingModifier, doFruitDrop)) + if (drop != null) + StackUtils.dropItemStackAsEntity(drop, world, x, y, z); + } + + private ArrayList getLeafDrop(World world, int x, int y, int z, int metadata, float saplingModifier, boolean doFruitDrop) { + ArrayList prod = new ArrayList(); + + TileLeaves tile = getLeafTile(world, x, y, z); + if (tile == null) + return prod; + + if (tile.getTree() == null) + return prod; + + // Add saplings + ITree[] saplings = tile.getTree().getSaplings(world, x, y, z, saplingModifier); + for (ITree sapling : saplings) + if (sapling != null) + prod.add(PluginArboriculture.treeInterface.getMemberStack(sapling, EnumGermlingType.SAPLING.ordinal())); + + // Add fruits + if (doFruitDrop && tile.hasFruit()) + for (ItemStack stack : tile.getTree().produceStacks(world, x, y, z, tile.getRipeningTime())) + prod.add(stack); + + return prod; + } + + /* RENDERING */ + @Override + public boolean isOpaqueCube() { + return !Proxies.render.fancyGraphicsEnabled(); + } + + @Override + public int getRenderType() { + return PluginArboriculture.modelIdLeaves; + } + + @Override + @SideOnly(Side.CLIENT) + public int getBlockColor() { + double var1 = 0.5D; + double var3 = 1.0D; + return ColorizerFoliage.getFoliageColor(var1, var3); + } + + @Override + @SideOnly(Side.CLIENT) + public int colorMultiplier(IBlockAccess world, int x, int y, int z) { + + TileLeaves leaves = getLeafTile(world, x, y, z); + if (leaves == null) + return ColorizerFoliage.getFoliageColorBasic(); + + int colour = leaves.getFoliageColour(Proxies.common.getClientInstance().thePlayer); + if (colour == PluginArboriculture.proxy.getFoliageColorBasic()) + colour = world.getBiomeGenForCoords(x, z).getBiomeFoliageColor(x, y, z); // TODO: vanilla uses a more elaborate color query + + return colour; + } + + /* ICONS */ + @SideOnly(Side.CLIENT) + private static IIcon defaultIcon; + + @SideOnly(Side.CLIENT) + @Override + public void registerBlockIcons(IIconRegister register) { + defaultIcon = TextureManager.getInstance().registerTex(register, "leaves/deciduous.fancy"); + } + + @SideOnly(Side.CLIENT) + @Override + public IIcon getIcon(int side, int metadata) { + return defaultIcon; + } + + @SideOnly(Side.CLIENT) + @Override + public IIcon getIcon(IBlockAccess world, int x, int y, int z, int side) { + TileLeaves leaves = getLeafTile(world, x, y, z); + if (leaves != null) + return leaves.getIcon(Proxies.render.fancyGraphicsEnabled()); + + return defaultIcon; + } + + /* BREAKING, LEAF DECAY */ + @Override + public void updateTick(World world, int x, int y, int z, Random random) { + + super.updateTick(world, x, y, z, random); + if (!Proxies.common.isSimulating(world)) + return; + + int meta = world.getBlockMetadata(x, y, z); + + if ((meta & 8) != 0 && (meta & 4) == 0) { + byte offset = 4; + int shift = offset + 1; + byte var9 = 32; + int var10 = var9 * var9; + int var11 = var9 / 2; + + if (this.adjacentTreeBlocks == null) + this.adjacentTreeBlocks = new int[var9 * var9 * var9]; + + int var12; + + if (world.checkChunksExist(x - shift, y - shift, z - shift, x + shift, y + shift, z + shift)) { + + int var13; + int var14; + int var15; + + for (var12 = -offset; var12 <= offset; ++var12) + for (var13 = -offset; var13 <= offset; ++var13) + for (var14 = -offset; var14 <= offset; ++var14) { + Block block = world.getBlock(x + var12, y + var13, z + var14); + + if (block.canSustainLeaves(world, x + var12, y + var13, z + var14)) + this.adjacentTreeBlocks[(var12 + var11) * var10 + (var13 + var11) * var9 + var14 + var11] = 0; + else if (block.isLeaves(world, x + var12, y + var13, z + var14)) + this.adjacentTreeBlocks[(var12 + var11) * var10 + (var13 + var11) * var9 + var14 + var11] = -2; + else + this.adjacentTreeBlocks[(var12 + var11) * var10 + (var13 + var11) * var9 + var14 + var11] = -1; + } + + for (var12 = 1; var12 <= 4; ++var12) + for (var13 = -offset; var13 <= offset; ++var13) + for (var14 = -offset; var14 <= offset; ++var14) + for (var15 = -offset; var15 <= offset; ++var15) + if (this.adjacentTreeBlocks[(var13 + var11) * var10 + (var14 + var11) * var9 + var15 + var11] == var12 - 1) { + + if (this.adjacentTreeBlocks[(var13 + var11 - 1) * var10 + (var14 + var11) * var9 + var15 + var11] == -2) + this.adjacentTreeBlocks[(var13 + var11 - 1) * var10 + (var14 + var11) * var9 + var15 + var11] = var12; + + if (this.adjacentTreeBlocks[(var13 + var11 + 1) * var10 + (var14 + var11) * var9 + var15 + var11] == -2) + this.adjacentTreeBlocks[(var13 + var11 + 1) * var10 + (var14 + var11) * var9 + var15 + var11] = var12; + + if (this.adjacentTreeBlocks[(var13 + var11) * var10 + (var14 + var11 - 1) * var9 + var15 + var11] == -2) + this.adjacentTreeBlocks[(var13 + var11) * var10 + (var14 + var11 - 1) * var9 + var15 + var11] = var12; + + if (this.adjacentTreeBlocks[(var13 + var11) * var10 + (var14 + var11 + 1) * var9 + var15 + var11] == -2) + this.adjacentTreeBlocks[(var13 + var11) * var10 + (var14 + var11 + 1) * var9 + var15 + var11] = var12; + + if (this.adjacentTreeBlocks[(var13 + var11) * var10 + (var14 + var11) * var9 + (var15 + var11 - 1)] == -2) + this.adjacentTreeBlocks[(var13 + var11) * var10 + (var14 + var11) * var9 + (var15 + var11 - 1)] = var12; + + if (this.adjacentTreeBlocks[(var13 + var11) * var10 + (var14 + var11) * var9 + var15 + var11 + 1] == -2) + this.adjacentTreeBlocks[(var13 + var11) * var10 + (var14 + var11) * var9 + var15 + var11 + 1] = var12; + } + } + + var12 = this.adjacentTreeBlocks[var11 * var10 + var11 * var9 + var11]; + + if (var12 >= 0) + world.setBlockMetadataWithNotify(x, y, z, meta & -9, Defaults.FLAG_BLOCK_SYNCH); + else + this.removeLeaves(world, x, y, z); + } + } + + @Override + public void beginLeavesDecay(World world, int x, int y, int z) { + world.setBlockMetadataWithNotify(x, y, z, world.getBlockMetadata(x, y, z) | 8, Defaults.FLAG_BLOCK_SYNCH); + } + + /* PROPERTIES */ + @Override + public int getFlammability(IBlockAccess world, int x, int y, int z, ForgeDirection face) { + return 60; + } + + @Override + public boolean isFlammable(IBlockAccess world, int x, int y, int z, ForgeDirection face) { + return true; + } + + @Override + public int getFireSpreadSpeed(IBlockAccess world, int x, int y, int z, ForgeDirection face) { + if (face == ForgeDirection.DOWN) + return 20; + else if (face != ForgeDirection.UP) + return 10; + else + return 5; + } + + @Override + public boolean isLeaves(IBlockAccess world, int x, int y, int z) { + return true; + } + + @Override + public boolean onBlockActivated(World world, int x, int y, + int z, EntityPlayer player, int par6, float par7, + float par8, float par9) { + + ItemStack heldItem = player.getHeldItem(); + TileEntity tile = world.getTileEntity(x, y, z); + IButterfly caterpillar = tile instanceof TileLeaves ? ((TileLeaves) tile).getCaterpillar() : null; + if(heldItem != null && heldItem.getItem() instanceof IToolScoop + && caterpillar != null) { + StackUtils.dropItemStackAsEntity(PluginLepidopterology.butterflyInterface.getMemberStack(caterpillar, EnumFlutterType.CATERPILLAR.ordinal()), + world, x, y, z); + ((TileLeaves) tile).setCaterpillar(null); + return true; + } + + return super.onBlockActivated(world, x, y, z, player, + par6, par7, par8, par9); + } + +} diff --git a/forestry_common/arboriculture/forestry/arboriculture/gadgets/BlockLog.java b/forestry_common/arboriculture/forestry/arboriculture/gadgets/BlockLog.java new file mode 100755 index 000000000..c9a7c6dcf --- /dev/null +++ b/forestry_common/arboriculture/forestry/arboriculture/gadgets/BlockLog.java @@ -0,0 +1,203 @@ +/******************************************************************************* + * Copyright 2011-2014 by SirSengir + * + * This work is licensed under a Creative Commons Attribution-NonCommercial-NoDerivs 3.0 Unported License. + * + * To view a copy of this license, visit http://creativecommons.org/licenses/by-nc-nd/3.0/. + ******************************************************************************/ +package forestry.arboriculture.gadgets; + +import java.util.List; + +import net.minecraft.block.Block; +import net.minecraft.block.material.Material; +import net.minecraft.client.renderer.texture.IIconRegister; +import net.minecraft.creativetab.CreativeTabs; +import net.minecraft.init.Blocks; +import net.minecraft.item.Item; +import net.minecraft.item.ItemStack; +import net.minecraft.util.IIcon; +import net.minecraft.world.IBlockAccess; +import net.minecraft.world.World; + +import cpw.mods.fml.relauncher.Side; +import cpw.mods.fml.relauncher.SideOnly; + +import net.minecraftforge.common.util.ForgeDirection; + +import forestry.api.core.Tabs; +import forestry.arboriculture.IWoodTyped; +import forestry.arboriculture.WoodType; + +public class BlockLog extends Block implements IWoodTyped { + + public enum LogCat { + CAT0, CAT1, CAT2, CAT3, CAT4, CAT5, CAT6, CAT7 + } + + private final LogCat cat; + + public BlockLog(LogCat cat) { + + super(Material.wood); + this.cat = cat; + + setHardness(2.0F); + setResistance(5.0F); + setStepSound(soundTypeWood); + setCreativeTab(Tabs.tabArboriculture); + + } + + public static int getTypeFromMeta(int damage) { + return damage & 3; + } + + @Override + public int getRenderType() { + return Blocks.log.getRenderType(); + } + + @Override + public void breakBlock(World world, int x, int y, int z, Block block, int meta) { + + byte radius = 4; + int boundary = radius + 1; + + if (world.checkChunksExist(x - boundary, y - boundary, z - boundary, x + boundary, y + boundary, z + boundary)) + for (int i = -radius; i <= radius; ++i) + for (int j = -radius; j <= radius; ++j) + for (int k = -radius; k <= radius; ++k) { + Block neighbor = world.getBlock(x + i, y + j, z + k); + + neighbor.beginLeavesDecay(world, x + i, y + j, z + k); + } + } + + @Override + public int onBlockPlaced(World world, int x, int y, int z, int side, float par6, float par7, float par8, int meta) { + int type = getTypeFromMeta(meta); + byte b0 = 0; + + switch (side) { + case 0: + case 1: + b0 = 0; + break; + case 2: + case 3: + b0 = 8; + break; + case 4: + case 5: + b0 = 4; + } + + return type | b0; + } + + @SuppressWarnings({ "rawtypes", "unchecked" }) + @Override + public void getSubBlocks(Item item, CreativeTabs par2CreativeTabs, List itemList) { + if(cat == LogCat.CAT6) { + return; + } + + for (int i = 0; i < 4; i++) + itemList.add(new ItemStack(this, 1, i)); + } + + /* ICONS */ + @SideOnly(Side.CLIENT) + @Override + public void registerBlockIcons(IIconRegister register) { + WoodType.registerIcons(register); + } + + @Override + @SideOnly(Side.CLIENT) + public IIcon getIcon(int side, int meta) { + + int oriented = meta & 12; + + WoodType type = getWoodType(getTypeFromMeta(meta)); + switch (oriented) { + case 4: + if (side > 3) + return type.getHeartIcon(); + else + return type.getBarkIcon(); + case 8: + if (side == 2 || side == 3) + return type.getHeartIcon(); + else + return type.getBarkIcon(); + case 0: + default: + if (side < 2) + return type.getHeartIcon(); + else + return type.getBarkIcon(); + } + } + + @Override + public int damageDropped(int meta) { + return getTypeFromMeta(meta); + } + + @Override + protected ItemStack createStackedBlock(int meta) { + return new ItemStack(this, 1, getTypeFromMeta(meta)); + } + + /* PROPERTIES */ + @Override + public float getBlockHardness(World world, int x, int y, int z) { + return getWoodType(getTypeFromMeta(world.getBlockMetadata(x, y, z))).getHardness(); + } + + @Override + public int getFlammability(IBlockAccess world, int x, int y, int z, ForgeDirection face) { + return 20; + } + + @Override + public boolean isFlammable(IBlockAccess world, int x, int y, int z, ForgeDirection face) { + return true; + } + + @Override + public int getFireSpreadSpeed(IBlockAccess world, int x, int y, int z, ForgeDirection face) { + if (face == ForgeDirection.DOWN) + return 20; + else if (face != ForgeDirection.UP) + return 10; + else + return 5; + } + + @Override + public boolean canSustainLeaves(IBlockAccess world, int x, int y, int z) { + return true; + } + + @Override + public boolean isWood(IBlockAccess world, int x, int y, int z) { + return true; + } + + @Override + public WoodType getWoodType(int meta) { + if(meta + cat.ordinal() * 4 < WoodType.VALUES.length) + return WoodType.VALUES[meta + cat.ordinal() * 4]; + else + return WoodType.LARCH; + } + + @Override + public String getBlockKind() { + return "log"; + } + +} diff --git a/forestry_common/arboriculture/forestry/arboriculture/gadgets/BlockPlanks.java b/forestry_common/arboriculture/forestry/arboriculture/gadgets/BlockPlanks.java new file mode 100755 index 000000000..7d7c0cf67 --- /dev/null +++ b/forestry_common/arboriculture/forestry/arboriculture/gadgets/BlockPlanks.java @@ -0,0 +1,111 @@ +/******************************************************************************* + * Copyright 2011-2014 by SirSengir + * + * This work is licensed under a Creative Commons Attribution-NonCommercial-NoDerivs 3.0 Unported License. + * + * To view a copy of this license, visit http://creativecommons.org/licenses/by-nc-nd/3.0/. + ******************************************************************************/ +package forestry.arboriculture.gadgets; + +import java.util.List; + +import net.minecraft.block.Block; +import net.minecraft.block.material.Material; +import net.minecraft.client.renderer.texture.IIconRegister; +import net.minecraft.creativetab.CreativeTabs; +import net.minecraft.item.Item; +import net.minecraft.item.ItemStack; +import net.minecraft.util.IIcon; +import net.minecraft.world.IBlockAccess; +import net.minecraft.world.World; + +import cpw.mods.fml.relauncher.Side; +import cpw.mods.fml.relauncher.SideOnly; + +import net.minecraftforge.common.util.ForgeDirection; + +import forestry.api.core.Tabs; +import forestry.arboriculture.IWoodTyped; +import forestry.arboriculture.WoodType; + +public class BlockPlanks extends Block implements IWoodTyped { + + public static enum PlankCat { + CAT0, CAT1 + } + + private final PlankCat cat; + + public BlockPlanks(PlankCat cat) { + super(Material.wood); + this.cat = cat; + setResistance(5.0F); + setStepSound(soundTypeWood); + setCreativeTab(Tabs.tabArboriculture); + } + + @SuppressWarnings({ "rawtypes", "unchecked" }) + @Override + public void getSubBlocks(Item item, CreativeTabs par2CreativeTabs, List itemList) { + int count = (cat == PlankCat.CAT0 ? 16 : 8); + for (int i = 0; i < count; i++) + itemList.add(new ItemStack(this, 1, i)); + } + + /* ICONS */ + @SideOnly(Side.CLIENT) + @Override + public void registerBlockIcons(IIconRegister register) { + WoodType.registerIcons(register); + } + + @SideOnly(Side.CLIENT) + @Override + public IIcon getIcon(int side, int meta) { + return getWoodType(meta).getPlankIcon(); + } + + @Override + public int damageDropped(int meta) { + return meta; + } + + /* PROPERTIES */ + @Override + public float getBlockHardness(World world, int x, int y, int z) { + return getWoodType(world.getBlockMetadata(x, y, z)).getHardness(); + } + + @Override + public boolean isWood(IBlockAccess world, int x, int y, int z) { + return true; + } + + @Override + public int getFlammability(IBlockAccess world, int x, int y, int z, ForgeDirection face) { + return 20; + } + + @Override + public boolean isFlammable(IBlockAccess world, int x, int y, int z, ForgeDirection face) { + return true; + } + + @Override + public int getFireSpreadSpeed(IBlockAccess world, int x, int y, int z, ForgeDirection face) { + return 5; + } + + @Override + public WoodType getWoodType(int meta) { + if(cat.ordinal() * 16 + meta < WoodType.VALUES.length) + return WoodType.VALUES[cat.ordinal() * 16 + meta]; + else + return WoodType.LARCH; + } + + @Override + public String getBlockKind() { + return "planks"; + } +} diff --git a/forestry_common/arboriculture/forestry/arboriculture/gadgets/BlockSapling.java b/forestry_common/arboriculture/forestry/arboriculture/gadgets/BlockSapling.java new file mode 100755 index 000000000..f8b0f95bf --- /dev/null +++ b/forestry_common/arboriculture/forestry/arboriculture/gadgets/BlockSapling.java @@ -0,0 +1,165 @@ +/******************************************************************************* + * Copyright 2011-2014 by SirSengir + * + * This work is licensed under a Creative Commons Attribution-NonCommercial-NoDerivs 3.0 Unported License. + * + * To view a copy of this license, visit http://creativecommons.org/licenses/by-nc-nd/3.0/. + ******************************************************************************/ +package forestry.arboriculture.gadgets; + +import java.util.ArrayList; + +import net.minecraft.block.Block; +import net.minecraft.block.material.Material; +import net.minecraft.client.renderer.texture.IIconRegister; +import net.minecraft.entity.player.EntityPlayer; +import net.minecraft.item.ItemStack; +import net.minecraft.tileentity.TileEntity; +import net.minecraft.util.AxisAlignedBB; +import net.minecraft.util.IIcon; +import net.minecraft.world.IBlockAccess; +import net.minecraft.world.World; + +import cpw.mods.fml.relauncher.Side; +import cpw.mods.fml.relauncher.SideOnly; + +import forestry.api.arboriculture.EnumGermlingType; +import forestry.api.arboriculture.IAlleleFruit; +import forestry.api.arboriculture.IAlleleTreeSpecies; +import forestry.api.genetics.AlleleManager; +import forestry.api.genetics.IAllele; +import forestry.core.proxy.Proxies; +import forestry.core.render.TextureManager; +import forestry.core.utils.StackUtils; +import forestry.plugins.PluginArboriculture; + +public class BlockSapling extends BlockTreeContainer { + + public static TileSapling getSaplingTile(IBlockAccess world, int x, int y, int z) { + TileEntity tile = world.getTileEntity(x, y, z); + if (!(tile instanceof TileSapling)) + return null; + + return (TileSapling) tile; + } + + public BlockSapling() { + super(Material.plants); + + float factor = 0.4F; + setBlockBounds(0.5F - factor, 0.0F, 0.5F - factor, 0.5F + factor, factor * 2.0F, 0.5F + factor); + setStepSound(soundTypeGrass); + } + + @Override + public TileEntity createNewTileEntity(World var1, int meta) { + return new TileSapling(); + } + + /* COLLISION BOX */ + @Override + public AxisAlignedBB getCollisionBoundingBoxFromPool(World world, int x, int y, int z) { + return null; + } + + /* RENDERING */ + @Override + public boolean isOpaqueCube() { + return false; + } + + @Override + public boolean renderAsNormalBlock() { + return false; + } + + @Override + public int getRenderType() { + return PluginArboriculture.modelIdSaplings; + } + + /* ICONS */ + @SideOnly(Side.CLIENT) + private static IIcon defaultIcon; + + @SideOnly(Side.CLIENT) + @Override + public void registerBlockIcons(IIconRegister register) { + defaultIcon = TextureManager.getInstance().registerTex(register, "germlings/sapling.treeBalsa"); + + for (IAllele allele : AlleleManager.alleleRegistry.getRegisteredAlleles().values()) { + if (allele instanceof IAlleleTreeSpecies) + ((IAlleleTreeSpecies) allele).getIconProvider().registerIcons(register); + if (allele instanceof IAlleleFruit) + ((IAlleleFruit) allele).getProvider().registerIcons(register); + } + + } + + @SideOnly(Side.CLIENT) + @Override + public IIcon getIcon(int side, int metadata) { + return defaultIcon; + } + + @SideOnly(Side.CLIENT) + @Override + public IIcon getIcon(IBlockAccess world, int x, int y, int z, int side) { + TileSapling sapling = getSaplingTile(world, x, y, z); + if (sapling == null) + return defaultIcon; + + if (sapling.getTree() == null) + return defaultIcon; + + return sapling.getTree().getGenome().getPrimary().getGermlingIcon(EnumGermlingType.SAPLING, 0); + } + + /* PLANTING */ + @Override + public boolean canBlockStay(World world, int x, int y, int z) { + TileSapling tile = getSaplingTile(world, x, y, z); + if (tile == null) + return false; + if (tile.getTree() == null) + return false; + + return tile.getTree().canStay(world, x, y, z); + } + + @Override + public void onNeighborBlockChange(World world, int x, int y, int z, Block neighbour) { + if (Proxies.common.isSimulating(world) && !this.canBlockStay(world, x, y, z)) { + dropAsSapling(world, x, y, z); + world.setBlockToAir(x, y, z); + } + + } + + /* REMOVING */ + @Override + public ArrayList getDrops(World world, int x, int y, int z, int metadata, int fortune) { + return new ArrayList(); + } + + @Override + public boolean removedByPlayer(World world, EntityPlayer player, int x, int y, int z) { + if (Proxies.common.isSimulating(world) && canHarvestBlock(player, world.getBlockMetadata(x, y, z))) + if (!player.capabilities.isCreativeMode) + dropAsSapling(world, x, y, z); + + return world.setBlockToAir(x, y, z); + } + + private void dropAsSapling(World world, int x, int y, int z) { + if (!Proxies.common.isSimulating(world)) + return; + + TileSapling sapling = getSaplingTile(world, x, y, z); + if (sapling != null && sapling.getTree() != null) { + ItemStack saplingStack = PluginArboriculture.treeInterface.getMemberStack(sapling.getTree(), EnumGermlingType.SAPLING.ordinal()); + StackUtils.dropItemStackAsEntity(saplingStack, world, x, y, z); + } + + } +} diff --git a/forestry_common/arboriculture/forestry/arboriculture/gadgets/BlockSlab.java b/forestry_common/arboriculture/forestry/arboriculture/gadgets/BlockSlab.java new file mode 100755 index 000000000..ce5696dfd --- /dev/null +++ b/forestry_common/arboriculture/forestry/arboriculture/gadgets/BlockSlab.java @@ -0,0 +1,138 @@ +/******************************************************************************* + * Copyright 2011-2014 by SirSengir + * + * This work is licensed under a Creative Commons Attribution-NonCommercial-NoDerivs 3.0 Unported License. + * + * To view a copy of this license, visit http://creativecommons.org/licenses/by-nc-nd/3.0/. + ******************************************************************************/ +package forestry.arboriculture.gadgets; + +import java.util.List; +import java.util.Random; + +import net.minecraft.block.material.Material; +import net.minecraft.client.renderer.texture.IIconRegister; +import net.minecraft.creativetab.CreativeTabs; +import net.minecraft.init.Blocks; +import net.minecraft.item.Item; +import net.minecraft.item.ItemStack; +import net.minecraft.util.IIcon; +import net.minecraft.world.IBlockAccess; +import net.minecraft.world.World; + +import cpw.mods.fml.relauncher.Side; +import cpw.mods.fml.relauncher.SideOnly; + +import net.minecraftforge.common.util.ForgeDirection; + +import forestry.api.core.Tabs; +import forestry.arboriculture.IWoodTyped; +import forestry.arboriculture.WoodType; + +public class BlockSlab extends net.minecraft.block.BlockSlab implements IWoodTyped { + + public static enum SlabCat { + CAT0, CAT1, CAT2 + } + + private final SlabCat cat; + + public BlockSlab(SlabCat cat) { + super(false, Material.wood); + this.cat = cat; + setCreativeTab(Tabs.tabArboriculture); + setLightOpacity(0); + setHardness(2.0F); + setResistance(5.0F); + setStepSound(soundTypeWood); + } + + @Override + public boolean isOpaqueCube() { + return false; + } + + /* ICONS */ + @SideOnly(Side.CLIENT) + @Override + public void registerBlockIcons(IIconRegister register) { + WoodType.registerIcons(register); + } + + @Override + public IIcon getIcon(int side, int meta) { + WoodType type = WoodType.VALUES[(8 * cat.ordinal()) + (meta & 7)]; + return type.getPlankIcon(); + } + + @Override + public Item getItemDropped(int meta, Random random, int par3) { + return Item.getItemFromBlock(this); + } + + /** + * only called by clickMiddleMouseButton , and passed to inventory.setCurrentItem (along with isCreative) + */ + /*public int idPicked(World world, int x, int y, int z) { + return blockID; + }*/ + + /** + * Get the block's damage value (for use with pick block). + */ + @Override + public int getDamageValue(World world, int x, int y, int z) { + return super.getDamageValue(world, x, y, z) & 7; + } + + @Override + protected ItemStack createStackedBlock(int meta) { + return new ItemStack(Blocks.wooden_slab, 2, meta & 7); + } + + @Override + public String func_150002_b(int var1) { + return "SomeSlab"; + } + + @SuppressWarnings({ "rawtypes", "unchecked" }) + @Override + public void getSubBlocks(Item item, CreativeTabs par2CreativeTabs, List itemList) { + for (int i = 0; i < 8; ++i) + itemList.add(new ItemStack(item, 1, i)); + } + + /* PROPERTIES */ + @Override + public int getFlammability(IBlockAccess world, int x, int y, int z, ForgeDirection face) { + return 20; + } + + @Override + public boolean isFlammable(IBlockAccess world, int x, int y, int z, ForgeDirection face) { + return true; + } + + @Override + public int getFireSpreadSpeed(IBlockAccess world, int x, int y, int z, ForgeDirection face) { + return 5; + } + + @Override + public WoodType getWoodType(int meta) { + if(meta + cat.ordinal() * 8 < WoodType.VALUES.length) + return WoodType.VALUES[meta + cat.ordinal() * 8]; + else + return WoodType.LARCH; + } + + @Override + public String getBlockKind() { + return "slab"; + } + + @Override + public boolean getUseNeighborBrightness() { + return true; + } +} diff --git a/forestry_common/arboriculture/forestry/arboriculture/gadgets/BlockTreeContainer.java b/forestry_common/arboriculture/forestry/arboriculture/gadgets/BlockTreeContainer.java new file mode 100755 index 000000000..a730fd0d8 --- /dev/null +++ b/forestry_common/arboriculture/forestry/arboriculture/gadgets/BlockTreeContainer.java @@ -0,0 +1,42 @@ +/******************************************************************************* + * Copyright 2011-2014 by SirSengir + * + * This work is licensed under a Creative Commons Attribution-NonCommercial-NoDerivs 3.0 Unported License. + * + * To view a copy of this license, visit http://creativecommons.org/licenses/by-nc-nd/3.0/. + ******************************************************************************/ +package forestry.arboriculture.gadgets; + +import java.util.Random; + +import net.minecraft.block.BlockContainer; +import net.minecraft.block.material.Material; +import net.minecraft.tileentity.TileEntity; +import net.minecraft.world.World; + +public abstract class BlockTreeContainer extends BlockContainer { + + public BlockTreeContainer(Material material) { + super(material); + setTickRandomly(true); + } + + @Override + public void updateTick(World world, int x, int y, int z, Random rand) { + + if (world.rand.nextFloat() > 0.1) + return; + + TileEntity tile = world.getTileEntity(x, y, z); + if (!(tile instanceof TileTreeContainer)) + return; + + ((TileTreeContainer) tile).onBlockTick(); + } + + @Override + public boolean hasTileEntity(int metadata) { + return true; + } + +} diff --git a/forestry_common/arboriculture/forestry/arboriculture/gadgets/TileArboristChest.java b/forestry_common/arboriculture/forestry/arboriculture/gadgets/TileArboristChest.java new file mode 100755 index 000000000..060dafdff --- /dev/null +++ b/forestry_common/arboriculture/forestry/arboriculture/gadgets/TileArboristChest.java @@ -0,0 +1,21 @@ +/******************************************************************************* + * Copyright 2011-2014 by SirSengir + * + * This work is licensed under a Creative Commons Attribution-NonCommercial-NoDerivs 3.0 Unported License. + * + * To view a copy of this license, visit http://creativecommons.org/licenses/by-nc-nd/3.0/. + ******************************************************************************/ +package forestry.arboriculture.gadgets; + +import forestry.api.genetics.AlleleManager; +import forestry.arboriculture.genetics.TreeHelper; +import forestry.core.gadgets.TileNaturalistChest; +import forestry.core.network.GuiId; + +public class TileArboristChest extends TileNaturalistChest { + public TileArboristChest() { + super(AlleleManager.alleleRegistry.getSpeciesRoot(TreeHelper.UID), GuiId.ArboristChestGUI.ordinal()); + } + + +} diff --git a/forestry_common/arboriculture/forestry/arboriculture/gadgets/TileFruitPod.java b/forestry_common/arboriculture/forestry/arboriculture/gadgets/TileFruitPod.java new file mode 100755 index 000000000..0c2809f12 --- /dev/null +++ b/forestry_common/arboriculture/forestry/arboriculture/gadgets/TileFruitPod.java @@ -0,0 +1,194 @@ +/******************************************************************************* + * Copyright 2011-2014 by SirSengir + * + * This work is licensed under a Creative Commons Attribution-NonCommercial-NoDerivs 3.0 Unported License. + * + * To view a copy of this license, visit http://creativecommons.org/licenses/by-nc-nd/3.0/. + ******************************************************************************/ +package forestry.arboriculture.gadgets; + +import java.util.ArrayList; +import java.util.Arrays; +import java.util.Collection; + +import net.minecraft.item.ItemStack; +import net.minecraft.nbt.NBTTagCompound; +import net.minecraft.network.Packet; +import net.minecraft.tileentity.TileEntity; +import net.minecraft.util.IIcon; + +import cpw.mods.fml.relauncher.Side; +import cpw.mods.fml.relauncher.SideOnly; + +import forestry.api.arboriculture.IAlleleFruit; +import forestry.api.genetics.AlleleManager; +import forestry.api.genetics.IAllele; +import forestry.api.genetics.IFruitBearer; +import forestry.api.genetics.IFruitFamily; +import forestry.core.network.ForestryPacket; +import forestry.core.network.INetworkedEntity; +import forestry.core.network.PacketIds; +import forestry.core.network.PacketPayload; +import forestry.core.network.PacketUpdate; +import forestry.core.proxy.Proxies; +import forestry.core.render.TextureManager; + +public class TileFruitPod extends TileEntity implements INetworkedEntity, IFruitBearer { + + private static final short MAX_MATURITY = 2; + + private IAlleleFruit allele; + + private short maturity; + private int[] indices = new int[0]; + private float sappiness; + + public void setFruit(IAlleleFruit allele, float sappiness, short[] indices) { + this.allele = allele; + this.sappiness = sappiness; + this.indices = new int[indices.length]; + for (int i = 0; i < indices.length; i++) + this.indices[i] = indices[i]; + } + + /* SAVING & LOADING */ + @Override + public void readFromNBT(NBTTagCompound nbttagcompound) { + super.readFromNBT(nbttagcompound); + + IAllele stored = AlleleManager.alleleRegistry.getAllele(nbttagcompound.getString("UID")); + if (stored != null && stored instanceof IAlleleFruit) + allele = (IAlleleFruit)stored; + else + allele = (IAlleleFruit) AlleleManager.alleleRegistry.getAllele("fruitCocoa"); + + maturity = nbttagcompound.getShort("MT"); + sappiness = nbttagcompound.getFloat("SP"); + indices = nbttagcompound.getIntArray("IN"); + } + + @Override + public void writeToNBT(NBTTagCompound nbttagcompound) { + super.writeToNBT(nbttagcompound); + + if (allele != null) + nbttagcompound.setString("UID", allele.getUID()); + + nbttagcompound.setShort("MT", maturity); + nbttagcompound.setFloat("SP", sappiness); + nbttagcompound.setIntArray("IN", indices); + } + + /* UPDATING */ + /** + * This doesn't use normal TE updates + */ + @Override + public boolean canUpdate() { + return false; + } + + public void onBlockTick() { + if (canMature() && worldObj.rand.nextFloat() <= sappiness) { + mature(); + } + } + + public void mature() { + maturity++; + sendNetworkUpdateRipening(); + } + + public boolean canMature() { + return maturity < MAX_MATURITY; + } + + @SideOnly(Side.CLIENT) + public IIcon getIcon(int metadata, int side) { + if (maturity < indices.length) + return TextureManager.getInstance().getIcon((short) indices[maturity]); + else + return null; + } + + public short getMaturity() { + return maturity; + } + + public ItemStack[] getDrop() { + return allele.getProvider().getFruits(null, worldObj, xCoord, yCoord, zCoord, maturity); + } + + /* NETWORK */ + @Override + public Packet getDescriptionPacket() { + return toPacket().getPacket(); + } + + @Override + public void sendNetworkUpdate() { + Proxies.net.sendNetworkPacket(toPacket(), xCoord, yCoord, zCoord); + } + + private void sendNetworkUpdateRipening() { + Proxies.net.sendNetworkPacket(new PacketUpdate(PacketIds.TILE_UPDATE, xCoord, yCoord, zCoord, maturity), xCoord, yCoord, zCoord); + } + + private ForestryPacket toPacket() { + + PacketPayload payload = new PacketPayload(indices.length, 1); + payload.shortPayload[0] = maturity; + payload.intPayload = indices; + + return new PacketUpdate(PacketIds.TILE_UPDATE, xCoord, yCoord, zCoord, payload); + } + + @Override + public void fromPacket(ForestryPacket packetRaw) { + PacketUpdate packet = (PacketUpdate) packetRaw; + maturity = packet.payload.shortPayload[0]; + + if (packet.payload.intPayload != null && packet.payload.intPayload.length > 0) { + indices = packet.payload.intPayload; + } + + worldObj.func_147479_m(xCoord, yCoord, zCoord); + } + + /* IFRUITBEARER */ + @Override + public boolean hasFruit() { + return true ; + } + + @Override + public IFruitFamily getFruitFamily() { + if (allele == null) + return null; + return allele.getProvider().getFamily(); + } + + @Override + public Collection pickFruit(ItemStack tool) { + if (allele == null) + return new ArrayList(); + + + Collection fruits = Arrays.asList(getDrop()); + maturity = 0; + sendNetworkUpdateRipening(); + return fruits; + } + + @Override + public float getRipeness() { + return (float)maturity / MAX_MATURITY; + } + + @Override + public void addRipeness(float add) { + maturity += MAX_MATURITY * add; + sendNetworkUpdateRipening(); + } + +} diff --git a/forestry_common/arboriculture/forestry/arboriculture/gadgets/TileLeaves.java b/forestry_common/arboriculture/forestry/arboriculture/gadgets/TileLeaves.java new file mode 100755 index 000000000..6b5ed8ed8 --- /dev/null +++ b/forestry_common/arboriculture/forestry/arboriculture/gadgets/TileLeaves.java @@ -0,0 +1,425 @@ +/******************************************************************************* + * Copyright 2011-2014 by SirSengir + * + * This work is licensed under a Creative Commons Attribution-NonCommercial-NoDerivs 3.0 Unported License. + * + * To view a copy of this license, visit http://creativecommons.org/licenses/by-nc-nd/3.0/. + ******************************************************************************/ +package forestry.arboriculture.gadgets; + +import java.util.ArrayList; +import java.util.Arrays; +import java.util.Collection; +import java.util.EnumSet; + +import net.minecraft.entity.player.EntityPlayer; +import net.minecraft.item.ItemStack; +import net.minecraft.nbt.NBTTagCompound; +import net.minecraft.network.Packet; +import net.minecraft.util.IIcon; +import net.minecraft.world.World; +import net.minecraft.world.biome.BiomeGenBase; + +import cpw.mods.fml.relauncher.Side; +import cpw.mods.fml.relauncher.SideOnly; + +import net.minecraftforge.common.EnumPlantType; + +import forestry.api.arboriculture.IAlleleFruit; +import forestry.api.arboriculture.IFruitProvider; +import forestry.api.arboriculture.ILeafTickHandler; +import forestry.api.arboriculture.ITree; +import forestry.api.core.EnumHumidity; +import forestry.api.core.EnumTemperature; +import forestry.api.genetics.AlleleManager; +import forestry.api.genetics.IEffectData; +import forestry.api.genetics.IFruitBearer; +import forestry.api.genetics.IFruitFamily; +import forestry.api.genetics.IIndividual; +import forestry.api.genetics.IPollinatable; +import forestry.api.lepidopterology.IButterfly; +import forestry.api.lepidopterology.IButterflyNursery; +import forestry.api.lepidopterology.IButterflyRoot; +import forestry.arboriculture.network.PacketLeafUpdate; +import forestry.core.genetics.Allele; +import forestry.core.network.ForestryPacket; +import forestry.core.proxy.Proxies; +import forestry.core.render.TextureManager; +import forestry.core.utils.Utils; +import forestry.plugins.PluginArboriculture; + +public class TileLeaves extends TileTreeContainer implements IPollinatable, IFruitBearer, IButterflyNursery { + + private int colourLeaves; + private int colourFruits; + private short textureIndexFancy = 48; + private short textureIndexPlain = 64; + private short textureIndexFruits = -1; + + private boolean isFruitLeaf; + private boolean isPollinatedState; + private int ripeningTime; + + private int maturationTime; + private int encumbrance; + + private int biomeId = -1; + + private IEffectData effectData[] = new IEffectData[2]; + + private void updateBiome() { + if(worldObj == null) + return; + BiomeGenBase biome = Utils.getBiomeAt(worldObj, xCoord, zCoord); + if (biome != null) { + this.biomeId = biome.biomeID; + } + } + + /* SAVING & LOADING */ + @Override + public void readFromNBT(NBTTagCompound nbttagcompound) { + super.readFromNBT(nbttagcompound); + + isFruitLeaf = nbttagcompound.getBoolean("FL"); + ripeningTime = nbttagcompound.getInteger("RT"); + + encumbrance = nbttagcompound.getInteger("ENC"); + + if (nbttagcompound.hasKey("CATER")) { + maturationTime = nbttagcompound.getInteger("CATMAT"); + caterpillar = (IButterfly)AlleleManager.alleleRegistry.getSpeciesRoot("rootButterflies").getMember(nbttagcompound.getCompoundTag("CATER")); + } + + } + + @Override + public void writeToNBT(NBTTagCompound nbttagcompound) { + super.writeToNBT(nbttagcompound); + + nbttagcompound.setBoolean("FL", isFruitLeaf); + nbttagcompound.setInteger("RT", ripeningTime); + nbttagcompound.setInteger("ENC", encumbrance); + + if (caterpillar != null) { + nbttagcompound.setInteger("CATMAT", maturationTime); + + NBTTagCompound subcompound = new NBTTagCompound(); + caterpillar.writeToNBT(subcompound); + nbttagcompound.setTag("CATER", subcompound); + } + + } + + @Override + public void onBlockTick() { + if(biomeId < 0) + updateBiome(); + + if(getTree() == null) + return; + + boolean isDestroyed = isDestroyed(); + for(ILeafTickHandler tickHandler : getTree().getGenome().getPrimary().getRoot().getLeafTickHandlers()) + if(tickHandler.onRandomLeafTick(getTree(), worldObj, biomeId, xCoord, yCoord, zCoord, isDestroyed)) + return; + + if(isDestroyed) + return; + + if(encumbrance > 0) + encumbrance--; + + if (hasFruit() && ripeningTime < Short.MAX_VALUE - 1) { + float sappiness = getTree().getGenome().getSappiness() + * PluginArboriculture.treeInterface.getTreekeepingMode(worldObj).getSappinessModifier(this.getTree().getGenome(), 1f); + + if (worldObj.rand.nextFloat() < sappiness) { + ripeningTime++; + sendNetworkUpdateRipening(); + } + } + + if(caterpillar != null) + matureCaterpillar(); + + effectData = getTree().doEffect(effectData, worldObj, biomeId, xCoord, yCoord, zCoord); + } + + @Override + public void setTree(ITree tree) { + if (tree.canBearFruit()) + isFruitLeaf = tree.getGenome().getFruitProvider().markAsFruitLeaf(tree.getGenome(), worldObj, xCoord, yCoord, zCoord); + super.setTree(tree); + } + + /* INFORMATION */ + private boolean isDestroyed() { + if(getTree() == null) + return false; + return encumbrance > getTree().getResilience(); + } + + public boolean isPollinated() { + return !isDestroyed() && getTree() != null && getTree().getMate() != null; + } + + public int getFoliageColour(EntityPlayer player) { + return isPollinatedState & Utils.hasNaturalistEye(player) ? 0xffffff : colourLeaves; + } + + public int getFruitColour() { + return colourFruits; + } + + @SideOnly(Side.CLIENT) + public IIcon getIcon(boolean fancy) { + if (fancy) + return TextureManager.getInstance().getIcon(textureIndexFancy); + else + return TextureManager.getInstance().getIcon(textureIndexPlain); + } + + @SideOnly(Side.CLIENT) + public IIcon getFruitTexture() { + if (textureIndexFruits >= 0) + return TextureManager.getInstance().getIcon(textureIndexFruits); + else + return null; + } + + public int getRipeningTime() { + return ripeningTime; + } + + /* IPOLLINATABLE */ + @Override + public EnumSet getPlantType() { + if (getTree() == null) + return EnumSet.noneOf(EnumPlantType.class); + + return getTree().getPlantTypes(); + } + + @Override + public boolean canMateWith(IIndividual individual) { + if (getTree() == null) + return false; + if (getTree().getMate() != null) + return false; + + return !getTree().isGeneticEqual(individual); + } + + @Override + public void mateWith(IIndividual individual) { + if (getTree() == null) + return; + + getTree().mate((ITree) individual); + worldObj.markBlockForUpdate(xCoord, yCoord, zCoord); + } + + @Override + public IIndividual getPollen() { + return getTree(); + } + + public int determineFoliageColour() { + + if (getTree() == null) + return PluginArboriculture.proxy.getFoliageColorBasic(); + + int colour = getTree().getGenome().getPrimary().getLeafColour(getTree()); + + if(isDestroyed()) + return Utils.addRGBComponents(colour, 92, 61, 0); + else if(caterpillar != null) + return Utils.multiplyRGBComponents(colour, 1.5f); + return colour; + } + + public int determineFruitColour() { + if (getTree() == null) + return 0xffffff; + + IFruitProvider fruit = getTree().getGenome().getFruitProvider(); + return fruit.getColour(getTree().getGenome(), worldObj, xCoord, yCoord, zCoord, getRipeningTime()); + } + + public short determineTextureIndex(boolean fancy) { + if (getTree() != null) + return getTree().getGenome().getPrimary().getLeafIconIndex(getTree(), fancy); + + return 0; + } + + public short determineOverlayIndex() { + if (getTree() == null) + return -1; + if (!hasFruit()) + return -1; + + IFruitProvider fruit = getTree().getGenome().getFruitProvider(); + + // Hardcoded because vanilla oak trees don't show fruits. + if (getTree().getGenome().getPrimary() == Allele.treeOak && fruit == ((IAlleleFruit) Allele.fruitApple).getProvider()) + return -1; + else + return fruit.getIconIndex(getTree().getGenome(), worldObj, xCoord, yCoord, zCoord, getRipeningTime(), true); + + } + + /* NETWORK */ + @Override + public Packet getDescriptionPacket() { + return new PacketLeafUpdate(xCoord, yCoord, zCoord, this).getPacket(); + } + + @Override + public void sendNetworkUpdate() { + Proxies.net.sendNetworkPacket(new PacketLeafUpdate(xCoord, yCoord, zCoord, this), xCoord, yCoord, zCoord); + } + + private void sendNetworkUpdateRipening() { + Proxies.net.sendNetworkPacket(new PacketLeafUpdate(xCoord, yCoord, zCoord, determineFruitColour()), xCoord, yCoord, zCoord); + } + + @Override + public void fromPacket(ForestryPacket packetRaw) { + + PacketLeafUpdate packet = (PacketLeafUpdate)packetRaw; + if(packet.isRipeningUpdate()) { + colourFruits = packet.colourFruits; + } else { + isFruitLeaf = packet.isFruitLeaf(); + isPollinatedState = packet.isPollinated(); + textureIndexFancy = packet.textureIndexFancy; + textureIndexPlain = packet.textureIndexPlain; + textureIndexFruits = packet.textureIndexFruit; + colourLeaves = packet.colourLeaves; + colourFruits = packet.colourFruits; + } + + worldObj.func_147479_m(xCoord, yCoord, zCoord); + } + + /* IFRUITBEARER */ + @Override + public Collection pickFruit(ItemStack tool) { + if (!hasFruit()) + return new ArrayList(); + if (getTree() == null) + return new ArrayList(); + + ArrayList picked = new ArrayList(Arrays.asList(getTree().produceStacks(worldObj, xCoord, yCoord, zCoord, getRipeningTime()))); + ripeningTime = 0; + sendNetworkUpdateRipening(); + return picked; + } + + @Override + public IFruitFamily getFruitFamily() { + if (getTree() == null) + return null; + return getTree().getGenome().getFruitProvider().getFamily(); + } + + @Override + public float getRipeness() { + if (getTree() == null) + return 0f; + int ripeningPeriod = getTree().getGenome().getFruitProvider().getRipeningPeriod(); + if (ripeningPeriod == 0) + return 1.0f; + return (float) ripeningTime / ripeningPeriod; + } + + @Override + public boolean hasFruit() { + return isFruitLeaf && !isDestroyed(); + } + + @Override + public void addRipeness(float add) { + if (getTree() == null) + return; + ripeningTime += getTree().getGenome().getFruitProvider().getRipeningPeriod() * add; + sendNetworkUpdateRipening(); + } + + /* IBUTTERFLYNURSERY */ + private IButterfly caterpillar; + + private void matureCaterpillar() { + maturationTime++; + + boolean wasDestroyed = isDestroyed(); + encumbrance += caterpillar.getGenome().getMetabolism(); + wasDestroyed = !wasDestroyed && isDestroyed() ? true : false; + + if(maturationTime >= (float)caterpillar.getGenome().getLifespan() / (caterpillar.getGenome().getFertility()*2) + && caterpillar.canTakeFlight(worldObj, xCoord, yCoord, zCoord)) { + if(worldObj.isAirBlock(xCoord - 1, yCoord, zCoord)) { + attemptButterflySpawn(worldObj, caterpillar, xCoord - 1, yCoord, zCoord); + } else if(worldObj.isAirBlock(xCoord + 1, yCoord, zCoord)) { + attemptButterflySpawn(worldObj, caterpillar, xCoord + 1, yCoord, zCoord); + } else if(worldObj.isAirBlock(xCoord, yCoord, zCoord - 1)) { + attemptButterflySpawn(worldObj, caterpillar, xCoord, yCoord, zCoord - 1); + } else if(worldObj.isAirBlock(xCoord, yCoord, zCoord + 1)) { + attemptButterflySpawn(worldObj, caterpillar, xCoord, yCoord, zCoord + 1); + } + setCaterpillar(null); + } else if(wasDestroyed) { + sendNetworkUpdate(); + } + } + + private void attemptButterflySpawn(World world, IButterfly butterfly, double x, double y, double z) { + if(((IButterflyRoot)AlleleManager.alleleRegistry.getSpeciesRoot("rootButterflies")).spawnButterflyInWorld(world, butterfly.copy(), x, y + 0.1f, z) != null) + Proxies.log.finest("A caterpillar '%s' hatched at %s/%s/%s.", butterfly.getDisplayName(), x, y, z); + } + + @Override public World getWorld() { return worldObj; } + @Override public int getXCoord() { return xCoord; } + @Override public int getYCoord() { return yCoord; } + @Override public int getZCoord() { return zCoord; } + + @Override + public int getBiomeId() { + return 0; + } + + @Override + public EnumTemperature getTemperature() { + return null; + } + + @Override + public EnumHumidity getHumidity() { + return null; + } + + @Override public void setErrorState(int state) {} + @Override public int getErrorOrdinal() { return 0; } + @Override + public boolean addProduct(ItemStack product, boolean all) { + return false; + } + + @Override public IButterfly getCaterpillar() { return caterpillar; } + @Override public IIndividual getNanny() { return getTree(); } + + @Override + public void setCaterpillar(IButterfly butterfly) { + maturationTime = 0; + caterpillar = butterfly; + sendNetworkUpdate(); + } + + @Override + public boolean canNurse(IButterfly butterfly) { + return !isDestroyed() && caterpillar == null; + } + +} diff --git a/forestry_common/arboriculture/forestry/arboriculture/gadgets/TileSapling.java b/forestry_common/arboriculture/forestry/arboriculture/gadgets/TileSapling.java new file mode 100755 index 000000000..9a8646b4d --- /dev/null +++ b/forestry_common/arboriculture/forestry/arboriculture/gadgets/TileSapling.java @@ -0,0 +1,67 @@ +/******************************************************************************* + * Copyright 2011-2014 by SirSengir + * + * This work is licensed under a Creative Commons Attribution-NonCommercial-NoDerivs 3.0 Unported License. + * + * To view a copy of this license, visit http://creativecommons.org/licenses/by-nc-nd/3.0/. + ******************************************************************************/ +package forestry.arboriculture.gadgets; + +import net.minecraft.nbt.NBTTagCompound; +import net.minecraft.world.gen.feature.WorldGenerator; + +import forestry.plugins.PluginArboriculture; + +public class TileSapling extends TileTreeContainer { + + private int timesTicked = 0; + + /* SAVING & LOADING */ + @Override + public void readFromNBT(NBTTagCompound nbttagcompound) { + super.readFromNBT(nbttagcompound); + + timesTicked = nbttagcompound.getInteger("TT"); + } + + @Override + public void writeToNBT(NBTTagCompound nbttagcompound) { + super.writeToNBT(nbttagcompound); + + nbttagcompound.setInteger("TT", timesTicked); + } + + @Override + public void onBlockTick() { + + timesTicked++; + tryGrow(false); + } + + public int tryGrow(boolean bonemealed) { + + int result = 0; + if (this.getTree() == null) + return result; + + int maturity = (int) (getTree().getRequiredMaturity() * PluginArboriculture.treeInterface.getTreekeepingMode(worldObj).getMaturationModifier( + getTree().getGenome(), 1f)); + + if (bonemealed && timesTicked < maturity) { + timesTicked++; + result = 1; + } + + if (timesTicked < maturity) + return result; + + WorldGenerator generator = this.getTree().getTreeGenerator(worldObj, xCoord, yCoord, zCoord, bonemealed); + if (generator.generate(worldObj, worldObj.rand, xCoord, yCoord, zCoord)) { + PluginArboriculture.treeInterface.getBreedingTracker(worldObj, getOwnerName()).registerBirth(getTree()); + return 2; + } + + return 3; + } + +} diff --git a/forestry_common/arboriculture/forestry/arboriculture/gadgets/TileStairs.java b/forestry_common/arboriculture/forestry/arboriculture/gadgets/TileStairs.java new file mode 100755 index 000000000..aad267a02 --- /dev/null +++ b/forestry_common/arboriculture/forestry/arboriculture/gadgets/TileStairs.java @@ -0,0 +1,78 @@ +/******************************************************************************* + * Copyright 2011-2014 by SirSengir + * + * This work is licensed under a Creative Commons Attribution-NonCommercial-NoDerivs 3.0 Unported License. + * + * To view a copy of this license, visit http://creativecommons.org/licenses/by-nc-nd/3.0/. + ******************************************************************************/ +package forestry.arboriculture.gadgets; + +import net.minecraft.nbt.NBTTagCompound; +import net.minecraft.network.Packet; +import net.minecraft.tileentity.TileEntity; + +import forestry.arboriculture.WoodType; +import forestry.core.network.ForestryPacket; +import forestry.core.network.INetworkedEntity; +import forestry.core.network.PacketIds; +import forestry.core.network.PacketTileNBT; +import forestry.core.proxy.Proxies; + +public class TileStairs extends TileEntity implements INetworkedEntity { + + private WoodType type; + + public WoodType getType() { + return this.type; + } + + public void setType(WoodType type) { + this.type = type; + sendNetworkUpdate(); + } + + /* SAVING & LOADING */ + @Override + public void readFromNBT(NBTTagCompound nbttagcompound) { + super.readFromNBT(nbttagcompound); + + if (nbttagcompound.hasKey("WT")) + type = WoodType.VALUES[nbttagcompound.getShort("WT")]; + } + + @Override + public void writeToNBT(NBTTagCompound nbttagcompound) { + super.writeToNBT(nbttagcompound); + + if (type != null) + nbttagcompound.setShort("WT", (short) type.ordinal()); + } + + /* UPDATING */ + /** + * This doesn't use normal TE updates + */ + @Override + public boolean canUpdate() { + return false; + } + + /* INETWORKEDENTITY */ + @Override + public Packet getDescriptionPacket() { + return new PacketTileNBT(PacketIds.TILE_NBT, this).getPacket(); + } + + @Override + public void sendNetworkUpdate() { + Proxies.net.sendNetworkPacket(new PacketTileNBT(PacketIds.TILE_NBT, this), xCoord, yCoord, zCoord); + } + + @Override + public void fromPacket(ForestryPacket packetRaw) { + PacketTileNBT packet = (PacketTileNBT) packetRaw; + this.readFromNBT(packet.getTagCompound()); + worldObj.func_147479_m(xCoord, yCoord, zCoord); + } + +} diff --git a/forestry_common/arboriculture/forestry/arboriculture/gadgets/TileTreeContainer.java b/forestry_common/arboriculture/forestry/arboriculture/gadgets/TileTreeContainer.java new file mode 100755 index 000000000..7bb445eb4 --- /dev/null +++ b/forestry_common/arboriculture/forestry/arboriculture/gadgets/TileTreeContainer.java @@ -0,0 +1,160 @@ +/******************************************************************************* + * Copyright 2011-2014 by SirSengir + * + * This work is licensed under a Creative Commons Attribution-NonCommercial-NoDerivs 3.0 Unported License. + * + * To view a copy of this license, visit http://creativecommons.org/licenses/by-nc-nd/3.0/. + ******************************************************************************/ +package forestry.arboriculture.gadgets; + +import net.minecraft.entity.player.EntityPlayer; +import net.minecraft.nbt.NBTTagCompound; +import net.minecraft.network.Packet; +import net.minecraft.tileentity.TileEntity; + +import forestry.api.arboriculture.ITree; +import forestry.arboriculture.genetics.Tree; +import forestry.core.interfaces.IOwnable; +import forestry.core.network.ForestryPacket; +import forestry.core.network.INetworkedEntity; +import forestry.core.network.PacketIds; +import forestry.core.network.PacketTileNBT; +import forestry.core.proxy.Proxies; +import forestry.core.utils.EnumAccess; + +/** + * This is the base TE class for any block that needs to contain tree genome information. + * + * @author SirSengir + */ +public abstract class TileTreeContainer extends TileEntity implements INetworkedEntity, IOwnable { + + private ITree containedTree; + + /* SAVING & LOADING */ + @Override + public void readFromNBT(NBTTagCompound nbttagcompound) { + super.readFromNBT(nbttagcompound); + + if (nbttagcompound.hasKey("ContainedTree")) + containedTree = new Tree(nbttagcompound.getCompoundTag("ContainedTree")); + if (nbttagcompound.hasKey("Owner")) + owner = nbttagcompound.getString("Owner"); + + } + + @Override + public void writeToNBT(NBTTagCompound nbttagcompound) { + super.writeToNBT(nbttagcompound); + + if (containedTree != null) { + NBTTagCompound subcompound = new NBTTagCompound(); + containedTree.writeToNBT(subcompound); + nbttagcompound.setTag("ContainedTree", subcompound); + } + if (owner != null) + nbttagcompound.setString("Owner", owner); + + } + + /* CLIENT INFORMATION */ + + /* CONTAINED TREE */ + public void setTree(ITree tree) { + this.containedTree = tree; + if (tree != null) + sendNetworkUpdate(); + } + + public ITree getTree() { + return this.containedTree; + } + + /* UPDATING */ + /** + * This doesn't use normal TE updates + */ + @Override + public boolean canUpdate() { + return false; + } + + /** + * Leaves and saplings will implement their logic here. + */ + public abstract void onBlockTick(); + + /* INETWORKEDENTITY */ + @Override + public Packet getDescriptionPacket() { + return new PacketTileNBT(PacketIds.TILE_NBT, this).getPacket(); + } + + @Override + public void sendNetworkUpdate() { + Proxies.net.sendNetworkPacket(new PacketTileNBT(PacketIds.TILE_NBT, this), xCoord, yCoord, zCoord); + } + + @Override + public void fromPacket(ForestryPacket packetRaw) { + PacketTileNBT packet = (PacketTileNBT) packetRaw; + this.readFromNBT(packet.getTagCompound()); + worldObj.func_147479_m(xCoord, yCoord, zCoord); + } + + /* IOWNABLE */ + public String owner = null; + + @Override + public boolean allowsRemoval(EntityPlayer player) { + return true; + } + + @Override + public boolean allowsInteraction(EntityPlayer player) { + return true; + } + + @Override + public EnumAccess getAccess() { + return EnumAccess.SHARED; + } + + @Override + public boolean isOwnable() { + return false; + } + + @Override + public boolean isOwned() { + return owner != null && !owner.isEmpty(); + } + + @Override + public String getOwnerName() { + return owner; + } + + @Override + public void setOwner(EntityPlayer player) { + this.owner = player.getGameProfile().getId(); + } + + public void setOwner(String playername) { + this.owner = playername; + } + + @Override + public boolean isOwner(EntityPlayer player) { + if (owner != null) + return owner.equals(player.getGameProfile().getId()); + else + return false; + } + + @Override + public boolean switchAccessRule(EntityPlayer player) { + return false; + } + +} diff --git a/forestry_common/arboriculture/forestry/arboriculture/genetics/AlleleFruit.java b/forestry_common/arboriculture/forestry/arboriculture/genetics/AlleleFruit.java new file mode 100755 index 000000000..b4bdd911d --- /dev/null +++ b/forestry_common/arboriculture/forestry/arboriculture/genetics/AlleleFruit.java @@ -0,0 +1,37 @@ +/******************************************************************************* + * Copyright 2011-2014 by SirSengir + * + * This work is licensed under a Creative Commons Attribution-NonCommercial-NoDerivs 3.0 Unported License. + * + * To view a copy of this license, visit http://creativecommons.org/licenses/by-nc-nd/3.0/. + ******************************************************************************/ +package forestry.arboriculture.genetics; + +import forestry.api.arboriculture.IAlleleFruit; +import forestry.api.arboriculture.IFruitProvider; +import forestry.core.genetics.Allele; + +public class AlleleFruit extends Allele implements IAlleleFruit { + + private IFruitProvider provider; + + public AlleleFruit(String uid, IFruitProvider provider) { + this(uid, provider, false); + } + + public AlleleFruit(String uid, IFruitProvider provider, boolean isDominant) { + super(uid, isDominant); + this.provider = provider; + } + + @Override + public IFruitProvider getProvider() { + return this.provider; + } + + @Override + public String getName() { + return getProvider().getDescription(); + } + +} diff --git a/forestry_common/arboriculture/forestry/arboriculture/genetics/AlleleGrowth.java b/forestry_common/arboriculture/forestry/arboriculture/genetics/AlleleGrowth.java new file mode 100755 index 000000000..ac5790a77 --- /dev/null +++ b/forestry_common/arboriculture/forestry/arboriculture/genetics/AlleleGrowth.java @@ -0,0 +1,32 @@ +/******************************************************************************* + * Copyright 2011-2014 by SirSengir + * + * This work is licensed under a Creative Commons Attribution-NonCommercial-NoDerivs 3.0 Unported License. + * + * To view a copy of this license, visit http://creativecommons.org/licenses/by-nc-nd/3.0/. + ******************************************************************************/ +package forestry.arboriculture.genetics; + +import forestry.api.arboriculture.IAlleleGrowth; +import forestry.api.arboriculture.IGrowthProvider; +import forestry.core.genetics.Allele; + +public class AlleleGrowth extends Allele implements IAlleleGrowth { + + IGrowthProvider provider; + + public AlleleGrowth(String uid, IGrowthProvider provider) { + this(uid, provider, false); + } + + public AlleleGrowth(String uid, IGrowthProvider provider, boolean isDominant) { + super(uid, isDominant); + this.provider = provider; + } + + @Override + public IGrowthProvider getProvider() { + return provider; + } + +} diff --git a/forestry_common/arboriculture/forestry/arboriculture/genetics/AlleleLeafEffectNone.java b/forestry_common/arboriculture/forestry/arboriculture/genetics/AlleleLeafEffectNone.java new file mode 100755 index 000000000..8fb0f81d5 --- /dev/null +++ b/forestry_common/arboriculture/forestry/arboriculture/genetics/AlleleLeafEffectNone.java @@ -0,0 +1,58 @@ +/******************************************************************************* + * Copyright 2011-2014 by SirSengir + * + * This work is licensed under a Creative Commons Attribution-NonCommercial-NoDerivs 3.0 Unported License. + * + * To view a copy of this license, visit http://creativecommons.org/licenses/by-nc-nd/3.0/. + ******************************************************************************/ +package forestry.arboriculture.genetics; + +import net.minecraft.util.AxisAlignedBB; +import net.minecraft.world.World; + +import forestry.api.arboriculture.IAlleleLeafEffect; +import forestry.api.arboriculture.ITreeGenome; +import forestry.api.genetics.IEffectData; +import forestry.core.genetics.Allele; +import forestry.core.utils.Vect; + +public class AlleleLeafEffectNone extends Allele implements IAlleleLeafEffect { + + int[] DEFAULT_EFFECT_AREA = new int[] { 12, 12, 12 }; + + public AlleleLeafEffectNone(String uid) { + super(uid, true); + } + + @Override + public boolean isCombinable() { + return true; + } + + @Override + public IEffectData validateStorage(IEffectData storedData) { + return storedData; + } + + @Override + public String getName() { + return "None"; + } + + @Override + public IEffectData doEffect(ITreeGenome genome, IEffectData storedData, World world, int x, int y, int z) { + return storedData; + } + + protected AxisAlignedBB getBounding(int x, int y, int z, float modifier) { + int[] areaAr = DEFAULT_EFFECT_AREA; + Vect area = new Vect(areaAr[0], areaAr[1], areaAr[2]).multiply(modifier); + Vect offset = new Vect(-Math.round(area.x / 2), -Math.round(area.y / 2), -Math.round(area.z / 2)); + + Vect min = new Vect(x + offset.x, y + offset.y, y + offset.z); + Vect max = new Vect(x + offset.x + area.x, y + offset.y + area.y, y + offset.z + area.z); + + return AxisAlignedBB.getAABBPool().getAABB(min.x, min.y, min.z, max.x, max.y, max.z); + } + +} diff --git a/forestry_common/arboriculture/forestry/arboriculture/genetics/AlleleTreeSpecies.java b/forestry_common/arboriculture/forestry/arboriculture/genetics/AlleleTreeSpecies.java new file mode 100755 index 000000000..738018daf --- /dev/null +++ b/forestry_common/arboriculture/forestry/arboriculture/genetics/AlleleTreeSpecies.java @@ -0,0 +1,289 @@ +/******************************************************************************* + * Copyright 2011-2014 by SirSengir + * + * This work is licensed under a Creative Commons Attribution-NonCommercial-NoDerivs 3.0 Unported License. + * + * To view a copy of this license, visit http://creativecommons.org/licenses/by-nc-nd/3.0/. + ******************************************************************************/ +package forestry.arboriculture.genetics; + +import java.util.ArrayList; +import java.util.HashMap; + +import net.minecraft.client.renderer.texture.IIconRegister; +import net.minecraft.init.Blocks; +import net.minecraft.item.ItemStack; +import net.minecraft.util.IIcon; +import net.minecraft.world.World; +import net.minecraft.world.gen.feature.WorldGenerator; + +import cpw.mods.fml.relauncher.Side; +import cpw.mods.fml.relauncher.SideOnly; + +import net.minecraftforge.common.EnumPlantType; + +import forestry.api.apiculture.EnumBeeChromosome; +import forestry.api.arboriculture.EnumGermlingType; +import forestry.api.arboriculture.IAlleleTreeSpecies; +import forestry.api.arboriculture.ITree; +import forestry.api.arboriculture.ITreeRoot; +import forestry.api.core.IIconProvider; +import forestry.api.genetics.AlleleManager; +import forestry.api.genetics.IAllele; +import forestry.api.genetics.IClassification; +import forestry.api.genetics.IFruitFamily; +import forestry.api.genetics.IMutation; +import forestry.api.world.ITreeGenData; +import forestry.arboriculture.worldgen.WorldGenArboriculture; +import forestry.arboriculture.worldgen.WorldGenBalsa; +import forestry.core.config.ForestryItem; +import forestry.core.genetics.AlleleSpecies; +import forestry.core.render.TextureManager; +import forestry.core.utils.Utils; + +public class AlleleTreeSpecies extends AlleleSpecies implements IAlleleTreeSpecies, IIconProvider { + + private static class LeafType { + public final String ident; + public final short fancyUID; + public final short plainUID; + public final short changedUID; + + public LeafType(String ident, short fancyUID, short plainUID, short changedUID) { + this.ident = ident; + this.fancyUID = fancyUID; + this.plainUID = plainUID; + this.changedUID = changedUID; + } + } + + private static HashMap leafTypes = new HashMap(); + static { + leafTypes.put("deciduous", new LeafType("deciduous", (short) 10, (short) 11, (short) 12)); + leafTypes.put("conifers", new LeafType("conifers", (short) 15, (short) 16, (short) 17)); + leafTypes.put("jungle", new LeafType("jungle", (short) 20, (short) 21, (short) 22)); + leafTypes.put("willow", new LeafType("willow", (short) 25, (short) 26, (short) 27)); + leafTypes.put("maple", new LeafType("maple", (short) 30, (short) 31, (short) 32)); + leafTypes.put("palm", new LeafType("palm", (short) 35, (short) 36, (short) 37)); + } + + private final ITreeRoot root; + + private Class generatorClass = WorldGenBalsa.class; + + private final int primaryColour; + //private final int secondaryColour; + + private LeafType leafType; + + private int girth = 1; + private EnumPlantType nativeType = EnumPlantType.Plains; + private final ArrayList fruits = new ArrayList(); + + private ItemStack wood; + + public AlleleTreeSpecies(String uid, boolean isDominant, String name, IClassification branch, String binomial, int primaryColor, int secondaryColor) { + super(uid, isDominant, name, branch, binomial); + + this.root = (ITreeRoot)AlleleManager.alleleRegistry.getSpeciesRoot(TreeHelper.UID); + this.primaryColour = primaryColor; + //this.secondaryColour = secondaryColor; + leafType = leafTypes.get("deciduous"); + } + + public AlleleTreeSpecies(String uid, boolean isDominant, String name, IClassification branch, String binomial, int primaryColor, + Class generator, ItemStack wood) { + this(uid, isDominant, name, branch, binomial, primaryColor, Utils.multiplyRGBComponents(primaryColor, 1.35f), generator, wood); + } + + public AlleleTreeSpecies(String uid, boolean isDominant, String name, IClassification branch, String binomial, int primaryColor, int secondaryColor, + Class generator, ItemStack wood) { + super(uid, isDominant, name, branch, binomial); + + this.root = (ITreeRoot)AlleleManager.alleleRegistry.getSpeciesRoot("rootTrees"); + this.generatorClass = generator; + this.primaryColour = primaryColor; + //this.secondaryColour = secondaryColor; + leafType = leafTypes.get("deciduous"); + this.wood = wood; + } + + @Override + public ITreeRoot getRoot() { + return root; + } + + public AlleleTreeSpecies setPlantType(EnumPlantType type) { + this.nativeType = type; + return this; + } + + public AlleleTreeSpecies setGirth(int girth) { + this.girth = girth; + return this; + } + + public AlleleTreeSpecies addFruitFamily(IFruitFamily family) { + fruits.add(family); + return this; + } + + public AlleleTreeSpecies setLeafIndices(String ident) { + leafType = leafTypes.get(ident); + return this; + } + + public AlleleTreeSpecies setVanillaMap(int vanillaMeta) { + vanillaMap = vanillaMeta; + return this; + } + + /* RESEARCH */ + @Override + public int getComplexity() { + return 1 + getGeneticAdvancement(this, new ArrayList()); + } + + private int getGeneticAdvancement(IAllele species, ArrayList exclude) { + + int own = 1; + int highest = 0; + exclude.add(species); + + for(IMutation mutation : getRoot().getPaths(species, EnumBeeChromosome.SPECIES.ordinal())) { + if(!exclude.contains(mutation.getAllele0())) { + int otherAdvance = getGeneticAdvancement(mutation.getAllele0(), exclude); + if(otherAdvance > highest) + highest = otherAdvance; + } + if(!exclude.contains(mutation.getAllele1())) { + int otherAdvance = getGeneticAdvancement(mutation.getAllele1(), exclude); + if(otherAdvance > highest) + highest = otherAdvance; + } + } + + return own + (highest < 0 ? 0 : highest); + } + + /* OTHER */ + @Override + public EnumPlantType getPlantType() { + return nativeType; + } + + @Override + public ArrayList getSuitableFruit() { + return fruits; + } + + @Override + public int getGirth() { + return girth; + } + + @Override + public WorldGenerator getGenerator(ITree tree, World world, int x, int y, int z) { + try { + return generatorClass.getConstructor(new Class[] { ITreeGenData.class }).newInstance(new Object[] { tree }); + } catch (Exception ex) { + throw new RuntimeException("Failed to instantiate generator of class " + generatorClass.getName()); + } + } + + @SuppressWarnings("unchecked") + @Override + public Class[] getGeneratorClasses() { + return new Class[] { generatorClass }; + } + + @Override + public short getLeafIconIndex(ITree tree, boolean fancy) { + + if (!fancy) + return leafType.plainUID; + + if (tree.getMate() != null) + return leafType.changedUID; + + return leafType.fancyUID; + } + + public AlleleTreeSpecies setGenerator(Class generatorClass) { + this.generatorClass = generatorClass; + return this; + } + + @Override + public int getLeafColour(ITree tree) { + //if(tree == null) + // return primaryColour; + + //if (tree.getMate() != null) + // return secondaryColour; + //else + return primaryColour; + } + + /* ICONS */ + private int vanillaMap = -1; + + @Override + public int getIconColour(int renderPass) { + if(renderPass == 0) + return primaryColour; + return 0xffffff; + } + + @SideOnly(Side.CLIENT) + IIcon icon; + + @Override + @SideOnly(Side.CLIENT) + public void registerIcons(IIconRegister register) { + if (vanillaMap < 0) + icon = TextureManager.getInstance().registerTex(register, "germlings/sapling." + uid); + else + icon = Blocks.sapling.getIcon(0, vanillaMap); + TextureManager.getInstance().registerTexUID(register, leafType.plainUID, "leaves/" + leafType.ident + ".plain"); + TextureManager.getInstance().registerTexUID(register, leafType.changedUID, "leaves/" + leafType.ident + ".changed"); + TextureManager.getInstance().registerTexUID(register, leafType.fancyUID, "leaves/" + leafType.ident + ".fancy"); + } + + @Override + @SideOnly(Side.CLIENT) + public IIcon getGermlingIcon(EnumGermlingType type, int renderPass) { + if(type == EnumGermlingType.POLLEN) + return ForestryItem.pollen.item().getIconFromDamageForRenderPass(0, renderPass); + + return icon; + } + + + @Override + @SideOnly(Side.CLIENT) + public int getGermlingColour(EnumGermlingType type, int renderPass) { + if(type == EnumGermlingType.SAPLING) + return 0xFFFFFF; + return getLeafColour(null); + } + + + @Override + @SideOnly(Side.CLIENT) + public IIconProvider getIconProvider() { + return this; + } + + @Override + @SideOnly(Side.CLIENT) + public IIcon getIcon(short texUID) { + return TextureManager.getInstance().getIcon(texUID); + } + + @Override + public ItemStack[] getLogStacks() { + return new ItemStack[] {wood}; + } + +} diff --git a/forestry_common/arboriculture/forestry/arboriculture/genetics/ArboristTracker.java b/forestry_common/arboriculture/forestry/arboriculture/genetics/ArboristTracker.java new file mode 100755 index 000000000..aed6fd802 --- /dev/null +++ b/forestry_common/arboriculture/forestry/arboriculture/genetics/ArboristTracker.java @@ -0,0 +1,42 @@ +/******************************************************************************* + * Copyright 2011-2014 by SirSengir + * + * This work is licensed under a Creative Commons Attribution-NonCommercial-NoDerivs 3.0 Unported License. + * + * To view a copy of this license, visit http://creativecommons.org/licenses/by-nc-nd/3.0/. + ******************************************************************************/ +package forestry.arboriculture.genetics; + +import net.minecraft.entity.player.EntityPlayer; + +import forestry.api.arboriculture.IArboristTracker; +import forestry.api.genetics.IBreedingTracker; +import forestry.api.genetics.IIndividual; +import forestry.core.genetics.BreedingTracker; +import forestry.plugins.PluginArboriculture; + +public class ArboristTracker extends BreedingTracker implements IArboristTracker { + + public ArboristTracker(String s) { + this(s, ""); + } + + public ArboristTracker(String s, String player) { + super(s, player); + } + + @Override + protected IBreedingTracker getCommonTracker(EntityPlayer player) { + return PluginArboriculture.treeInterface.getBreedingTracker(player.worldObj, "__COMMON_"); + } + + @Override + protected String getPacketTag() { + return TreeHelper.UID; + } + + @Override + public void registerPickup(IIndividual individual) { + } + +} diff --git a/forestry_common/arboriculture/forestry/arboriculture/genetics/BranchTrees.java b/forestry_common/arboriculture/forestry/arboriculture/genetics/BranchTrees.java new file mode 100755 index 000000000..a73ad8dd6 --- /dev/null +++ b/forestry_common/arboriculture/forestry/arboriculture/genetics/BranchTrees.java @@ -0,0 +1,18 @@ +/******************************************************************************* + * Copyright 2011-2014 by SirSengir + * + * This work is licensed under a Creative Commons Attribution-NonCommercial-NoDerivs 3.0 Unported License. + * + * To view a copy of this license, visit http://creativecommons.org/licenses/by-nc-nd/3.0/. + ******************************************************************************/ +package forestry.arboriculture.genetics; + +import forestry.core.genetics.Branch; + +public class BranchTrees extends Branch { + + public BranchTrees(String uid, String scientific) { + super("trees." + uid, scientific); + } + +} diff --git a/forestry_common/arboriculture/forestry/arboriculture/genetics/GrowthProvider.java b/forestry_common/arboriculture/forestry/arboriculture/genetics/GrowthProvider.java new file mode 100755 index 000000000..24204ae92 --- /dev/null +++ b/forestry_common/arboriculture/forestry/arboriculture/genetics/GrowthProvider.java @@ -0,0 +1,133 @@ +/******************************************************************************* + * Copyright 2011-2014 by SirSengir + * + * This work is licensed under a Creative Commons Attribution-NonCommercial-NoDerivs 3.0 Unported License. + * + * To view a copy of this license, visit http://creativecommons.org/licenses/by-nc-nd/3.0/. + ******************************************************************************/ +package forestry.arboriculture.genetics; + +import net.minecraft.tileentity.TileEntity; +import net.minecraft.world.World; +import net.minecraft.world.biome.BiomeGenBase; + +import forestry.api.arboriculture.EnumGrowthConditions; +import forestry.api.arboriculture.IGrowthProvider; +import forestry.api.arboriculture.ITree; +import forestry.api.arboriculture.ITreeGenome; +import forestry.arboriculture.gadgets.TileSapling; +import forestry.core.utils.Utils; +import forestry.core.utils.Vect; + +public class GrowthProvider implements IGrowthProvider { + + @Override + public boolean canGrow(ITreeGenome genome, World world, int xPos, int yPos, int zPos, int expectedGirth, int expectedHeight) { + return hasRoom(genome, world, xPos, yPos, zPos, expectedGirth, expectedHeight) + && getGrowthConditions(genome, world, xPos, yPos, zPos) != EnumGrowthConditions.HOSTILE + && hasSufficientSaplings(genome, world, xPos, yPos, zPos, expectedGirth); + } + + @Override + public EnumGrowthConditions getGrowthConditions(ITreeGenome genome, World world, int xPos, int yPos, int zPos) { + return getConditionFromLight(world, xPos, yPos, zPos); + } + + @Override + public String getDescription() { + return "Light"; + } + + @Override + public String[] getInfo() { + return new String[0]; + } + + protected EnumGrowthConditions getConditionsFromRainfall(World world, int xPos, int yPos, int zPos, float min, float max) { + + BiomeGenBase biome = world.getWorldChunkManager().getBiomeGenAt(xPos, zPos); + if (biome.rainfall < min || biome.rainfall > max) + return EnumGrowthConditions.HOSTILE; + + return EnumGrowthConditions.EXCELLENT; + } + + protected EnumGrowthConditions getConditionsFromTemperature(World world, int xPos, int yPos, int zPos, float min, float max) { + + BiomeGenBase biome = world.getWorldChunkManager().getBiomeGenAt(xPos, zPos); + if (biome.temperature < min || biome.temperature > max) + return EnumGrowthConditions.HOSTILE; + + return EnumGrowthConditions.EXCELLENT; + } + + protected EnumGrowthConditions getConditionFromLight(World world, int xPos, int yPos, int zPos) { + int lightvalue = world.getBlockLightValue(xPos, yPos + 1, zPos); + + if (lightvalue > 13) + return EnumGrowthConditions.EXCELLENT; + else if (lightvalue > 11) + return EnumGrowthConditions.GOOD; + else if (lightvalue > 8) + return EnumGrowthConditions.NORMAL; + else if (lightvalue > 6) + return EnumGrowthConditions.PALTRY; + else + return EnumGrowthConditions.HOSTILE; + } + + /* + * protected EnumGrowthConditions getConditionFromGround(World world, int xPos, int yPos, int zPos) { Block block = Block.blocksList[world.getBlock(xPos, + * yPos - 1, zPos)]; if(block == null) return EnumGrowthConditions.HOSTILE; + * + * for(EnumPlantType type : this.validPlantTypes) { this.plantType = type; if(block.canSustainPlant(world, xPos, yPos - 1, zPos, ForgeDirection.UP, this)) + * return EnumGrowthConditions.EXCELLENT; } + * + * return EnumGrowthConditions.HOSTILE; } + */ + + protected boolean hasRoom(ITreeGenome genome, World world, int xPos, int yPos, int zPos, int expectedGirth, int expectedHeight) { + + int offset = (expectedGirth - 1) / 2; + // if(offset <= 0) + // offset = 1; + + return checkArea(world, new Vect(xPos - offset, yPos + 1, zPos + offset), + new Vect(-offset + expectedGirth, expectedHeight + 1, -offset + expectedGirth)); + } + + protected final boolean checkArea(World world, Vect start, Vect area) { + for (int x = start.x; x < start.x + area.x; x++) + for (int y = start.y; y < start.y + area.y; y++) + for (int z = start.z; z < start.z + area.z; z++) + if (!world.isAirBlock(x, y, z) && !Utils.isReplaceableBlock(world, x, y, z)) + return false; + return true; + } + + protected boolean hasSufficientSaplings(ITreeGenome genome, World world, int xPos, int yPos, int zPos, int expectedGirth) { + + if (expectedGirth == 1) + return true; + + int offset = (expectedGirth - 1) / 2; + + for (int x = xPos - offset; x < xPos - offset + expectedGirth; x++) + for (int z = zPos - offset; z < zPos - offset + expectedGirth; z++) { + + if (world.isAirBlock(x, yPos, z)) + return false; + + TileEntity tile = world.getTileEntity(x, yPos, z); + if (!(tile instanceof TileSapling)) + return false; + + ITree tree = ((TileSapling) tile).getTree(); + if (tree == null || !tree.getGenome().getPrimary().getUID().equals(genome.getPrimary().getUID())) + return false; + } + + return true; + } + +} diff --git a/forestry_common/arboriculture/forestry/arboriculture/genetics/GrowthProviderTropical.java b/forestry_common/arboriculture/forestry/arboriculture/genetics/GrowthProviderTropical.java new file mode 100755 index 000000000..aea68de0e --- /dev/null +++ b/forestry_common/arboriculture/forestry/arboriculture/genetics/GrowthProviderTropical.java @@ -0,0 +1,44 @@ +/******************************************************************************* + * Copyright 2011-2014 by SirSengir + * + * This work is licensed under a Creative Commons Attribution-NonCommercial-NoDerivs 3.0 Unported License. + * + * To view a copy of this license, visit http://creativecommons.org/licenses/by-nc-nd/3.0/. + ******************************************************************************/ +package forestry.arboriculture.genetics; + +import java.util.EnumSet; + +import net.minecraft.world.World; + +import forestry.api.arboriculture.EnumGrowthConditions; +import forestry.api.arboriculture.ITreeGenome; + +public class GrowthProviderTropical extends GrowthProvider { + + @Override + public EnumGrowthConditions getGrowthConditions(ITreeGenome genome, World world, int xPos, int yPos, int zPos) { + EnumGrowthConditions light = getConditionFromLight(world, xPos, yPos, zPos); + EnumGrowthConditions moisture = getConditionsFromRainfall(world, xPos, yPos, zPos, 0.9f, 2.0f); + EnumGrowthConditions temperature = getConditionsFromTemperature(world, xPos, yPos, zPos, 1.2f, 1.9f); + + EnumSet conditions = EnumSet.of(light, moisture, temperature); + + EnumGrowthConditions result = EnumGrowthConditions.HOSTILE; + for (EnumGrowthConditions cond : conditions) { + if (cond == EnumGrowthConditions.HOSTILE) + return EnumGrowthConditions.HOSTILE; + + if (cond.ordinal() > result.ordinal()) + result = cond; + } + + return result; + } + + @Override + public String getDescription() { + return "Tropical"; + } + +} diff --git a/forestry_common/arboriculture/forestry/arboriculture/genetics/Tree.java b/forestry_common/arboriculture/forestry/arboriculture/genetics/Tree.java new file mode 100755 index 000000000..03db049a7 --- /dev/null +++ b/forestry_common/arboriculture/forestry/arboriculture/genetics/Tree.java @@ -0,0 +1,394 @@ +/******************************************************************************* + * Copyright 2011-2014 by SirSengir + * + * This work is licensed under a Creative Commons Attribution-NonCommercial-NoDerivs 3.0 Unported License. + * + * To view a copy of this license, visit http://creativecommons.org/licenses/by-nc-nd/3.0/. + ******************************************************************************/ +package forestry.arboriculture.genetics; + +import java.util.ArrayList; +import java.util.Collection; +import java.util.EnumSet; +import java.util.List; + +import net.minecraft.block.Block; +import net.minecraft.item.ItemStack; +import net.minecraft.nbt.NBTTagCompound; +import net.minecraft.world.IBlockAccess; +import net.minecraft.world.World; +import net.minecraft.world.gen.feature.WorldGenerator; + +import net.minecraftforge.common.EnumPlantType; +import net.minecraftforge.common.IPlantable; +import net.minecraftforge.common.util.ForgeDirection; + +import forestry.api.arboriculture.EnumGrowthConditions; +import forestry.api.arboriculture.EnumTreeChromosome; +import forestry.api.arboriculture.IAlleleLeafEffect; +import forestry.api.arboriculture.IAlleleTreeSpecies; +import forestry.api.arboriculture.IFruitProvider; +import forestry.api.arboriculture.ITree; +import forestry.api.arboriculture.ITreeGenome; +import forestry.api.arboriculture.ITreeMutation; +import forestry.api.genetics.IAllele; +import forestry.api.genetics.IChromosome; +import forestry.api.genetics.IEffectData; +import forestry.api.genetics.IFruitFamily; +import forestry.api.genetics.IGenome; +import forestry.api.world.ITreeGenData; +import forestry.core.genetics.Allele; +import forestry.core.genetics.Chromosome; +import forestry.core.genetics.Individual; +import forestry.core.utils.StringUtil; +import forestry.plugins.PluginArboriculture; + +public class Tree extends Individual implements ITree, ITreeGenData, IPlantable { + + private ITreeGenome genome; + private ITreeGenome mate; + + /* CONSTRUCTOR */ + public Tree(NBTTagCompound nbttagcompound) { + readFromNBT(nbttagcompound); + } + + public Tree(ITreeGenome genome) { + this.genome = genome; + } + + public Tree(World world, ITreeGenome genome) { + this.genome = genome; + + } + + /* SAVING & LOADING */ + @Override + public void readFromNBT(NBTTagCompound nbttagcompound) { + + super.readFromNBT(nbttagcompound); + + if (nbttagcompound.hasKey("Genome")) + genome = new TreeGenome(nbttagcompound.getCompoundTag("Genome")); + else + genome = PluginArboriculture.treeInterface.templateAsGenome(TreeTemplates.getOakTemplate()); + if (nbttagcompound.hasKey("Mate")) + mate = new TreeGenome(nbttagcompound.getCompoundTag("Mate")); + + } + + @Override + public void writeToNBT(NBTTagCompound nbttagcompound) { + + super.writeToNBT(nbttagcompound); + + if (genome != null) { + NBTTagCompound NBTmachine = new NBTTagCompound(); + genome.writeToNBT(NBTmachine); + nbttagcompound.setTag("Genome", NBTmachine); + } + if (mate != null) { + NBTTagCompound NBTmachine = new NBTTagCompound(); + mate.writeToNBT(NBTmachine); + nbttagcompound.setTag("Mate", NBTmachine); + } + + } + + /* INTERACTION */ + @Override + public void mate(ITree other) { + mate = new TreeGenome(other.getGenome().getChromosomes()); + } + + /* EFFECTS */ + @Override + public IEffectData[] doEffect(IEffectData[] storedData, World world, int biomeid, int x, int y, int z) { + IAlleleLeafEffect effect = (IAlleleLeafEffect) getGenome().getActiveAllele(EnumTreeChromosome.EFFECT.ordinal()); + + if (effect == null) + return null; + + storedData[0] = doEffect(effect, storedData[0], world, biomeid, x, y, z); + + // Return here if the primary can already not be combined + if (!effect.isCombinable()) + return storedData; + + IAlleleLeafEffect secondary = (IAlleleLeafEffect) getGenome().getInactiveAllele(EnumTreeChromosome.EFFECT.ordinal()); + if (!secondary.isCombinable()) + return storedData; + + storedData[1] = doEffect(secondary, storedData[1], world, biomeid, x, y, z); + + return storedData; + } + + private IEffectData doEffect(IAlleleLeafEffect effect, IEffectData storedData, World world, int biomeid, int x, int y, int z) { + storedData = effect.validateStorage(storedData); + return effect.doEffect(getGenome(), storedData, world, x, y, z); + } + + @Override + public IEffectData[] doFX(IEffectData[] storedData, World world, int biomeid, int x, int y, int z) { + return null; + } + + /* GROWTH */ + @Override + public WorldGenerator getTreeGenerator(World world, int x, int y, int z, boolean wasBonemealed) { + return genome.getPrimary().getGenerator(this, world, x, y, z); + } + + @Override + public boolean canStay(World world, int x, int y, int z) { + Block block = world.getBlock(x, y - 1, z); + if (block == null) + return false; + + for (EnumPlantType type : getPlantTypes()) { + this.plantType = type; + if (block.canSustainPlant(world, x, y - 1, z, ForgeDirection.UP, this)) + return true; + } + + return false; + } + + private EnumPlantType plantType; + + @Override + public EnumPlantType getPlantType(IBlockAccess world, int x, int y, int z) { + return plantType; + } + + @Override + public Block getPlant(IBlockAccess world, int x, int y, int z) { + return null; + } + + @Override + public int getPlantMetadata(IBlockAccess world, int x, int y, int z) { + return 0; + } + + @Override + public boolean canGrow(World world, int x, int y, int z, int expectedGirth, int expectedHeight) { + return genome.getGrowthProvider().canGrow(genome, world, x, y, z, expectedGirth, expectedHeight); + } + + @Override + public int getRequiredMaturity() { + return genome.getMaturationTime(); + } + + @Override + public EnumGrowthConditions getGrowthCondition(World world, int x, int y, int z) { + return genome.getGrowthProvider().getGrowthConditions(getGenome(), world, x, y, z); + } + + @Override + public int getGirth(World world, int x, int y, int z) { + return genome.getGirth(); + } + + @Override + public int getResilience() { + int base = (int)(getGenome().getFertility() * getGenome().getSappiness() * 100); + return (base > 1 ? base : 1) * 10; + } + + @Override + public float getHeightModifier() { + return genome.getHeight(); + } + + @Override + public void setLeaves(World world, String owner, int x, int y, int z) { + PluginArboriculture.treeInterface.setLeaves(world, this, owner, x, y, z); + } + + @Override + public boolean allowsFruitBlocks() { + IFruitProvider provider = getGenome().getFruitProvider(); + if (!provider.requiresFruitBlocks()) + return false; + + Collection suitable = genome.getPrimary().getSuitableFruit(); + if (!suitable.contains(provider.getFamily())) + return false; + + return true; + } + + @Override + public boolean trySpawnFruitBlock(World world, int x, int y, int z) { + IFruitProvider provider = getGenome().getFruitProvider(); + Collection suitable = genome.getPrimary().getSuitableFruit(); + if (!suitable.contains(provider.getFamily())) + return false; + + return provider.trySpawnFruitBlock(getGenome(), world, x, y, z); + } + + /* INFORMATION */ + @Override + public ITreeGenome getGenome() { + return this.genome; + } + + @Override + public ITree copy() { + NBTTagCompound nbttagcompound = new NBTTagCompound(); + this.writeToNBT(nbttagcompound); + return new Tree(nbttagcompound); + } + + @Override + public ITreeGenome getMate() { + return this.mate; + } + + @Override + public boolean isPureBred(EnumTreeChromosome chromosome) { + return genome.getActiveAllele(chromosome.ordinal()).getUID().equals(genome.getInactiveAllele(chromosome.ordinal()).getUID()); + } + + @Override + public EnumSet getPlantTypes() { + EnumSet tolerated = genome.getPlantTypes(); + tolerated.add(genome.getPrimary().getPlantType()); + return tolerated; + } + + @Override + public void addTooltip(List list) { + + // No info 4 u! + if (!isAnalyzed) { + list.add("<" + StringUtil.localize("gui.unknown") + ">"); + return; + } + + // You analyzed it? Juicy tooltip coming up! + IAlleleTreeSpecies primary = genome.getPrimary(); + IAlleleTreeSpecies secondary = genome.getSecondary(); + if (!isPureBred(EnumTreeChromosome.SPECIES)) + list.add("\u00A79" + primary.getName() + "-" + secondary.getName() + " " + StringUtil.localize("gui.hybrid")); + list.add(String.format("\u00A76S: %s, \u00A7cM: %s", genome.getActiveAllele(EnumTreeChromosome.SAPPINESS.ordinal()).getName(), genome.getActiveAllele(EnumTreeChromosome.MATURATION.ordinal()).getName())); + list.add(String.format("\u00A7dH: %s, \u00A7bG: %sx%s", genome.getActiveAllele(EnumTreeChromosome.HEIGHT.ordinal()).getName(), genome.getGirth(), genome.getGirth())); + + list.add(String.format("\u00A7eS: %s, \u00A7fY: %s", genome.getActiveAllele(EnumTreeChromosome.FERTILITY.ordinal()).getName(), genome.getActiveAllele(EnumTreeChromosome.YIELD.ordinal()).getName())); + + IAllele fruit = getGenome().getActiveAllele(EnumTreeChromosome.FRUITS.ordinal()); + if(fruit != Allele.fruitNone) { + String strike = ""; + if (!canBearFruit()) + strike = "\u00A7m"; + list.add(strike + "\u00A7aF: " + StringUtil.localize(genome.getFruitProvider().getDescription())); + } + + } + + /* REPRODUCTION */ + @Override + public ITree[] getSaplings(World world, int x, int y, int z, float modifier) { + ArrayList prod = new ArrayList(); + + float chance = genome.getFertility() * modifier; + + if (world.rand.nextFloat() <= chance) + if (this.getMate() == null) + prod.add(PluginArboriculture.treeInterface.getTree(world, new TreeGenome(genome.getChromosomes()))); + else + prod.add(createOffspring(world, x, y, z)); + + return prod.toArray(new ITree[0]); + } + + private ITree createOffspring(World world, int x, int y, int z) { + + IChromosome[] chromosomes = new IChromosome[genome.getChromosomes().length]; + IChromosome[] parent1 = genome.getChromosomes(); + IChromosome[] parent2 = mate.getChromosomes(); + + // Check for mutation. Replace one of the parents with the mutation + // template if mutation occured. + IChromosome[] mutated = mutateSpecies(world, x, y, z, genome, mate); + if (mutated == null) + mutated = mutateSpecies(world, x, y, z, mate, genome); + + if (mutated != null) + return new Tree(world, new TreeGenome(mutated)); + + for (int i = 0; i < parent1.length; i++) + if (parent1[i] != null && parent2[i] != null) + chromosomes[i] = Chromosome.inheritChromosome(world.rand, parent1[i], parent2[i]); + + return new Tree(world, new TreeGenome(chromosomes)); + } + + private IChromosome[] mutateSpecies(World world, int x, int y, int z, IGenome genomeOne, IGenome genomeTwo) { + + IChromosome[] parent1 = genomeOne.getChromosomes(); + IChromosome[] parent2 = genomeTwo.getChromosomes(); + + IGenome genome0; + IGenome genome1; + IAllele allele0; + IAllele allele1; + + if (world.rand.nextBoolean()) { + allele0 = parent1[EnumTreeChromosome.SPECIES.ordinal()].getPrimaryAllele(); + allele1 = parent2[EnumTreeChromosome.SPECIES.ordinal()].getSecondaryAllele(); + + genome0 = genomeOne; + genome1 = genomeTwo; + } else { + allele0 = parent2[EnumTreeChromosome.SPECIES.ordinal()].getPrimaryAllele(); + allele1 = parent1[EnumTreeChromosome.SPECIES.ordinal()].getSecondaryAllele(); + + genome0 = genomeTwo; + genome1 = genomeOne; + } + + for (ITreeMutation mutation : PluginArboriculture.treeInterface.getMutations(true)) { + float chance = 0; + + // Stop blacklisted species. + // if (BeeManager.breedingManager.isBlacklisted(mutation.getTemplate()[0].getUID())) { + // continue; + // } + + if ((chance = mutation.getChance(world, x, y, z, allele0, allele1, genome0, genome1)) > 0) + if (world.rand.nextFloat()*100 < chance) + // IApiaristTracker breedingTracker = BeeManager.breedingManager.getApiaristTracker(world); + // breedingTracker.registerMutation(mutation); + return PluginArboriculture.treeInterface.templateAsChromosomes(mutation.getTemplate()); + } + + return null; + } + + /* PRODUCTION */ + @Override + public boolean canBearFruit() { + return genome.getPrimary().getSuitableFruit().contains(genome.getFruitProvider().getFamily()); + } + + @Override + public ItemStack[] getProduceList() { + return genome.getFruitProvider().getProducts(); + } + + @Override + public ItemStack[] getSpecialtyList() { + return genome.getFruitProvider().getSpecialty(); + } + + @Override + public ItemStack[] produceStacks(World world, int x, int y, int z, int ripeningTime) { + return genome.getFruitProvider().getFruits(genome, world, x, y, z, ripeningTime); + } + +} diff --git a/forestry_common/arboriculture/forestry/arboriculture/genetics/TreeGenome.java b/forestry_common/arboriculture/forestry/arboriculture/genetics/TreeGenome.java new file mode 100755 index 000000000..c4a56189d --- /dev/null +++ b/forestry_common/arboriculture/forestry/arboriculture/genetics/TreeGenome.java @@ -0,0 +1,143 @@ +/******************************************************************************* + * Copyright 2011-2014 by SirSengir + * + * This work is licensed under a Creative Commons Attribution-NonCommercial-NoDerivs 3.0 Unported License. + * + * To view a copy of this license, visit http://creativecommons.org/licenses/by-nc-nd/3.0/. + ******************************************************************************/ +package forestry.arboriculture.genetics; + +import java.util.EnumSet; + +import net.minecraft.nbt.NBTTagCompound; + +import net.minecraftforge.common.EnumPlantType; + +import forestry.api.arboriculture.EnumTreeChromosome; +import forestry.api.arboriculture.IAlleleFruit; +import forestry.api.arboriculture.IAlleleGrowth; +import forestry.api.arboriculture.IAlleleLeafEffect; +import forestry.api.arboriculture.IAlleleTreeSpecies; +import forestry.api.arboriculture.IFruitProvider; +import forestry.api.arboriculture.IGrowthProvider; +import forestry.api.arboriculture.ITreeGenome; +import forestry.api.genetics.IAllele; +import forestry.api.genetics.IAlleleFloat; +import forestry.api.genetics.IAlleleInteger; +import forestry.api.genetics.IChromosome; +import forestry.api.genetics.ISpeciesRoot; +import forestry.core.genetics.Allele; +import forestry.core.genetics.AllelePlantType; +import forestry.core.genetics.Chromosome; +import forestry.core.genetics.Genome; +import forestry.plugins.PluginArboriculture; + +public class TreeGenome extends Genome implements ITreeGenome { + + public TreeGenome(IChromosome[] chromosomes) { + super(chromosomes); + } + + public TreeGenome(NBTTagCompound nbttagcompound) { + super(nbttagcompound); + } + + @Override + public IAlleleTreeSpecies getPrimary() { + return (IAlleleTreeSpecies) getActiveAllele(EnumTreeChromosome.SPECIES.ordinal()); + } + + @Override + public IAlleleTreeSpecies getSecondary() { + return (IAlleleTreeSpecies) getInactiveAllele(EnumTreeChromosome.SPECIES.ordinal()); + } + + @Override + public IFruitProvider getFruitProvider() { + return ((IAlleleFruit) getActiveAllele(EnumTreeChromosome.FRUITS.ordinal())).getProvider(); + } + + @Override + public IGrowthProvider getGrowthProvider() { + return ((IAlleleGrowth) getActiveAllele(EnumTreeChromosome.GROWTH.ordinal())).getProvider(); + } + + @Override + public float getHeight() { + return ((IAlleleFloat) getActiveAllele(EnumTreeChromosome.HEIGHT.ordinal())).getValue(); + } + + @Override + public float getFertility() { + return ((IAlleleFloat) getActiveAllele(EnumTreeChromosome.FERTILITY.ordinal())).getValue(); + } + + @Override + public float getYield() { + return ((IAlleleFloat) getActiveAllele(EnumTreeChromosome.YIELD.ordinal())).getValue(); + } + + @Override + public float getSappiness() { + // FIXME: Legacy handling. + if (getChromosomes()[EnumTreeChromosome.SAPPINESS.ordinal()] == null) + getChromosomes()[EnumTreeChromosome.SAPPINESS.ordinal()] = new Chromosome(Allele.sappinessLowest); + + IAllele allele = getActiveAllele(EnumTreeChromosome.SAPPINESS.ordinal()); + // FIXME: More legacy handling + if (allele instanceof IAlleleFloat) + return ((IAlleleFloat) allele).getValue(); + else { + getChromosomes()[EnumTreeChromosome.SAPPINESS.ordinal()] = new Chromosome(Allele.sappinessLowest); + return 0.1f; + } + } + + @Override + public EnumSet getPlantTypes() { + // / FIXME: Needs some legacy handling. + if (!(getActiveAllele(EnumTreeChromosome.PLANT.ordinal()) instanceof AllelePlantType)) + getChromosomes()[EnumTreeChromosome.PLANT.ordinal()] = new Chromosome(Allele.plantTypeNone); + + return ((AllelePlantType) getActiveAllele(EnumTreeChromosome.PLANT.ordinal())).getPlantTypes(); + } + + @Override + public int getMaturationTime() { + if (getChromosomes()[EnumTreeChromosome.MATURATION.ordinal()] == null) + getChromosomes()[EnumTreeChromosome.MATURATION.ordinal()] = new Chromosome(Allele.maturationSlowest); + + return ((IAlleleInteger) getActiveAllele(EnumTreeChromosome.MATURATION.ordinal())).getValue(); + } + + private IAllele translateGirth(int girth) { + switch (girth) { + case 2: + return Allele.int2; + case 3: + return Allele.int3; + default: + return Allele.int1; + } + } + + @Override + public int getGirth() { + if (getChromosomes()[EnumTreeChromosome.GIRTH.ordinal()] == null) + getChromosomes()[EnumTreeChromosome.GIRTH.ordinal()] = new Chromosome(translateGirth(getPrimary().getGirth()), + translateGirth(getSecondary().getGirth())); + + return ((IAlleleInteger) getActiveAllele(EnumTreeChromosome.GIRTH.ordinal())).getValue(); + } + + @Override + public IAlleleLeafEffect getEffect() { + return (IAlleleLeafEffect) getActiveAllele(EnumTreeChromosome.EFFECT.ordinal()); + } + + @Override + public ISpeciesRoot getSpeciesRoot() { + return PluginArboriculture.treeInterface; + } + +} diff --git a/forestry_common/arboriculture/forestry/arboriculture/genetics/TreeHelper.java b/forestry_common/arboriculture/forestry/arboriculture/genetics/TreeHelper.java new file mode 100755 index 000000000..5d8ce3f54 --- /dev/null +++ b/forestry_common/arboriculture/forestry/arboriculture/genetics/TreeHelper.java @@ -0,0 +1,391 @@ +/******************************************************************************* + * Copyright 2011-2014 by SirSengir + * + * This work is licensed under a Creative Commons Attribution-NonCommercial-NoDerivs 3.0 Unported License. + * + * To view a copy of this license, visit http://creativecommons.org/licenses/by-nc-nd/3.0/. + ******************************************************************************/ +package forestry.arboriculture.genetics; + +import java.util.ArrayList; +import java.util.Collection; +import java.util.Collections; +import java.util.Iterator; +import java.util.LinkedList; +import java.util.Locale; +import java.util.Map.Entry; + +import net.minecraft.init.Blocks; +import net.minecraft.item.Item; +import net.minecraft.item.ItemStack; +import net.minecraft.nbt.NBTTagCompound; +import net.minecraft.tileentity.TileEntity; +import net.minecraft.world.World; + +import cpw.mods.fml.common.FMLCommonHandler; + +import forestry.api.arboriculture.EnumGermlingType; +import forestry.api.arboriculture.EnumTreeChromosome; +import forestry.api.arboriculture.IAlleleFruit; +import forestry.api.arboriculture.IAlleleTreeSpecies; +import forestry.api.arboriculture.IArboristTracker; +import forestry.api.arboriculture.ILeafTickHandler; +import forestry.api.arboriculture.ITree; +import forestry.api.arboriculture.ITreeGenome; +import forestry.api.arboriculture.ITreeMutation; +import forestry.api.arboriculture.ITreeRoot; +import forestry.api.arboriculture.ITreekeepingMode; +import forestry.api.genetics.AlleleManager; +import forestry.api.genetics.IAllele; +import forestry.api.genetics.IChromosomeType; +import forestry.api.genetics.IIndividual; +import forestry.api.genetics.IMutation; +import forestry.arboriculture.gadgets.BlockFruitPod; +import forestry.arboriculture.gadgets.TileFruitPod; +import forestry.arboriculture.gadgets.TileLeaves; +import forestry.arboriculture.gadgets.TileSapling; +import forestry.core.config.Defaults; +import forestry.core.config.ForestryBlock; +import forestry.core.config.ForestryItem; +import forestry.core.genetics.SpeciesRoot; +import forestry.core.utils.BlockUtil; +import forestry.plugins.PluginArboriculture; + +public class TreeHelper extends SpeciesRoot implements ITreeRoot { + + public static final String UID = "rootTrees"; + public static int treeSpeciesCount = -1; + + @Override + public String getUID() { + return UID; + } + + public TreeHelper() { + setResearchSuitability(new ItemStack(Blocks.sapling, 1, Defaults.WILDCARD), 1.0f); + } + + @Override + public Class getMemberClass() { + return ITree.class; + } + + @Override + public int getSpeciesCount() { + if (treeSpeciesCount < 0) { + treeSpeciesCount = 0; + Iterator > it = AlleleManager.alleleRegistry.getRegisteredAlleles().entrySet().iterator(); + while (it.hasNext()) { + Entry entry = it.next(); + if (entry.getValue() instanceof IAlleleTreeSpecies) + if (((IAlleleTreeSpecies) entry.getValue()).isCounted()) + treeSpeciesCount++; + } + } + + return treeSpeciesCount; + } + + @Override + public boolean isMember(ItemStack itemstack) { + return getType(itemstack) != EnumGermlingType.NONE; + } + + @Override + public boolean isMember(ItemStack stack, int type) { + return getType(stack).ordinal() == type; + } + + @Override + public boolean isMember(IIndividual individual) { + return individual instanceof ITree; + } + + /* TREE SPECIFIC */ + @Override + public EnumGermlingType getType(ItemStack stack) { + if(stack == null) + return EnumGermlingType.NONE; + + if(ForestryItem.sapling.isItemEqual(stack)) + return EnumGermlingType.SAPLING; + else if(ForestryItem.pollenFertile.isItemEqual(stack)) + return EnumGermlingType.POLLEN; + + return EnumGermlingType.NONE; + } + + @Override + public ITree getTree(World world, int x, int y, int z) { + TileEntity tile = world.getTileEntity(x, y, z); + if (!(tile instanceof TileSapling)) + return null; + + return ((TileSapling) tile).getTree(); + } + + @Override + public ITree getMember(ItemStack itemstack) { + if (!isMember(itemstack)) + return null; + if (itemstack.getTagCompound() == null) + return null; + + return new Tree(itemstack.getTagCompound()); + } + + @Override + public ITree getMember(NBTTagCompound compound) { + return new Tree(compound); + } + + @Override + public ITree getTree(World world, ITreeGenome genome) { + return new Tree(genome); + } + + @Override + public ItemStack getMemberStack(IIndividual tree, int type) { + + Item germlingItem; + switch (EnumGermlingType.VALUES[type]) { + case SAPLING: + germlingItem = ForestryItem.sapling.item(); + break; + case POLLEN: + germlingItem = ForestryItem.pollenFertile.item(); + break; + default: + return null; + } + + NBTTagCompound nbttagcompound = new NBTTagCompound(); + tree.writeToNBT(nbttagcompound); + + ItemStack treeStack = new ItemStack(germlingItem); + treeStack.setTagCompound(nbttagcompound); + + return treeStack; + + } + + @Override + public boolean plantSapling(World world, ITree tree, String owner, int x, int y, int z) { + + boolean placed = world.setBlock(x, y, z, ForestryBlock.saplingGE, 0, Defaults.FLAG_BLOCK_SYNCH); + if (!placed) + return false; + + if (world.getBlock(x, y, z) != ForestryBlock.saplingGE) + return false; + + TileEntity tile = world.getTileEntity(x, y, z); + if (!(tile instanceof TileSapling)) { + world.setBlockToAir(x, y, z); + return false; + } + + TileSapling sapling = (TileSapling) tile; + sapling.setTree(tree.copy()); + sapling.setOwner(owner); + world.markBlockForUpdate(x, y, z); + + return true; + } + + @Override + public boolean setLeaves(World world, IIndividual tree, String owner, int x, int y, int z) { + + boolean placed = world.setBlock(x, y, z, ForestryBlock.leaves, 0, Defaults.FLAG_BLOCK_SYNCH); + if (!placed) + return false; + + if (world.getBlock(x, y, z) != ForestryBlock.leaves) + return false; + + TileEntity tile = world.getTileEntity(x, y, z); + if (!(tile instanceof TileLeaves)) { + world.setBlockToAir(x, y, z); + return false; + } + + TileLeaves leaves = (TileLeaves) tile; + leaves.setTree((ITree) tree.copy()); + leaves.setOwner(owner); + world.markBlockForUpdate(x, y, z); + + return true; + } + + @Override + public boolean setFruitBlock(World world, IAlleleFruit allele, float sappiness, short[] indices, int x, int y, int z) { + + int direction = BlockUtil.getDirectionalMetadata(world, x, y, z); + if (direction < 0) + return false; + boolean placed = world.setBlock(x, y, z, ForestryBlock.pods, direction, Defaults.FLAG_BLOCK_SYNCH); + if (!placed) + return false; + + if (world.getBlock(x, y, z) != ForestryBlock.pods) + return false; + + TileFruitPod pod = BlockFruitPod.getPodTile(world, x, y, z); + if (pod == null) { + world.setBlockToAir(x, y, z); + return false; + } + pod.setFruit(allele, sappiness, indices); + world.markBlockForUpdate(x, y, z); + return true; + } + + /* GENOME CONVERSIONS */ + @Override + public ITreeGenome templateAsGenome(IAllele[] template) { + return new TreeGenome(templateAsChromosomes(template)); + } + + @Override + public ITreeGenome templateAsGenome(IAllele[] templateActive, IAllele[] templateInactive) { + return new TreeGenome(templateAsChromosomes(templateActive, templateInactive)); + } + + @Override + public ITree templateAsIndividual(IAllele[] template) { + return new Tree(templateAsGenome(template)); + } + + @Override + public ITree templateAsIndividual(IAllele[] templateActive, IAllele[] templateInactive) { + return new Tree(templateAsGenome(templateActive, templateInactive)); + } + + /* BREEDING TRACKER */ + @Override + public IArboristTracker getBreedingTracker(World world, String player) { + String filename = "ArboristTracker." + player; + ArboristTracker tracker = (ArboristTracker) world.loadItemData(ArboristTracker.class, filename); + + // Create a tracker if there is none yet. + if (tracker == null) { + tracker = new ArboristTracker(filename, player); + world.setItemData(filename, tracker); + } + + return tracker; + } + + /* BREEDING MODES */ + ArrayList treekeepingModes = new ArrayList(); + public static ITreekeepingMode activeTreekeepingMode; + + @Override + public ArrayList getTreekeepingModes() { + return this.treekeepingModes; + } + + @Override + public ITreekeepingMode getTreekeepingMode(World world) { + if (activeTreekeepingMode != null) + return activeTreekeepingMode; + + // No Treekeeping mode yet, item it. + IArboristTracker tracker = getBreedingTracker(world, "__COMMON_"); + String mode = tracker.getModeName(); + if (mode == null || mode.isEmpty()) + mode = PluginArboriculture.treekeepingMode; + + setTreekeepingMode(world, mode); + FMLCommonHandler.instance().getFMLLogger().debug("Set Treekeeping mode for a world to " + mode); + + return activeTreekeepingMode; + } + + @Override + public void registerTreekeepingMode(ITreekeepingMode mode) { + treekeepingModes.add(mode); + } + + @Override + public void setTreekeepingMode(World world, String name) { + activeTreekeepingMode = getTreekeepingMode(name); + getBreedingTracker(world, "__COMMON_").setModeName(name); + } + + @Override + public ITreekeepingMode getTreekeepingMode(String name) { + for (ITreekeepingMode mode : treekeepingModes) + if (mode.getName().equals(name) || mode.getName().equals(name.toLowerCase(Locale.ENGLISH))) + return mode; + + FMLCommonHandler.instance().getFMLLogger().debug("Failed to find a Treekeeping mode called '%s', reverting to fallback."); + return treekeepingModes.get(0); + } + + /* TEMPLATES */ + public static ArrayList treeTemplates = new ArrayList(); + + @Override + public ArrayList getIndividualTemplates() { + return treeTemplates; + } + + @Override + public void registerTemplate(String identifier, IAllele[] template) { + treeTemplates.add(new Tree(PluginArboriculture.treeInterface.templateAsGenome(template))); + speciesTemplates.put(identifier, template); + } + + @Override + public IAllele[] getDefaultTemplate() { + return TreeTemplates.getDefaultTemplate(); + } + + /* MUTATIONS */ + private static ArrayList treeMutations = new ArrayList(); + + @Override + public ArrayList getMutations(boolean shuffle) { + if (shuffle) + Collections.shuffle(treeMutations); + return treeMutations; + } + + @Override + public void registerMutation(IMutation mutation) { + if (AlleleManager.alleleRegistry.isBlacklisted(mutation.getTemplate()[0].getUID())) + return; + if (AlleleManager.alleleRegistry.isBlacklisted(mutation.getAllele0().getUID())) + return; + if (AlleleManager.alleleRegistry.isBlacklisted(mutation.getAllele1().getUID())) + return; + + treeMutations.add((ITreeMutation)mutation); + } + + /* ILEAFTICKHANDLER */ + private final LinkedList leafTickHandlers = new LinkedList(); + + @Override + public void registerLeafTickHandler(ILeafTickHandler handler) { + leafTickHandlers.add(handler); + } + + @Override + public Collection getLeafTickHandlers() { + return leafTickHandlers; + } + + @Override + public IChromosomeType[] getKaryotype() { + return EnumTreeChromosome.values(); + } + + @Override + public IChromosomeType getKaryotypeKey() { + return EnumTreeChromosome.SPECIES; + } + + +} diff --git a/forestry_common/arboriculture/forestry/arboriculture/genetics/TreeMutation.java b/forestry_common/arboriculture/forestry/arboriculture/genetics/TreeMutation.java new file mode 100755 index 000000000..6d3a3d4cf --- /dev/null +++ b/forestry_common/arboriculture/forestry/arboriculture/genetics/TreeMutation.java @@ -0,0 +1,58 @@ +/******************************************************************************* + * Copyright 2011-2014 by SirSengir + * + * This work is licensed under a Creative Commons Attribution-NonCommercial-NoDerivs 3.0 Unported License. + * + * To view a copy of this license, visit http://creativecommons.org/licenses/by-nc-nd/3.0/. + ******************************************************************************/ +package forestry.arboriculture.genetics; + +import net.minecraft.world.World; +import net.minecraft.world.biome.BiomeGenBase; + +import forestry.api.arboriculture.ITreeGenome; +import forestry.api.arboriculture.ITreeMutation; +import forestry.api.arboriculture.ITreeRoot; +import forestry.api.genetics.AlleleManager; +import forestry.api.genetics.IAllele; +import forestry.api.genetics.IGenome; +import forestry.core.genetics.Mutation; +import forestry.plugins.PluginArboriculture; + +public class TreeMutation extends Mutation implements ITreeMutation { + + private ITreeRoot root; + + public TreeMutation(IAllele allele0, IAllele allele1, IAllele[] template, int chance) { + super(allele0, allele1, template, chance); + + root = (ITreeRoot)AlleleManager.alleleRegistry.getSpeciesRoot("rootTrees"); + PluginArboriculture.treeInterface.registerMutation(this); + } + + @Override + public ITreeRoot getRoot() { + return root; + } + + @Override + public float getChance(World world, int x, int y, int z, IAllele allele0, IAllele allele1, IGenome genome0, IGenome genome1) { + float processedChance = chance; + + BiomeGenBase biome = world.getWorldChunkManager().getBiomeGenAt(x, z); + if (biome.temperature < minTemperature || biome.temperature > maxTemperature) + return 0; + if (biome.rainfall < minRainfall || biome.rainfall > maxRainfall) + return 0; + + processedChance *= PluginArboriculture.treeInterface.getTreekeepingMode(world).getMutationModifier((ITreeGenome) genome0, (ITreeGenome) genome1, 1f); + + if (this.allele0.getUID().equals(allele0.getUID()) && this.allele1.getUID().equals(allele1.getUID())) + return processedChance; + if (this.allele1.getUID().equals(allele0.getUID()) && this.allele0.getUID().equals(allele1.getUID())) + return processedChance; + + return 0; + } + +} diff --git a/forestry_common/arboriculture/forestry/arboriculture/genetics/TreeTemplates.java b/forestry_common/arboriculture/forestry/arboriculture/genetics/TreeTemplates.java new file mode 100755 index 000000000..59fc9e0f5 --- /dev/null +++ b/forestry_common/arboriculture/forestry/arboriculture/genetics/TreeTemplates.java @@ -0,0 +1,385 @@ +/******************************************************************************* + * Copyright 2011-2014 by SirSengir + * + * This work is licensed under a Creative Commons Attribution-NonCommercial-NoDerivs 3.0 Unported License. + * + * To view a copy of this license, visit http://creativecommons.org/licenses/by-nc-nd/3.0/. + ******************************************************************************/ +package forestry.arboriculture.genetics; + +import forestry.api.arboriculture.EnumTreeChromosome; +import forestry.api.arboriculture.ITreeGenome; +import forestry.api.genetics.IAllele; +import forestry.api.genetics.IMutation; +import forestry.core.genetics.Allele; +import forestry.core.genetics.Chromosome; + +public class TreeTemplates { + + /* MUTATIONS */ + public static IMutation larchA; + public static IMutation larchB; + public static IMutation pineA; + public static IMutation sequoiaA; + + public static IMutation limeA; + + public static IMutation cherryA; + public static IMutation cherryB; + + public static IMutation walnutA; + public static IMutation chestnutA; + public static IMutation chestnutB; + + public static IMutation teakA; + public static IMutation kapokA; + public static IMutation ebonyA; + public static IMutation mahoganyA; + + public static IMutation balsaA; + public static IMutation acaciaA; + public static IMutation wengeA; + public static IMutation baobabA; + + public static IMutation willowA; + public static IMutation willowB; + public static IMutation willowC; + + public static IMutation sipiriA; + + public static IMutation mahoeA; + + public static IMutation poplarA; + public static IMutation poplarB; + public static IMutation poplarC; + + public static IMutation lemonA; + public static IMutation plumA; + + public static IMutation mapleA; + + public static IMutation papayaA; + public static IMutation dateA; + + /* TEMPLATES */ + public static IAllele[] getDefaultTemplate() { + IAllele[] alleles = new IAllele[EnumTreeChromosome.values().length]; + + alleles[EnumTreeChromosome.SPECIES.ordinal()] = Allele.treeOak; + alleles[EnumTreeChromosome.FRUITS.ordinal()] = Allele.fruitNone; + alleles[EnumTreeChromosome.GROWTH.ordinal()] = Allele.growthLightlevel; + alleles[EnumTreeChromosome.HEIGHT.ordinal()] = Allele.heightSmall; + alleles[EnumTreeChromosome.FERTILITY.ordinal()] = Allele.saplingsLower; + alleles[EnumTreeChromosome.YIELD.ordinal()] = Allele.yieldLowest; + alleles[EnumTreeChromosome.PLANT.ordinal()] = Allele.plantTypeNone; + alleles[EnumTreeChromosome.SAPPINESS.ordinal()] = Allele.sappinessLowest; + alleles[EnumTreeChromosome.TERRITORY.ordinal()] = Allele.territoryDefault; + alleles[EnumTreeChromosome.EFFECT.ordinal()] = Allele.leavesNone; + alleles[EnumTreeChromosome.MATURATION.ordinal()] = Allele.maturationAverage; + alleles[EnumTreeChromosome.GIRTH.ordinal()] = Allele.int1; + + return alleles; + } + + public static IAllele[] getOakTemplate() { + IAllele[] alleles = getDefaultTemplate(); + alleles[EnumTreeChromosome.FRUITS.ordinal()] = Allele.fruitApple; + alleles[EnumTreeChromosome.FERTILITY.ordinal()] = Allele.saplingsAverage; + alleles[EnumTreeChromosome.MATURATION.ordinal()] = Allele.maturationFaster; + return alleles; + } + + public static IAllele[] getBirchTemplate() { + IAllele[] alleles = getDefaultTemplate(); + alleles[EnumTreeChromosome.SPECIES.ordinal()] = Allele.treeBirch; + alleles[EnumTreeChromosome.FERTILITY.ordinal()] = Allele.saplingsAverage; + alleles[EnumTreeChromosome.MATURATION.ordinal()] = Allele.maturationFaster; + return alleles; + } + + public static IAllele[] getSpruceTemplate() { + IAllele[] alleles = getDefaultTemplate(); + alleles[EnumTreeChromosome.SPECIES.ordinal()] = Allele.treeSpruce; + alleles[EnumTreeChromosome.FERTILITY.ordinal()] = Allele.saplingsAverage; + alleles[EnumTreeChromosome.HEIGHT.ordinal()] = Allele.heightAverage; + alleles[EnumTreeChromosome.MATURATION.ordinal()] = Allele.maturationFaster; + return alleles; + } + + public static IAllele[] getJungleTemplate() { + IAllele[] alleles = getDefaultTemplate(); + alleles[EnumTreeChromosome.SPECIES.ordinal()] = Allele.treeJungle; + alleles[EnumTreeChromosome.FRUITS.ordinal()] = Allele.fruitCocoa; + alleles[EnumTreeChromosome.HEIGHT.ordinal()] = Allele.heightLarger; + alleles[EnumTreeChromosome.MATURATION.ordinal()] = Allele.maturationFast; + return alleles; + } + + public static IAllele[] getBalsaTemplate() { + IAllele[] alleles = getDefaultTemplate(); + alleles[EnumTreeChromosome.SPECIES.ordinal()] = Allele.treeBalsa; + alleles[EnumTreeChromosome.FERTILITY.ordinal()] = Allele.saplingsHigh; + alleles[EnumTreeChromosome.SAPPINESS.ordinal()] = Allele.sappinessLower; + alleles[EnumTreeChromosome.HEIGHT.ordinal()] = Allele.heightLarge; + return alleles; + } + + public static IAllele[] getSequoiaTemplate() { + IAllele[] alleles = getDefaultTemplate(); + alleles[EnumTreeChromosome.SPECIES.ordinal()] = Allele.treeSequioa; + alleles[EnumTreeChromosome.HEIGHT.ordinal()] = Allele.heightLargest; + alleles[EnumTreeChromosome.SAPPINESS.ordinal()] = Allele.sappinessLower; + alleles[EnumTreeChromosome.MATURATION.ordinal()] = Allele.maturationSlower; + alleles[EnumTreeChromosome.GIRTH.ordinal()] = Allele.int3; + return alleles; + } + + public static IAllele[] getGiganteumTemplate() { + IAllele[] alleles = getDefaultTemplate(); + alleles[EnumTreeChromosome.SPECIES.ordinal()] = Allele.treeGiganteum; + alleles[EnumTreeChromosome.HEIGHT.ordinal()] = Allele.heightGigantic; + alleles[EnumTreeChromosome.SAPPINESS.ordinal()] = Allele.sappinessLowest; + alleles[EnumTreeChromosome.MATURATION.ordinal()] = Allele.maturationSlowest; + alleles[EnumTreeChromosome.GIRTH.ordinal()] = Allele.int4; + return alleles; + } + + public static IAllele[] getLarchTemplate() { + IAllele[] alleles = getDefaultTemplate(); + alleles[EnumTreeChromosome.SPECIES.ordinal()] = Allele.treeLarch; + alleles[EnumTreeChromosome.FERTILITY.ordinal()] = Allele.saplingsLow; + alleles[EnumTreeChromosome.SAPPINESS.ordinal()] = Allele.sappinessLower; + alleles[EnumTreeChromosome.HEIGHT.ordinal()] = Allele.heightAverage; + return alleles; + } + + public static IAllele[] getPineTemplate() { + IAllele[] alleles = getDefaultTemplate(); + alleles[EnumTreeChromosome.SPECIES.ordinal()] = Allele.treePine; + alleles[EnumTreeChromosome.FERTILITY.ordinal()] = Allele.saplingsLow; + alleles[EnumTreeChromosome.SAPPINESS.ordinal()] = Allele.sappinessLower; + alleles[EnumTreeChromosome.HEIGHT.ordinal()] = Allele.heightAverage; + return alleles; + } + + public static IAllele[] getCherryTemplate() { + IAllele[] alleles = getDefaultTemplate(); + alleles[EnumTreeChromosome.SPECIES.ordinal()] = Allele.treeCherry; + alleles[EnumTreeChromosome.FRUITS.ordinal()] = Allele.fruitCherry; + alleles[EnumTreeChromosome.FERTILITY.ordinal()] = Allele.saplingsLow; + alleles[EnumTreeChromosome.YIELD.ordinal()] = Allele.yieldAverage; + alleles[EnumTreeChromosome.SAPPINESS.ordinal()] = Allele.sappinessLow; + alleles[EnumTreeChromosome.HEIGHT.ordinal()] = Allele.heightSmaller; + return alleles; + } + + public static IAllele[] getLimeTemplate() { + IAllele[] alleles = getDefaultTemplate(); + alleles[EnumTreeChromosome.SPECIES.ordinal()] = Allele.treeLime; + alleles[EnumTreeChromosome.FERTILITY.ordinal()] = Allele.saplingsLow; + alleles[EnumTreeChromosome.SAPPINESS.ordinal()] = Allele.sappinessLower; + alleles[EnumTreeChromosome.YIELD.ordinal()] = Allele.yieldLower; + //alleles[EnumTreeChromosome.EFFECT.ordinal()] = Allele.leavesBrimstone; + return alleles; + } + + public static IAllele[] getTeakTemplate() { + IAllele[] alleles = getDefaultTemplate(); + alleles[EnumTreeChromosome.SPECIES.ordinal()] = Allele.treeTeak; + alleles[EnumTreeChromosome.SAPPINESS.ordinal()] = Allele.sappinessLower; + return alleles; + } + + public static IAllele[] getKapokTemplate() { + IAllele[] alleles = getDefaultTemplate(); + alleles[EnumTreeChromosome.SPECIES.ordinal()] = Allele.treeKapok; + alleles[EnumTreeChromosome.HEIGHT.ordinal()] = Allele.heightLarge; + alleles[EnumTreeChromosome.SAPPINESS.ordinal()] = Allele.sappinessLow; + alleles[EnumTreeChromosome.MATURATION.ordinal()] = Allele.maturationSlow; + return alleles; + } + + public static IAllele[] getEbonyTemplate() { + IAllele[] alleles = getDefaultTemplate(); + alleles[EnumTreeChromosome.SPECIES.ordinal()] = Allele.treeEbony; + alleles[EnumTreeChromosome.HEIGHT.ordinal()] = Allele.heightAverage; + alleles[EnumTreeChromosome.SAPPINESS.ordinal()] = Allele.sappinessLow; + alleles[EnumTreeChromosome.MATURATION.ordinal()] = Allele.maturationSlower; + alleles[EnumTreeChromosome.GIRTH.ordinal()] = Allele.int3; + return alleles; + } + + public static IAllele[] getMahoganyTemplate() { + IAllele[] alleles = getDefaultTemplate(); + alleles[EnumTreeChromosome.SPECIES.ordinal()] = Allele.treeMahogany; + alleles[EnumTreeChromosome.HEIGHT.ordinal()] = Allele.heightLarge; + alleles[EnumTreeChromosome.SAPPINESS.ordinal()] = Allele.sappinessLow; + alleles[EnumTreeChromosome.MATURATION.ordinal()] = Allele.maturationSlow; + alleles[EnumTreeChromosome.GIRTH.ordinal()] = Allele.int2; + return alleles; + } + + public static IAllele[] getChestnutTemplate() { + IAllele[] alleles = getDefaultTemplate(); + alleles[EnumTreeChromosome.SPECIES.ordinal()] = Allele.treeChestnut; + alleles[EnumTreeChromosome.FRUITS.ordinal()] = Allele.fruitChestnut; + alleles[EnumTreeChromosome.YIELD.ordinal()] = Allele.yieldAverage; + alleles[EnumTreeChromosome.SAPPINESS.ordinal()] = Allele.sappinessLower; + alleles[EnumTreeChromosome.HEIGHT.ordinal()] = Allele.heightLarge; + alleles[EnumTreeChromosome.GIRTH.ordinal()] = Allele.int2; + return alleles; + } + + public static IAllele[] getAcaciaTemplate() { + IAllele[] alleles = getDefaultTemplate(); + alleles[EnumTreeChromosome.SPECIES.ordinal()] = Allele.treeAcacia; + alleles[EnumTreeChromosome.PLANT.ordinal()] = Allele.plantTypeDesert; + return alleles; + } + + public static IAllele[] getWengeTemplate() { + IAllele[] alleles = getDefaultTemplate(); + alleles[EnumTreeChromosome.SPECIES.ordinal()] = Allele.treeWenge; + alleles[EnumTreeChromosome.FERTILITY.ordinal()] = Allele.saplingsLowest; + alleles[EnumTreeChromosome.GIRTH.ordinal()] = Allele.int2; + return alleles; + } + + public static IAllele[] getBaobabTemplate() { + IAllele[] alleles = getDefaultTemplate(); + alleles[EnumTreeChromosome.SPECIES.ordinal()] = Allele.treeBaobab; + alleles[EnumTreeChromosome.HEIGHT.ordinal()] = Allele.heightLarge; + alleles[EnumTreeChromosome.PLANT.ordinal()] = Allele.plantTypeDesert; + alleles[EnumTreeChromosome.SAPPINESS.ordinal()] = Allele.sappinessLower; + alleles[EnumTreeChromosome.MATURATION.ordinal()] = Allele.maturationSlow; + alleles[EnumTreeChromosome.GIRTH.ordinal()] = Allele.int3; + return alleles; + } + + public static IAllele[] getWalnutTemplate() { + IAllele[] alleles = getDefaultTemplate(); + alleles[EnumTreeChromosome.SPECIES.ordinal()] = Allele.treeWalnut; + alleles[EnumTreeChromosome.FRUITS.ordinal()] = Allele.fruitWalnut; + alleles[EnumTreeChromosome.FERTILITY.ordinal()] = Allele.saplingsLower; + alleles[EnumTreeChromosome.YIELD.ordinal()] = Allele.yieldAverage; + alleles[EnumTreeChromosome.SAPPINESS.ordinal()] = Allele.sappinessLower; + alleles[EnumTreeChromosome.HEIGHT.ordinal()] = Allele.heightAverage; + alleles[EnumTreeChromosome.GIRTH.ordinal()] = Allele.int2; + return alleles; + } + + public static IAllele[] getWillowTemplate() { + IAllele[] alleles = getDefaultTemplate(); + alleles[EnumTreeChromosome.SPECIES.ordinal()] = Allele.treeWillow; + alleles[EnumTreeChromosome.HEIGHT.ordinal()] = Allele.heightAverage; + alleles[EnumTreeChromosome.SAPPINESS.ordinal()] = Allele.sappinessLow; + alleles[EnumTreeChromosome.MATURATION.ordinal()] = Allele.maturationFaster; + return alleles; + } + + public static IAllele[] getSipiriTemplate() { + IAllele[] alleles = getDefaultTemplate(); + alleles[EnumTreeChromosome.SPECIES.ordinal()] = Allele.treeSipiri; + alleles[EnumTreeChromosome.GROWTH.ordinal()] = Allele.growthTropical; + alleles[EnumTreeChromosome.HEIGHT.ordinal()] = Allele.heightLarge; + alleles[EnumTreeChromosome.SAPPINESS.ordinal()] = Allele.sappinessLow; + alleles[EnumTreeChromosome.MATURATION.ordinal()] = Allele.maturationSlow; + return alleles; + } + + public static IAllele[] getMahoeTemplate() { + IAllele[] alleles = getDefaultTemplate(); + alleles[EnumTreeChromosome.SPECIES.ordinal()] = Allele.treeMahoe; + alleles[EnumTreeChromosome.HEIGHT.ordinal()] = Allele.heightSmall; + alleles[EnumTreeChromosome.SAPPINESS.ordinal()] = Allele.sappinessHigh; + alleles[EnumTreeChromosome.MATURATION.ordinal()] = Allele.maturationSlowest; + return alleles; + } + + public static IAllele[] getPoplarTemplate() { + IAllele[] alleles = getDefaultTemplate(); + alleles[EnumTreeChromosome.SPECIES.ordinal()] = Allele.treePoplar; + alleles[EnumTreeChromosome.HEIGHT.ordinal()] = Allele.heightSmall; + alleles[EnumTreeChromosome.SAPPINESS.ordinal()] = Allele.sappinessLow; + alleles[EnumTreeChromosome.MATURATION.ordinal()] = Allele.maturationSlower; + return alleles; + } + + public static IAllele[] getLemonTemplate() { + IAllele[] alleles = getDefaultTemplate(); + alleles[EnumTreeChromosome.SPECIES.ordinal()] = Allele.treeLemon; + alleles[EnumTreeChromosome.FRUITS.ordinal()] = Allele.fruitLemon; + alleles[EnumTreeChromosome.YIELD.ordinal()] = Allele.yieldLower; + alleles[EnumTreeChromosome.SAPPINESS.ordinal()] = Allele.sappinessAverage; + alleles[EnumTreeChromosome.HEIGHT.ordinal()] = Allele.heightSmallest; + return alleles; + } + + public static IAllele[] getPlumTemplate() { + IAllele[] alleles = getDefaultTemplate(); + alleles[EnumTreeChromosome.SPECIES.ordinal()] = Allele.treePlum; + alleles[EnumTreeChromosome.FRUITS.ordinal()] = Allele.fruitPlum; + alleles[EnumTreeChromosome.YIELD.ordinal()] = Allele.yieldHigh; + alleles[EnumTreeChromosome.SAPPINESS.ordinal()] = Allele.sappinessAverage; + alleles[EnumTreeChromosome.HEIGHT.ordinal()] = Allele.heightSmallest; + return alleles; + } + + public static IAllele[] getMapleTemplate() { + IAllele[] alleles = getDefaultTemplate(); + alleles[EnumTreeChromosome.SPECIES.ordinal()] = Allele.treeMaple; + alleles[EnumTreeChromosome.FERTILITY.ordinal()] = Allele.saplingsLow; + alleles[EnumTreeChromosome.SAPPINESS.ordinal()] = Allele.sappinessLower; + alleles[EnumTreeChromosome.HEIGHT.ordinal()] = Allele.heightAverage; + return alleles; + } + + public static IAllele[] getPapayaTemplate() { + IAllele[] alleles = getDefaultTemplate(); + alleles[EnumTreeChromosome.SPECIES.ordinal()] = Allele.treePapaya; + alleles[EnumTreeChromosome.FRUITS.ordinal()] = Allele.fruitPapaya; + alleles[EnumTreeChromosome.FERTILITY.ordinal()] = Allele.saplingsLow; + alleles[EnumTreeChromosome.SAPPINESS.ordinal()] = Allele.sappinessLower; + alleles[EnumTreeChromosome.HEIGHT.ordinal()] = Allele.heightAverage; + return alleles; + } + + public static IAllele[] getDateTemplate() { + IAllele[] alleles = getDefaultTemplate(); + alleles[EnumTreeChromosome.SPECIES.ordinal()] = Allele.treeDate; + alleles[EnumTreeChromosome.FRUITS.ordinal()] = Allele.fruitDates; + alleles[EnumTreeChromosome.FERTILITY.ordinal()] = Allele.saplingsLow; + alleles[EnumTreeChromosome.YIELD.ordinal()] = Allele.yieldLow; + alleles[EnumTreeChromosome.SAPPINESS.ordinal()] = Allele.sappinessLow; + alleles[EnumTreeChromosome.HEIGHT.ordinal()] = Allele.heightAverage; + return alleles; + } + + // / HELPER FUNCTIONS + + public static Chromosome[] templateAsChromosomes(IAllele[] template) { + Chromosome[] chromosomes = new Chromosome[template.length]; + for (int i = 0; i < template.length; i++) + if (template[i] != null) + chromosomes[i] = new Chromosome(template[i]); + + return chromosomes; + } + + public static Chromosome[] templateAsChromosomes(IAllele[] templateActive, IAllele[] templateInactive) { + Chromosome[] chromosomes = new Chromosome[templateActive.length]; + for (int i = 0; i < templateActive.length; i++) + if (templateActive[i] != null) + chromosomes[i] = new Chromosome(templateActive[i], templateInactive[i]); + + return chromosomes; + } + + public static ITreeGenome templateAsGenome(IAllele[] template) { + return new TreeGenome(templateAsChromosomes(template)); + } + + public static ITreeGenome templateAsGenome(IAllele[] templateActive, IAllele[] templateInactive) { + return new TreeGenome(templateAsChromosomes(templateActive, templateInactive)); + } +} diff --git a/forestry_common/arboriculture/forestry/arboriculture/genetics/TreekeepingMode.java b/forestry_common/arboriculture/forestry/arboriculture/genetics/TreekeepingMode.java new file mode 100755 index 000000000..97170e06a --- /dev/null +++ b/forestry_common/arboriculture/forestry/arboriculture/genetics/TreekeepingMode.java @@ -0,0 +1,77 @@ +/******************************************************************************* + * Copyright 2011-2014 by SirSengir + * + * This work is licensed under a Creative Commons Attribution-NonCommercial-NoDerivs 3.0 Unported License. + * + * To view a copy of this license, visit http://creativecommons.org/licenses/by-nc-nd/3.0/. + ******************************************************************************/ +package forestry.arboriculture.genetics; + +import java.util.ArrayList; +import java.util.Locale; +import java.util.Random; + +import forestry.api.arboriculture.ITreeGenome; +import forestry.api.arboriculture.ITreekeepingMode; + +public class TreekeepingMode implements ITreekeepingMode { + + public static ITreekeepingMode easy = new TreekeepingMode("EASY", 1.4f, 1.3f, 1.2f, 1.2f); + public static ITreekeepingMode normal = new TreekeepingMode("NORMAL", 1f, 1f, 1f, 1f); + public static ITreekeepingMode hard = new TreekeepingMode("HARD", 0.9f, 0.9f, 0.9f, 0.9f); + public static ITreekeepingMode hardcore = new TreekeepingMode("HARDCORE", 0.7f, 0.7f, 0.5f, 0.5f); + public static ITreekeepingMode insane = new TreekeepingMode("INSANE", 0.5f, 0.5f, 0.2f, 0.1f); + + final Random rand; + final String name; + private float yieldModifier; + private float sappinessModifier; + private float maturationModifier; + private float mutationModifier; + + public TreekeepingMode(String name, float yieldModifier, float sappinessModifier, float maturationModifier, float mutationModifier) { + this.rand = new Random(); + this.name = name; + this.yieldModifier = yieldModifier; + this.sappinessModifier = sappinessModifier; + this.maturationModifier = maturationModifier; + this.mutationModifier = mutationModifier; + } + + @Override + public String getName() { + return this.name; + } + + @Override + public ArrayList getDescription() { + ArrayList ret = new ArrayList(); + ret.add("treemode." + name.toLowerCase(Locale.ENGLISH) + ".desc"); + return ret; + } + + @Override + public float getHeightModifier(ITreeGenome genome, float currentModifier) { + return 1f; + } + + @Override + public float getYieldModifier(ITreeGenome genome, float currentModifier) { + return yieldModifier; + } + + @Override + public float getSappinessModifier(ITreeGenome genome, float currentModifier) { + return sappinessModifier; + } + + @Override + public float getMaturationModifier(ITreeGenome genome, float currentModifier) { + return maturationModifier; + } + + @Override + public float getMutationModifier(ITreeGenome genome, ITreeGenome mate, float currentModifier) { + return mutationModifier; + } +} diff --git a/forestry_common/arboriculture/forestry/arboriculture/gui/ContainerTreealyzer.java b/forestry_common/arboriculture/forestry/arboriculture/gui/ContainerTreealyzer.java new file mode 100755 index 000000000..d0b9e98a7 --- /dev/null +++ b/forestry_common/arboriculture/forestry/arboriculture/gui/ContainerTreealyzer.java @@ -0,0 +1,83 @@ +/******************************************************************************* + * Copyright 2011-2014 by SirSengir + * + * This work is licensed under a Creative Commons Attribution-NonCommercial-NoDerivs 3.0 Unported License. + * + * To view a copy of this license, visit http://creativecommons.org/licenses/by-nc-nd/3.0/. + ******************************************************************************/ +package forestry.arboriculture.gui; + +import org.apache.commons.lang3.ArrayUtils; + +import net.minecraft.entity.player.EntityPlayer; +import net.minecraft.entity.player.InventoryPlayer; +import net.minecraft.init.Blocks; +import net.minecraft.item.ItemStack; +import forestry.api.genetics.AlleleManager; +import forestry.arboriculture.items.ItemGermlingGE; +import forestry.arboriculture.items.ItemTreealyzer.TreealyzerInventory; +import forestry.core.config.ForestryItem; +import forestry.core.gui.ContainerItemInventory; +import forestry.core.gui.slots.SlotCustom; +import forestry.core.proxy.Proxies; + +public class ContainerTreealyzer extends ContainerItemInventory { + + TreealyzerInventory inventory; + + public ContainerTreealyzer(InventoryPlayer inventoryplayer, TreealyzerInventory inventory) { + super(inventory, inventoryplayer.player); + + this.inventory = inventory; + + // Energy + this.addSlot(new SlotCustom(inventory, TreealyzerInventory.SLOT_ENERGY, 172, 8, new Object[] { ForestryItem.honeydew, ForestryItem.honeyDrop })); + + // Bee to analyze + this.addSlot(new SlotCustom(inventory, TreealyzerInventory.SLOT_SPECIMEN, 172, 26, ArrayUtils.addAll(AlleleManager.ersatzSaplings.keySet().toArray(new ItemStack[0]), ItemGermlingGE.class))); + + // Analyzed bee + this.addSlot(new SlotCustom(inventory, TreealyzerInventory.SLOT_ANALYZE_1, 172, 57, new Object[] { ItemGermlingGE.class })); + this.addSlot(new SlotCustom(inventory, TreealyzerInventory.SLOT_ANALYZE_2, 172, 75, new Object[] { ItemGermlingGE.class })); + this.addSlot(new SlotCustom(inventory, TreealyzerInventory.SLOT_ANALYZE_3, 172, 93, new Object[] { ItemGermlingGE.class })); + this.addSlot(new SlotCustom(inventory, TreealyzerInventory.SLOT_ANALYZE_4, 172, 111, new Object[] { ItemGermlingGE.class })); + this.addSlot(new SlotCustom(inventory, TreealyzerInventory.SLOT_ANALYZE_5, 172, 129, new Object[] { ItemGermlingGE.class })); + + // Player inventory + for (int i1 = 0; i1 < 3; i1++) + for (int l1 = 0; l1 < 9; l1++) + addSecuredSlot(inventoryplayer, l1 + i1 * 9 + 9, 18 + l1 * 18, 156 + i1 * 18); + // Player hotbar + for (int j1 = 0; j1 < 9; j1++) + addSecuredSlot(inventoryplayer, j1, 18 + j1 * 18, 214); + + } + + @Override + public void onContainerClosed(EntityPlayer entityplayer) { + + if (!Proxies.common.isSimulating(entityplayer.worldObj)) + return; + + // Last slot is the energy slot, so we don't save that one. + for (int i = 0; i < inventory.getSizeInventory(); i++) { + if (i == TreealyzerInventory.SLOT_ENERGY) + continue; + ItemStack stack = inventory.getStackInSlot(i); + if (stack == null) + continue; + + Proxies.common.dropItemPlayer(entityplayer, stack); + inventory.setInventorySlotContents(i, null); + } + + inventory.onGuiSaved(entityplayer); + + } + + @Override + protected boolean isAcceptedItem(EntityPlayer player, ItemStack stack) { + return true; + } + +} diff --git a/forestry_common/arboriculture/forestry/arboriculture/gui/GuiTreealyzer.java b/forestry_common/arboriculture/forestry/arboriculture/gui/GuiTreealyzer.java new file mode 100755 index 000000000..da7fccca1 --- /dev/null +++ b/forestry_common/arboriculture/forestry/arboriculture/gui/GuiTreealyzer.java @@ -0,0 +1,343 @@ +/******************************************************************************* + * Copyright 2011-2014 by SirSengir + * + * This work is licensed under a Creative Commons Attribution-NonCommercial-NoDerivs 3.0 Unported License. + * + * To view a copy of this license, visit http://creativecommons.org/licenses/by-nc-nd/3.0/. + ******************************************************************************/ +package forestry.arboriculture.gui; + +import java.util.ArrayList; +import java.util.Locale; + +import net.minecraft.entity.player.EntityPlayer; +import net.minecraft.item.ItemStack; + +import net.minecraftforge.common.EnumPlantType; + +import forestry.api.arboriculture.EnumTreeChromosome; +import forestry.api.arboriculture.IAlleleFruit; +import forestry.api.arboriculture.IAlleleGrowth; +import forestry.api.arboriculture.ITree; +import forestry.api.genetics.AlleleManager; +import forestry.api.genetics.IAllele; +import forestry.api.genetics.IAlleleEffect; +import forestry.api.genetics.IAlleleFloat; +import forestry.api.genetics.IAlleleInteger; +import forestry.api.genetics.IFruitFamily; +import forestry.arboriculture.items.ItemGermlingGE; +import forestry.arboriculture.items.ItemTreealyzer.TreealyzerInventory; +import forestry.core.config.ForestryItem; +import forestry.core.genetics.Allele; +import forestry.core.genetics.AllelePlantType; +import forestry.core.gui.GuiAlyzer; +import forestry.core.utils.StringUtil; +import forestry.plugins.PluginArboriculture; + +public class GuiTreealyzer extends GuiAlyzer { + + private ItemStack[] tempProductList; + + public GuiTreealyzer(EntityPlayer player, TreealyzerInventory inventory) { + super(AlleleManager.alleleRegistry.getSpeciesRoot("rootTrees"), player, + new ContainerTreealyzer(player.inventory, inventory), inventory, 1, inventory.getSizeInventory()); + + xSize = 196; + ySize = 238; + + ArrayList treeList = new ArrayList(); + ((ItemGermlingGE) ForestryItem.sapling.item()).addCreativeItems(treeList, false); + for (ItemStack beeStack : treeList) + iconStacks.put(PluginArboriculture.treeInterface.getMember(beeStack).getIdent(), beeStack); + } + + @Override + protected void drawGuiContainerBackgroundLayer(float var1, int mouseX, int mouseY) { + super.drawGuiContainerBackgroundLayer(var1, mouseX, mouseY); + + int page = 0; + ITree tree = null; + for (int k = 1; k < TreealyzerInventory.SLOT_ANALYZE_5 + 1; k++) { + if (k == TreealyzerInventory.SLOT_ENERGY) + continue; + + if (inventory.getStackInSlot(k) == null) + continue; + tree = PluginArboriculture.treeInterface.getMember(inventory.getStackInSlot(k)); + if (tree == null || !tree.isAnalyzed()) + continue; + + page = k; + break; + } + + switch (page) { + case 1: + drawAnalyticsPage1(tree); + break; + case 2: + drawAnalyticsPage2(tree); + break; + case 3: + drawAnalyticsPage3(tree); + break; + case 4: + drawAnalyticsPage4(tree); + break; + case 6: + drawAnalyticsPageClassification(tree); + break; + default: + drawAnalyticsOverview(); + } + + } + + private void drawAnalyticsOverview() { + + startPage(); + + newLine(); + String title = StringUtil.localize("gui.treealyzer").toUpperCase(); + drawCenteredLine(title, 8, 158); + newLine(); + + fontRendererObj.drawSplitString(StringUtil.localize("gui.treealyzer.help"), (int) ((guiLeft + COLUMN_0 + 4) * (1 / factor)), + (int) ((guiTop + 42) * (1 / factor)), (int) (158 * (1 / factor)), fontColor.get("gui.screen")); + newLine(); + newLine(); + newLine(); + newLine(); + + drawLine(StringUtil.localize("gui.treealyzer.overview") + ":", COLUMN_0 + 4); + newLine(); + drawLine("I : " + StringUtil.localize("gui.general"), COLUMN_0 + 4); + newLine(); + drawLine("II : " + StringUtil.localize("gui.environment"), COLUMN_0 + 4); + newLine(); + drawLine("III: " + StringUtil.localize("gui.produce"), COLUMN_0 + 4); + newLine(); + drawLine("IV : " + StringUtil.localize("gui.evolution"), COLUMN_0 + 4); + + endPage(); + } + + private void drawAnalyticsPage1(ITree tree) { + + startPage(COLUMN_0, COLUMN_1, COLUMN_2); + + drawLine(StringUtil.localize("gui.active"), COLUMN_1); + drawLine(StringUtil.localize("gui.inactive"), COLUMN_2); + + newLine(); + newLine(); + + /* + IAlleleTreeSpecies primary = tree.getGenome().getPrimaryAsTree(); + IAlleleTreeSpecies secondary = tree.getGenome().getSecondaryAsTree(); + + drawLine(StringUtil.localize("gui.species"), COLUMN_0); + drawSplitLine(primary.getName(), COLUMN_1, COLUMN_2 - COLUMN_1 - 4, tree, EnumTreeChromosome.SPECIES, false); + drawSplitLine(secondary.getName(), COLUMN_2, COLUMN_2 - COLUMN_1 - 4, tree, EnumTreeChromosome.SPECIES, true); + + newLine(); + newLine();*/ + + drawSpeciesRow(StringUtil.localize("gui.species"), tree, EnumTreeChromosome.SPECIES); + newLine(); + + drawLine(StringUtil.localize("gui.saplings"), COLUMN_0); + drawLine(tree.getGenome().getActiveAllele(EnumTreeChromosome.FERTILITY.ordinal()).getName(), COLUMN_1, tree, EnumTreeChromosome.FERTILITY, false); + drawLine(tree.getGenome().getInactiveAllele(EnumTreeChromosome.FERTILITY.ordinal()).getName(), COLUMN_2, tree, + EnumTreeChromosome.FERTILITY, true); + + newLine(); + + drawRow(StringUtil.localize("gui.maturity"), tree.getGenome().getActiveAllele(EnumTreeChromosome.MATURATION.ordinal()).getName(), + tree.getGenome().getInactiveAllele(EnumTreeChromosome.MATURATION.ordinal()).getName(), tree, + EnumTreeChromosome.MATURATION); + + drawLine(StringUtil.localize("gui.height"), COLUMN_0); + drawLine(tree.getGenome().getActiveAllele(EnumTreeChromosome.HEIGHT.ordinal()).getName(), COLUMN_1, tree, EnumTreeChromosome.HEIGHT, false); + drawLine(tree.getGenome().getInactiveAllele(EnumTreeChromosome.HEIGHT.ordinal()).getName(), COLUMN_2, tree, + EnumTreeChromosome.HEIGHT, true); + + newLine(); + + drawLine(StringUtil.localize("gui.girth"), COLUMN_0); + drawLine(String.format("%sx%s", tree.getGenome().getGirth(), tree.getGenome().getGirth()), COLUMN_1, tree, EnumTreeChromosome.FERTILITY, false); + int secondGirth = ((IAlleleInteger) tree.getGenome().getInactiveAllele(EnumTreeChromosome.GIRTH.ordinal())).getValue(); + drawLine(String.format("%sx%s", secondGirth, secondGirth), COLUMN_2, tree, EnumTreeChromosome.FERTILITY, true); + + newLine(); + + drawLine(StringUtil.localize("gui.yield"), COLUMN_0); + drawLine(tree.getGenome().getActiveAllele(EnumTreeChromosome.YIELD.ordinal()).getName(), COLUMN_1, tree, EnumTreeChromosome.YIELD, false); + drawLine(tree.getGenome().getInactiveAllele(EnumTreeChromosome.YIELD.ordinal()).getName(), COLUMN_2, tree, + EnumTreeChromosome.YIELD, true); + + newLine(); + + drawLine(StringUtil.localize("gui.sappiness"), COLUMN_0); + drawLine(tree.getGenome().getActiveAllele(EnumTreeChromosome.SAPPINESS.ordinal()).getName(), COLUMN_1, tree, EnumTreeChromosome.SAPPINESS, false); + + // FIXME: Legacy handling + IAllele sappiness = tree.getGenome().getInactiveAllele(EnumTreeChromosome.SAPPINESS.ordinal()); + String sap; + if (sappiness instanceof IAlleleFloat) + sap = sappiness.getName(); + else + sap = Allele.saplingsLowest.getName(); + + drawLine(sap, COLUMN_2, tree, EnumTreeChromosome.SAPPINESS, true); + + newLine(); + + drawRow(StringUtil.localize("gui.effect"), StringUtil.localize(tree.getGenome().getEffect().getName()), + StringUtil.localize(((IAlleleEffect) tree.getGenome().getInactiveAllele(EnumTreeChromosome.EFFECT.ordinal())).getName()), tree, + EnumTreeChromosome.EFFECT); + + newLine(); + newLine(); + + endPage(); + } + + private void drawAnalyticsPage2(ITree tree) { + + startPage(); + + int speciesDominance0 = getColorCoding(tree.getGenome().getPrimary().isDominant()); + int speciesDominance1 = getColorCoding(tree.getGenome().getSecondary().isDominant()); + + drawLine(StringUtil.localize("gui.active"), COLUMN_1); + drawLine(StringUtil.localize("gui.inactive"), COLUMN_2); + + newLine(); + newLine(); + + drawLine(StringUtil.localize("gui.growth"), COLUMN_0); + drawLine(tree.getGenome().getGrowthProvider().getDescription(), COLUMN_1, tree, EnumTreeChromosome.GROWTH, false); + drawLine(((IAlleleGrowth) tree.getGenome().getInactiveAllele(EnumTreeChromosome.GROWTH.ordinal())).getProvider().getDescription(), COLUMN_2, tree, + EnumTreeChromosome.GROWTH, true); + + newLine(); + + drawLine(StringUtil.localize("gui.native"), COLUMN_0); + drawLine(StringUtil.localize("gui." + tree.getGenome().getPrimary().getPlantType().toString().toLowerCase(Locale.ENGLISH)), COLUMN_1, + speciesDominance0); + drawLine(StringUtil.localize("gui." + tree.getGenome().getSecondary().getPlantType().toString().toLowerCase(Locale.ENGLISH)), COLUMN_2, + speciesDominance1); + + newLine(); + + drawLine(StringUtil.localize("gui.tolerated"), COLUMN_0); + + EnumPlantType[] tolerated0 = tree.getGenome().getPlantTypes().toArray(new EnumPlantType[0]); + EnumPlantType[] tolerated1 = new EnumPlantType[0]; + IAllele allele1 = tree.getGenome().getInactiveAllele(EnumTreeChromosome.PLANT.ordinal()); + if (allele1 instanceof AllelePlantType) + tolerated1 = ((AllelePlantType) allele1).getPlantTypes().toArray(new EnumPlantType[0]); + + int max = tolerated0.length > tolerated1.length ? tolerated0.length : tolerated1.length; + for (int i = 0; i < max; i++) { + if (i > 0) + newLine(); + if(tolerated0.length > i) + drawLine(StringUtil.localize("gui." + tolerated0[i].toString().toLowerCase(Locale.ENGLISH)), COLUMN_1, tree, EnumTreeChromosome.PLANT, false); + if(tolerated1.length > i) + drawLine(StringUtil.localize("gui." + tolerated1[i].toString().toLowerCase(Locale.ENGLISH)), COLUMN_2, tree, EnumTreeChromosome.PLANT, true); + } + newLine(); + + // FRUITS + drawLine(StringUtil.localize("gui.supports"), COLUMN_0); + IFruitFamily[] families0 = tree.getGenome().getPrimary().getSuitableFruit().toArray(new IFruitFamily[0]); + IFruitFamily[] families1 = tree.getGenome().getPrimary().getSuitableFruit().toArray(new IFruitFamily[0]); + + max = families0.length > families1.length ? families0.length : families1.length; + for (int i = 0; i < max; i++) { + if (i > 0) + newLine(); + + if (families0.length > i) + drawLine(StringUtil.localize(families0[i].getName()), COLUMN_1, speciesDominance0); + if (families1.length > i) + drawLine(StringUtil.localize(families1[i].getName()), COLUMN_2, speciesDominance1); + + } + + newLine(); + newLine(); + + int fruitDominance0 = getColorCoding(tree.getGenome().getActiveAllele(EnumTreeChromosome.FRUITS.ordinal()).isDominant()); + int fruitDominance1 = getColorCoding(tree.getGenome().getInactiveAllele(EnumTreeChromosome.FRUITS.ordinal()).isDominant()); + + drawLine(StringUtil.localize("gui.fruits"), COLUMN_0); + String strike = ""; + IAllele fruit0 = tree.getGenome().getActiveAllele(EnumTreeChromosome.FRUITS.ordinal()); + if (!tree.canBearFruit() && fruit0 != Allele.fruitNone) + strike = "\u00A7m"; + drawLine(strike + StringUtil.localize(tree.getGenome().getFruitProvider().getDescription()), COLUMN_1, fruitDominance0); + + strike = ""; + IAllele fruit1 = tree.getGenome().getInactiveAllele(EnumTreeChromosome.FRUITS.ordinal()); + if (!tree.getGenome().getSecondary().getSuitableFruit().contains(((IAlleleFruit) fruit1).getProvider().getFamily()) && fruit1 != Allele.fruitNone) + strike = "\u00A7m"; + drawLine(strike + StringUtil.localize(((IAlleleFruit) fruit1).getProvider().getDescription()), COLUMN_2, fruitDominance1); + + newLine(); + + drawLine(StringUtil.localize("gui.family"), COLUMN_0); + IFruitFamily primary = tree.getGenome().getFruitProvider().getFamily(); + IFruitFamily secondary = ((IAlleleFruit) tree.getGenome().getInactiveAllele(EnumTreeChromosome.FRUITS.ordinal())).getProvider().getFamily(); + + if (primary != null) + drawLine(StringUtil.localize(primary.getName()), COLUMN_1, fruitDominance0); + if (secondary != null) + drawLine(StringUtil.localize(secondary.getName()), COLUMN_2, fruitDominance1); + + endPage(); + } + + private void drawAnalyticsPage3(ITree tree) { + + tempProductList = tree.getProduceList(); + + startPage(COLUMN_0, COLUMN_1, COLUMN_2); + + drawLine(StringUtil.localize("gui.beealyzer.produce") + ":", COLUMN_0); + newLine(); + + int x = COLUMN_0; + for (ItemStack stack : tempProductList) { + itemRender.renderItemIntoGUI(fontRendererObj, mc.renderEngine, stack, (int) ((guiLeft + x) * (1 / factor)), + (int) ((guiTop + getLineY()) * (1 / factor))); + x += 18; + if (x > adjustToFactor(148)) { + x = COLUMN_0; + newLine(); + } + } + + newLine(); + newLine(); + + drawLine(StringUtil.localize("gui.beealyzer.specialty") + ":", COLUMN_0); + newLine(); + + x = COLUMN_0; + for (ItemStack stack : tree.getSpecialtyList()) { + itemRender.renderItemIntoGUI(fontRendererObj, mc.renderEngine, stack, (int) ((guiLeft + x) * (1 / factor)), + (int) ((guiTop + getLineY()) * (1 / factor))); + x += 18; + if (x > adjustToFactor(148)) { + x = COLUMN_0; + newLine(); + } + } + + endPage(); + } + +} diff --git a/forestry_common/arboriculture/forestry/arboriculture/items/ItemGermlingGE.java b/forestry_common/arboriculture/forestry/arboriculture/items/ItemGermlingGE.java new file mode 100755 index 000000000..df4f40243 --- /dev/null +++ b/forestry_common/arboriculture/forestry/arboriculture/items/ItemGermlingGE.java @@ -0,0 +1,185 @@ +/******************************************************************************* + * Copyright 2011-2014 by SirSengir + * + * This work is licensed under a Creative Commons Attribution-NonCommercial-NoDerivs 3.0 Unported License. + * + * To view a copy of this license, visit http://creativecommons.org/licenses/by-nc-nd/3.0/. + ******************************************************************************/ +package forestry.arboriculture.items; + +import java.util.List; + +import net.minecraft.creativetab.CreativeTabs; +import net.minecraft.entity.player.EntityPlayer; +import net.minecraft.item.Item; +import net.minecraft.item.ItemStack; +import net.minecraft.tileentity.TileEntity; +import net.minecraft.util.IIcon; +import net.minecraft.world.World; + +import cpw.mods.fml.relauncher.Side; +import cpw.mods.fml.relauncher.SideOnly; + +import forestry.api.arboriculture.EnumGermlingType; +import forestry.api.arboriculture.EnumTreeChromosome; +import forestry.api.arboriculture.IAlleleTreeSpecies; +import forestry.api.arboriculture.ITree; +import forestry.api.core.Tabs; +import forestry.api.genetics.IIndividual; +import forestry.api.genetics.IPollinatable; +import forestry.api.recipes.IVariableFermentable; +import forestry.arboriculture.genetics.Tree; +import forestry.core.config.Config; +import forestry.core.genetics.ItemGE; +import forestry.core.network.PacketFXSignal; +import forestry.core.proxy.Proxies; +import forestry.core.render.SpriteSheet; +import forestry.core.utils.Utils; +import forestry.plugins.PluginArboriculture; + +public class ItemGermlingGE extends ItemGE implements IVariableFermentable { + + private final EnumGermlingType type; + + public ItemGermlingGE(EnumGermlingType type) { + super(); + this.type = type; + setCreativeTab(Tabs.tabArboriculture); + } + + @Override + protected IIndividual getIndividual(ItemStack itemstack) { + return new Tree(itemstack.getTagCompound()); + } + + private IAlleleTreeSpecies getPrimarySpecies(ItemStack itemstack) { + ITree tree = PluginArboriculture.treeInterface.getMember(itemstack); + if (tree == null) + return (IAlleleTreeSpecies) PluginArboriculture.treeInterface.getDefaultTemplate()[EnumTreeChromosome.SPECIES.ordinal()]; + else + return tree.getGenome().getPrimary(); + } + + @Override + protected int getDefaultPrimaryColour() { + return 0; + } + + @Override + protected int getDefaultSecondaryColour() { + return 0; + } + + @Override + public String getItemStackDisplayName(ItemStack itemstack) { + if (!itemstack.hasTagCompound()) + return "Unknown"; + IIndividual individual = getIndividual(itemstack); + return individual.getDisplayName() + " " + type.getName(); + } + + @SuppressWarnings("rawtypes") + @Override + public void getSubItems(Item item, CreativeTabs par2CreativeTabs, List itemList) { + addCreativeItems(itemList, true); + } + + @SuppressWarnings({ "rawtypes", "unchecked" }) + public void addCreativeItems(List itemList, boolean hideSecrets) { + for (IIndividual individual : PluginArboriculture.treeInterface.getIndividualTemplates()) { + // Don't show secrets unless ordered to. + if (hideSecrets && individual.isSecret() && !Config.isDebug) + continue; + + itemList.add(PluginArboriculture.treeInterface.getMemberStack(individual, type.ordinal())); + } + } + + @Override + public int getColorFromItemStack(ItemStack itemstack, int renderPass) { + return getPrimarySpecies(itemstack).getGermlingColour(type, renderPass); + } + + /* ICONS */ + @Override + public boolean requiresMultipleRenderPasses() { + return true; + } + + @Override + public int getRenderPasses(int metadata) { + return 2;//type == EnumGermlingType.SAPLING ? 1 : 2; + } + + @Override + public int getSpriteNumber() { + return type == EnumGermlingType.SAPLING ? SpriteSheet.BLOCKS.getSheetOrdinal() : SpriteSheet.ITEMS.getSheetOrdinal(); + } + + @Override + @SideOnly(Side.CLIENT) + public IIcon getIcon(ItemStack itemstack, int renderPass) { + IAlleleTreeSpecies species = getPrimarySpecies(itemstack); + return species.getGermlingIcon(type, renderPass); + } + + @Override + public boolean onItemUse(ItemStack itemstack, EntityPlayer player, World world, int x, int y, int z, int par7, float facingX, float facingY, float facingZ) { + + if (!Proxies.common.isSimulating(world)) + return false; + + ITree tree = PluginArboriculture.treeInterface.getMember(itemstack); + if(tree == null) + return false; + + if(type == EnumGermlingType.SAPLING) { + // x, y, z are the coordinates of the block "hit", can thus either be the soil or tall grass, etc. + int yShift; + if (!Utils.isReplaceableBlock(world, x, y, z)) { + if (!world.isAirBlock(x, y + 1, z)) + return false; + yShift = 1; + } else + yShift = 0; + + if (!tree.canStay(world, x, y + yShift, z)) + return false; + + if (PluginArboriculture.treeInterface.plantSapling(world, tree, player.getGameProfile().getId(), x, y + yShift, z)) { + Proxies.common.addBlockPlaceEffects(world, x, y, z, world.getBlock(x, y + yShift, z), 0); + if (!player.capabilities.isCreativeMode) + itemstack.stackSize--; + return true; + } else + return false; + } else if(type == EnumGermlingType.POLLEN) { + + TileEntity target = world.getTileEntity(x, y, z); + if(!(target instanceof IPollinatable)) + return false; + + IPollinatable pollinatable = (IPollinatable)target; + if(!pollinatable.canMateWith(tree)) + return false; + + pollinatable.mateWith(tree); + Proxies.common.sendFXSignal(PacketFXSignal.VisualFXType.BLOCK_DESTROY, PacketFXSignal.SoundFXType.LEAF, world, x, y, z, + world.getBlock(x, y, z), 0); + if (!player.capabilities.isCreativeMode) + itemstack.stackSize--; + return true; + + } else + return false; + } + + @Override + public float getFermentationModifier(ItemStack itemstack) { + ITree tree = PluginArboriculture.treeInterface.getMember(itemstack); + if (tree == null) + return 1.0f; + + return tree.getGenome().getSappiness() * 10; + } +} diff --git a/forestry_common/arboriculture/forestry/arboriculture/items/ItemGrafter.java b/forestry_common/arboriculture/forestry/arboriculture/items/ItemGrafter.java new file mode 100755 index 000000000..3ee0fb989 --- /dev/null +++ b/forestry_common/arboriculture/forestry/arboriculture/items/ItemGrafter.java @@ -0,0 +1,67 @@ +/******************************************************************************* + * Copyright 2011-2014 by SirSengir + * + * This work is licensed under a Creative Commons Attribution-NonCommercial-NoDerivs 3.0 Unported License. + * + * To view a copy of this license, visit http://creativecommons.org/licenses/by-nc-nd/3.0/. + ******************************************************************************/ +package forestry.arboriculture.items; + +import net.minecraft.block.Block; +import net.minecraft.entity.EntityLivingBase; +import net.minecraft.entity.player.EntityPlayer; +import net.minecraft.item.ItemStack; +import net.minecraft.world.World; + +import net.minecraftforge.common.ForgeHooks; + +import forestry.api.arboriculture.IToolGrafter; +import forestry.api.core.Tabs; +import forestry.core.items.ItemForestry; + +public class ItemGrafter extends ItemForestry implements IToolGrafter { + + private final float efficiencyOnProperMaterial; + + public ItemGrafter(int maxDamage) { + super(); + setMaxStackSize(1); + efficiencyOnProperMaterial = 4.0F; + setMaxDamage(maxDamage); + setCreativeTab(Tabs.tabArboriculture); + } + + @Override + public float func_150893_a(ItemStack itemstack, Block block) { + return 1.0F; + } + + @Override + public float getDigSpeed(ItemStack itemstack, Block block, int md) { + if (ForgeHooks.isToolEffective(itemstack, block, md)) + return efficiencyOnProperMaterial; + + return func_150893_a(itemstack, block); + } + + @Override + public boolean onBlockDestroyed(ItemStack itemstack, World world, Block block, int j, int k, int l, EntityLivingBase entityliving) { + return true; + } + + /*@Override + public float getDamageVsEntity(Entity entity, ItemStack itemstack) { + return 1; + }*/ + + @Override + public boolean isFull3D() { + return true; + } + + @Override + public float getSaplingModifier(ItemStack stack, World world, EntityPlayer player, int x, int y, int z) { + return 100f; + } + +} diff --git a/forestry_common/arboriculture/forestry/arboriculture/items/ItemStairs.java b/forestry_common/arboriculture/forestry/arboriculture/items/ItemStairs.java new file mode 100755 index 000000000..dc4de81f5 --- /dev/null +++ b/forestry_common/arboriculture/forestry/arboriculture/items/ItemStairs.java @@ -0,0 +1,73 @@ +/******************************************************************************* + * Copyright 2011-2014 by SirSengir + * + * This work is licensed under a Creative Commons Attribution-NonCommercial-NoDerivs 3.0 Unported License. + * + * To view a copy of this license, visit http://creativecommons.org/licenses/by-nc-nd/3.0/. + ******************************************************************************/ +package forestry.arboriculture.items; + +import net.minecraft.block.Block; +import net.minecraft.entity.player.EntityPlayer; +import net.minecraft.item.ItemStack; +import net.minecraft.tileentity.TileEntity; +import net.minecraft.world.World; + +import forestry.arboriculture.WoodType; +import forestry.arboriculture.gadgets.TileStairs; +import forestry.core.config.Defaults; +import forestry.core.config.ForestryBlock; +import forestry.core.items.ItemForestryBlock; +import forestry.core.utils.StringUtil; + +public class ItemStairs extends ItemForestryBlock { + + public ItemStairs(Block block) { + super(block); + } + + @Override + public boolean placeBlockAt(ItemStack stack, EntityPlayer player, World world, int x, int y, int z, int side, float hitX, float hitY, float hitZ, + int metadata) { + + WoodType type = WoodType.getFromCompound(stack.getTagCompound()); + return placeStairs(world, player, stack, type, x, y, z, metadata); + + } + + private boolean placeStairs(World world, EntityPlayer player, ItemStack stack, WoodType type, int x, int y, int z, int metadata) { + + boolean placed = world.setBlock(x, y, z, ForestryBlock.stairs, metadata, Defaults.FLAG_BLOCK_SYNCH); + if (!placed) + return false; + + Block block = world.getBlock(x, y, z); + + if (block != ForestryBlock.stairs) + return false; + + block.onBlockPlacedBy(world, x, y, z, player, stack); + block.onPostBlockPlaced(world, x, y, z, metadata); + + TileEntity tile = world.getTileEntity(x, y, z); + if (!(tile instanceof TileStairs)) { + world.setBlockToAir(x, y, z); + return false; + } + + ((TileStairs) tile).setType(type); + return true; + } + + private String getWoodNameIS(WoodType type) { + return StringUtil.localize("wood." + type.ordinal()); + } + + @Override + public String getItemStackDisplayName(ItemStack itemstack) { + + WoodType type = WoodType.getFromCompound(itemstack.getTagCompound()); + + return getWoodNameIS(type) + " " + StringUtil.localize(getUnlocalizedName()); + } +} diff --git a/forestry_common/arboriculture/forestry/arboriculture/items/ItemTreealyzer.java b/forestry_common/arboriculture/forestry/arboriculture/items/ItemTreealyzer.java new file mode 100755 index 000000000..cb2916685 --- /dev/null +++ b/forestry_common/arboriculture/forestry/arboriculture/items/ItemTreealyzer.java @@ -0,0 +1,169 @@ +/******************************************************************************* + * Copyright 2011-2014 by SirSengir + * + * This work is licensed under a Creative Commons Attribution-NonCommercial-NoDerivs 3.0 Unported License. + * + * To view a copy of this license, visit http://creativecommons.org/licenses/by-nc-nd/3.0/. + ******************************************************************************/ +package forestry.arboriculture.items; + +import net.minecraft.entity.player.EntityPlayer; +import net.minecraft.item.ItemStack; +import net.minecraft.nbt.NBTTagCompound; +import net.minecraft.nbt.NBTTagList; +import net.minecraft.world.World; + +import forestry.api.arboriculture.ITree; +import forestry.api.core.ForestryAPI; +import forestry.api.core.Tabs; +import forestry.core.EnumErrorCode; +import forestry.core.config.Config; +import forestry.core.config.ForestryItem; +import forestry.core.interfaces.IErrorSource; +import forestry.core.interfaces.IHintSource; +import forestry.core.items.ItemInventoried; +import forestry.core.network.GuiId; +import forestry.core.proxy.Proxies; +import forestry.core.utils.ItemInventory; +import forestry.core.utils.Utils; +import forestry.plugins.PluginArboriculture; + +public class ItemTreealyzer extends ItemInventoried { + + public static class TreealyzerInventory extends ItemInventory implements IErrorSource, IHintSource { + + public final static int SLOT_SPECIMEN = 0; + public final static int SLOT_ANALYZE_1 = 1; + public final static int SLOT_ANALYZE_2 = 2; + public final static int SLOT_ANALYZE_3 = 3; + public final static int SLOT_ANALYZE_4 = 4; + public final static int SLOT_ANALYZE_5 = 6; + public final static int SLOT_ENERGY = 5; + EntityPlayer player; + + public TreealyzerInventory(EntityPlayer player) { + super(ItemTreealyzer.class, 7); + this.player = player; + } + + public TreealyzerInventory(EntityPlayer player, ItemStack itemStack) { + super(ItemTreealyzer.class, 7, itemStack); + this.player = player; + } + + @Override + public void writeToNBT(NBTTagCompound nbttagcompound) { + + NBTTagList nbttaglist = new NBTTagList(); + for (int i = SLOT_ENERGY; i < SLOT_ENERGY + 1; i++) { + if (inventoryStacks[i] != null) { + NBTTagCompound nbttagcompound1 = new NBTTagCompound(); + nbttagcompound1.setByte("Slot", (byte) i); + inventoryStacks[i].writeToNBT(nbttagcompound1); + nbttaglist.appendTag(nbttagcompound1); + } + } + nbttagcompound.setTag("Items", nbttaglist); + + } + + private boolean isEnergy(ItemStack itemstack) { + if (itemstack == null || itemstack.stackSize <= 0) + return false; + + return ForestryItem.honeyDrop.isItemEqual(itemstack) || ForestryItem.honeydew.isItemEqual(itemstack); + } + + private void tryAnalyze() { + + // Analyzed slot occupied, abort + if (inventoryStacks[SLOT_ANALYZE_1] != null || inventoryStacks[SLOT_ANALYZE_2] != null || inventoryStacks[SLOT_ANALYZE_3] != null + || inventoryStacks[SLOT_ANALYZE_4] != null || inventoryStacks[SLOT_ANALYZE_5] != null) + return; + + // Source slot to analyze empty + if (getStackInSlot(SLOT_SPECIMEN) == null) + return; + + if (!PluginArboriculture.treeInterface.isMember(getStackInSlot(SLOT_SPECIMEN))) { + ItemStack ersatz = Utils.convertSaplingToGeneticEquivalent(getStackInSlot(SLOT_SPECIMEN)); + if (ersatz != null) + setInventorySlotContents(SLOT_SPECIMEN, ersatz); + } + ITree tree = PluginArboriculture.treeInterface.getMember(getStackInSlot(SLOT_SPECIMEN)); + // No tree, abort + if (tree == null) + return; + + // Analyze if necessary + if (!tree.isAnalyzed()) { + + // Requires energy + if (!isEnergy(getStackInSlot(SLOT_ENERGY))) + return; + + tree.analyze(); + if (player != null) { + PluginArboriculture.treeInterface.getBreedingTracker(player.worldObj, player.getGameProfile().getId()).registerSpecies(tree.getGenome().getPrimary()); + PluginArboriculture.treeInterface.getBreedingTracker(player.worldObj, player.getGameProfile().getId()).registerSpecies(tree.getGenome().getSecondary()); + } + NBTTagCompound nbttagcompound = new NBTTagCompound(); + tree.writeToNBT(nbttagcompound); + getStackInSlot(SLOT_SPECIMEN).setTagCompound(nbttagcompound); + + // Decrease energy + decrStackSize(SLOT_ENERGY, 1); + } + + setInventorySlotContents(SLOT_ANALYZE_1, getStackInSlot(SLOT_SPECIMEN)); + setInventorySlotContents(SLOT_SPECIMEN, null); + } + + @Override + public void markDirty() { + // if (!Proxies.common.isSimulating(player.worldObj)) + // return; + tryAnalyze(); + } + + // / IHINTSOURCE + @Override + public boolean hasHints() { + return Config.hints.get("treealyzer") != null && Config.hints.get("treealyzer").length > 0; + } + + @Override + public String[] getHints() { + return Config.hints.get("treealyzer"); + } + + // / IERRORSOURCE + @Override + public boolean throwsErrors() { + return true; + } + + @Override + public EnumErrorCode getErrorState() { + if (PluginArboriculture.treeInterface.isMember(inventoryStacks[SLOT_SPECIMEN]) && !isEnergy(getStackInSlot(SLOT_ENERGY))) + return EnumErrorCode.NOHONEY; + + return EnumErrorCode.OK; + } + } + + public ItemTreealyzer() { + super(); + setMaxStackSize(1); + setCreativeTab(Tabs.tabArboriculture); + } + + @Override + public ItemStack onItemRightClick(ItemStack itemstack, World world, EntityPlayer entityplayer) { + if (Proxies.common.isSimulating(world)) + entityplayer.openGui(ForestryAPI.instance, GuiId.TreealyzerGUI.ordinal(), world, (int) entityplayer.posX, (int) entityplayer.posY, + (int) entityplayer.posZ); + + return itemstack; + } +} diff --git a/forestry_common/arboriculture/forestry/arboriculture/items/ItemWoodBlock.java b/forestry_common/arboriculture/forestry/arboriculture/items/ItemWoodBlock.java new file mode 100755 index 000000000..69f0c1020 --- /dev/null +++ b/forestry_common/arboriculture/forestry/arboriculture/items/ItemWoodBlock.java @@ -0,0 +1,42 @@ +/******************************************************************************* + * Copyright 2011-2014 by SirSengir + * + * This work is licensed under a Creative Commons Attribution-NonCommercial-NoDerivs 3.0 Unported License. + * + * To view a copy of this license, visit http://creativecommons.org/licenses/by-nc-nd/3.0/. + ******************************************************************************/ +package forestry.arboriculture.items; + +import net.minecraft.block.Block; +import net.minecraft.item.ItemStack; + +import forestry.arboriculture.IWoodTyped; +import forestry.arboriculture.WoodType; +import forestry.core.items.ItemForestryBlock; +import forestry.core.utils.StringUtil; + +public class ItemWoodBlock extends ItemForestryBlock { + + public ItemWoodBlock(Block block) { + super(block); + } + + public static int getTypeFromMeta(int damage) { + return damage & 3; + } + + private String getWoodNameIS(WoodType type) { + return StringUtil.localize("wood." + type.ordinal()); + } + + @Override + public String getItemStackDisplayName(ItemStack itemstack) { + + if (this.getBlock() instanceof IWoodTyped) { + IWoodTyped block = (IWoodTyped) getBlock(); + return getWoodNameIS(block.getWoodType(itemstack.getItemDamage())) + " " + StringUtil.localize("tile." + block.getBlockKind()); + } else + return StringUtil.localize(getUnlocalizedName(itemstack)); + } + +} diff --git a/forestry_common/arboriculture/forestry/arboriculture/network/PacketLeafUpdate.java b/forestry_common/arboriculture/forestry/arboriculture/network/PacketLeafUpdate.java new file mode 100755 index 000000000..cbeab6b48 --- /dev/null +++ b/forestry_common/arboriculture/forestry/arboriculture/network/PacketLeafUpdate.java @@ -0,0 +1,100 @@ +/******************************************************************************* + * Copyright 2011-2014 by SirSengir + * + * This work is licensed under a Creative Commons Attribution-NonCommercial-NoDerivs 3.0 Unported License. + * + * To view a copy of this license, visit http://creativecommons.org/licenses/by-nc-nd/3.0/. + ******************************************************************************/ +package forestry.arboriculture.network; + +import java.io.DataInputStream; +import java.io.DataOutputStream; +import java.io.IOException; + +import forestry.arboriculture.gadgets.TileLeaves; +import forestry.core.network.PacketCoordinates; +import forestry.core.network.PacketIds; + +public class PacketLeafUpdate extends PacketCoordinates { + + public byte isRipeningUpdate = 0; + + private byte leafState = 0; + public short textureIndexFancy; + public short textureIndexPlain; + public short textureIndexFruit; + + public int colourLeaves; + public int colourFruits; + + public PacketLeafUpdate() { + } + + public PacketLeafUpdate(int posX, int posY, int posZ, TileLeaves leaves) { + super(PacketIds.LEAF_UPDATE, posX, posY, posZ); + + leafState = 0; + if(leaves.hasFruit()) + leafState |= 1 << 0; + if(leaves.isPollinated()) + leafState |= 1 << 1; + textureIndexFancy = leaves.determineTextureIndex(true); + textureIndexPlain = leaves.determineTextureIndex(false); + textureIndexFruit = leaves.determineOverlayIndex(); + colourLeaves = leaves.determineFoliageColour(); + colourFruits = leaves.determineFruitColour(); + } + + public PacketLeafUpdate(int posX, int posY, int posZ, int fruitColour) { + super(PacketIds.LEAF_UPDATE, posX, posY, posZ); + + isRipeningUpdate = 1; + colourFruits = fruitColour; + } + + @Override + public void writeData(DataOutputStream data) throws IOException { + super.writeData(data); + + data.writeByte(isRipeningUpdate); + + if(isRipeningUpdate()) { + data.writeInt(colourFruits); + } else { + data.writeByte(leafState); + data.writeShort(textureIndexFancy); + data.writeShort(textureIndexPlain); + data.writeShort(textureIndexFruit); + data.writeInt(colourLeaves); + data.writeInt(colourFruits); + } + } + + @Override + public void readData(DataInputStream data) throws IOException { + super.readData(data); + + isRipeningUpdate = data.readByte(); + if(isRipeningUpdate()) { + colourFruits = data.readInt(); + } else { + leafState = data.readByte(); + textureIndexFancy = data.readShort(); + textureIndexPlain = data.readShort(); + textureIndexFruit = data.readShort(); + colourLeaves = data.readInt(); + colourFruits = data.readInt(); + } + } + + public boolean isRipeningUpdate() { + return isRipeningUpdate != 0; + } + + public boolean isFruitLeaf() { + return (leafState & (1 << 0)) > 0; + } + public boolean isPollinated() { + return (leafState & (1 << 1)) > 0; + } +} diff --git a/forestry_common/arboriculture/forestry/arboriculture/proxy/ClientProxyArboriculture.java b/forestry_common/arboriculture/forestry/arboriculture/proxy/ClientProxyArboriculture.java new file mode 100755 index 000000000..968aaf39c --- /dev/null +++ b/forestry_common/arboriculture/forestry/arboriculture/proxy/ClientProxyArboriculture.java @@ -0,0 +1,62 @@ +/******************************************************************************* + * Copyright 2011-2014 by SirSengir + * + * This work is licensed under a Creative Commons Attribution-NonCommercial-NoDerivs 3.0 Unported License. + * + * To view a copy of this license, visit http://creativecommons.org/licenses/by-nc-nd/3.0/. + ******************************************************************************/ +package forestry.arboriculture.proxy; + +import net.minecraft.item.Item; +import net.minecraft.world.ColorizerFoliage; + +import cpw.mods.fml.client.registry.RenderingRegistry; + +import net.minecraftforge.client.MinecraftForgeClient; + +import forestry.arboriculture.render.FenceRenderingHandler; +import forestry.arboriculture.render.FruitPodRenderingHandler; +import forestry.arboriculture.render.LeavesRenderingHandler; +import forestry.arboriculture.render.SaplingRenderHandler; +import forestry.arboriculture.render.StairItemRenderer; +import forestry.core.config.ForestryBlock; +import forestry.core.utils.Localization; +import forestry.plugins.PluginArboriculture; + +public class ClientProxyArboriculture extends ProxyArboriculture { + @Override + public void initializeRendering() { + PluginArboriculture.modelIdSaplings = RenderingRegistry.getNextAvailableRenderId(); + PluginArboriculture.modelIdLeaves = RenderingRegistry.getNextAvailableRenderId(); + PluginArboriculture.modelIdFences = RenderingRegistry.getNextAvailableRenderId(); + PluginArboriculture.modelIdPods = RenderingRegistry.getNextAvailableRenderId(); + + RenderingRegistry.registerBlockHandler(new SaplingRenderHandler()); + RenderingRegistry.registerBlockHandler(new LeavesRenderingHandler()); + RenderingRegistry.registerBlockHandler(new FenceRenderingHandler()); + RenderingRegistry.registerBlockHandler(new FruitPodRenderingHandler()); + + MinecraftForgeClient.registerItemRenderer(Item.getItemFromBlock(ForestryBlock.stairs), new StairItemRenderer()); + } + + @Override + public int getFoliageColorBasic() { + return ColorizerFoliage.getFoliageColorBasic(); + } + + @Override + public int getFoliageColorBirch() { + return ColorizerFoliage.getFoliageColorBirch(); + } + + @Override + public int getFoliageColorPine() { + return ColorizerFoliage.getFoliageColorPine(); + } + + @Override + public void addLocalizations() { + Localization.instance.addLocalization("/lang/forestry/arboriculture/"); + } + +} diff --git a/forestry_common/arboriculture/forestry/arboriculture/proxy/ProxyArboriculture.java b/forestry_common/arboriculture/forestry/arboriculture/proxy/ProxyArboriculture.java new file mode 100755 index 000000000..9e3cbe1db --- /dev/null +++ b/forestry_common/arboriculture/forestry/arboriculture/proxy/ProxyArboriculture.java @@ -0,0 +1,36 @@ +/******************************************************************************* + * Copyright 2011-2014 by SirSengir + * + * This work is licensed under a Creative Commons Attribution-NonCommercial-NoDerivs 3.0 Unported License. + * + * To view a copy of this license, visit http://creativecommons.org/licenses/by-nc-nd/3.0/. + ******************************************************************************/ +package forestry.arboriculture.proxy; + +import net.minecraft.world.World; + +public class ProxyArboriculture { + + public void initializeRendering() { + } + + public int getFoliageColorBasic() { + return 4764952; + } + + public int getFoliageColorBirch() { + return 8431445; + } + + public int getFoliageColorPine() { + return 6396257; + } + + public int getBiomeFoliageColour(World world, int x, int z) { + return getFoliageColorBasic(); + } + + public void addLocalizations() { + } + +} diff --git a/forestry_common/arboriculture/forestry/arboriculture/render/FenceRenderingHandler.java b/forestry_common/arboriculture/forestry/arboriculture/render/FenceRenderingHandler.java new file mode 100755 index 000000000..60bb39e7a --- /dev/null +++ b/forestry_common/arboriculture/forestry/arboriculture/render/FenceRenderingHandler.java @@ -0,0 +1,97 @@ +/******************************************************************************* + * Copyright 2011-2014 by SirSengir + * + * This work is licensed under a Creative Commons Attribution-NonCommercial-NoDerivs 3.0 Unported License. + * + * To view a copy of this license, visit http://creativecommons.org/licenses/by-nc-nd/3.0/. + ******************************************************************************/ +package forestry.arboriculture.render; + +import net.minecraft.block.Block; +import net.minecraft.block.BlockFence; +import net.minecraft.client.renderer.RenderBlocks; +import net.minecraft.client.renderer.Tessellator; +import net.minecraft.world.IBlockAccess; + +import cpw.mods.fml.client.registry.ISimpleBlockRenderingHandler; + +import org.lwjgl.opengl.GL11; + +import forestry.plugins.PluginArboriculture; + +public class FenceRenderingHandler implements ISimpleBlockRenderingHandler { + + @Override + public void renderInventoryBlock(Block block, int metadata, int modelID, RenderBlocks renderer) { + + Tessellator tess = Tessellator.instance; + + for (int i = 0; i < 4; ++i) { + + float thickness = 0.125F; + + if (i == 0) + block.setBlockBounds(0.5F - thickness, 0.0F, 0.0F, 0.5F + thickness, 1.0F, thickness * 2.0F); + + if (i == 1) + block.setBlockBounds(0.5F - thickness, 0.0F, 1.0F - thickness * 2.0F, 0.5F + thickness, 1.0F, 1.0F); + + thickness = 0.0625F; + + if (i == 2) + block.setBlockBounds(0.5F - thickness, 1.0F - thickness * 3.0F, -thickness * 2.0F, 0.5F + thickness, 1.0F - thickness, 1.0F + thickness * 2.0F); + + if (i == 3) + block.setBlockBounds(0.5F - thickness, 0.5F - thickness * 3.0F, -thickness * 2.0F, 0.5F + thickness, 0.5F - thickness, 1.0F + thickness * 2.0F); + + renderer.setRenderBoundsFromBlock(block); + + GL11.glTranslatef(-0.5F, -0.5F, -0.5F); + tess.startDrawingQuads(); + tess.setNormal(0.0F, -1.0F, 0.0F); + renderer.renderFaceYNeg(block, 0.0D, 0.0D, 0.0D, block.getIcon(0, metadata)); + tess.draw(); + tess.startDrawingQuads(); + tess.setNormal(0.0F, 1.0F, 0.0F); + renderer.renderFaceYPos(block, 0.0D, 0.0D, 0.0D, block.getIcon(1, metadata)); + tess.draw(); + tess.startDrawingQuads(); + tess.setNormal(0.0F, 0.0F, -1.0F); + renderer.renderFaceZNeg(block, 0.0D, 0.0D, 0.0D, block.getIcon(2, metadata)); + tess.draw(); + tess.startDrawingQuads(); + tess.setNormal(0.0F, 0.0F, 1.0F); + renderer.renderFaceZPos(block, 0.0D, 0.0D, 0.0D, block.getIcon(3, metadata)); + tess.draw(); + tess.startDrawingQuads(); + tess.setNormal(-1.0F, 0.0F, 0.0F); + renderer.renderFaceXNeg(block, 0.0D, 0.0D, 0.0D, block.getIcon(4, metadata)); + tess.draw(); + tess.startDrawingQuads(); + tess.setNormal(1.0F, 0.0F, 0.0F); + renderer.renderFaceXPos(block, 0.0D, 0.0D, 0.0D, block.getIcon(5, metadata)); + tess.draw(); + GL11.glTranslatef(0.5F, 0.5F, 0.5F); + } + + block.setBlockBounds(0.0F, 0.0F, 0.0F, 1.0F, 1.0F, 1.0F); + renderer.setRenderBoundsFromBlock(block); + + } + + @Override + public boolean renderWorldBlock(IBlockAccess world, int x, int y, int z, Block block, int modelId, RenderBlocks renderer) { + return renderer.renderBlockFence((BlockFence) block, x, y, z); + } + + @Override + public boolean shouldRender3DInInventory(int modelId) { + return true; + } + + @Override + public int getRenderId() { + return PluginArboriculture.modelIdFences; + } + +} diff --git a/forestry_common/arboriculture/forestry/arboriculture/render/FruitPodRenderingHandler.java b/forestry_common/arboriculture/forestry/arboriculture/render/FruitPodRenderingHandler.java new file mode 100755 index 000000000..5029221e3 --- /dev/null +++ b/forestry_common/arboriculture/forestry/arboriculture/render/FruitPodRenderingHandler.java @@ -0,0 +1,191 @@ +/******************************************************************************* + * Copyright 2011-2014 by SirSengir + * + * This work is licensed under a Creative Commons Attribution-NonCommercial-NoDerivs 3.0 Unported License. + * + * To view a copy of this license, visit http://creativecommons.org/licenses/by-nc-nd/3.0/. + ******************************************************************************/ +package forestry.arboriculture.render; + +import net.minecraft.block.Block; +import net.minecraft.block.BlockDirectional; +import net.minecraft.client.renderer.RenderBlocks; +import net.minecraft.client.renderer.Tessellator; +import net.minecraft.util.IIcon; +import net.minecraft.world.IBlockAccess; + +import cpw.mods.fml.client.registry.ISimpleBlockRenderingHandler; + +import forestry.arboriculture.gadgets.BlockFruitPod; +import forestry.arboriculture.gadgets.TileFruitPod; +import forestry.plugins.PluginArboriculture; + +public class FruitPodRenderingHandler implements ISimpleBlockRenderingHandler { + + @Override + public void renderInventoryBlock(Block block, int metadata, int modelID, RenderBlocks renderer) { + } + + @Override + public boolean renderWorldBlock(IBlockAccess world, int x, int y, int z, Block block, int modelId, RenderBlocks renderer) { + + int maturity = 0; + + BlockFruitPod blockPod = (BlockFruitPod) block; + TileFruitPod pod = BlockFruitPod.getPodTile(world, x, y, z); + if (pod != null) + maturity = pod.getMaturity(); + + Tessellator tessellator = Tessellator.instance; + tessellator.setBrightness(blockPod.getMixedBrightnessForBlock(world, x, y, z)); + tessellator.setColorOpaque_F(1.0f, 1.0f, 1.0f); + int metadata = world.getBlockMetadata(x, y, z); + IIcon podIcon = blockPod.getIcon(world, x, y, z, metadata); + int notchDirection = BlockDirectional.getDirection(metadata); + + int k1 = 4 + maturity * 2; + int l1 = 5 + maturity * 2; + double d0 = 15.0D - k1; + double d1 = 15.0D; + double d2 = 4.0D; + double d3 = 4.0D + l1; + double d4 = (double)podIcon.getInterpolatedU(d0); + double d5 = (double)podIcon.getInterpolatedU(d1); + double d6 = (double)podIcon.getInterpolatedV(d2); + double d7 = (double)podIcon.getInterpolatedV(d3); + double d8 = 0.0D; + double d9 = 0.0D; + + switch (notchDirection) { + case 0: + d8 = 8.0D - k1 / 2; + d9 = 15.0D - k1; + break; + case 1: + d8 = 1.0D; + d9 = 8.0D - k1 / 2; + break; + case 2: + d8 = 8.0D - k1 / 2; + d9 = 1.0D; + break; + case 3: + d8 = 15.0D - k1; + d9 = 8.0D - k1 / 2; + } + + double d10 = x + d8 / 16.0D; + double d11 = x + (d8 + k1) / 16.0D; + double d12 = y + (12.0D - l1) / 16.0D; + double d13 = y + 0.75D; + double d14 = z + d9 / 16.0D; + double d15 = z + (d9 + k1) / 16.0D; + tessellator.addVertexWithUV(d10, d12, d14, d4, d7); + tessellator.addVertexWithUV(d10, d12, d15, d5, d7); + tessellator.addVertexWithUV(d10, d13, d15, d5, d6); + tessellator.addVertexWithUV(d10, d13, d14, d4, d6); + tessellator.addVertexWithUV(d11, d12, d15, d4, d7); + tessellator.addVertexWithUV(d11, d12, d14, d5, d7); + tessellator.addVertexWithUV(d11, d13, d14, d5, d6); + tessellator.addVertexWithUV(d11, d13, d15, d4, d6); + tessellator.addVertexWithUV(d11, d12, d14, d4, d7); + tessellator.addVertexWithUV(d10, d12, d14, d5, d7); + tessellator.addVertexWithUV(d10, d13, d14, d5, d6); + tessellator.addVertexWithUV(d11, d13, d14, d4, d6); + tessellator.addVertexWithUV(d10, d12, d15, d4, d7); + tessellator.addVertexWithUV(d11, d12, d15, d5, d7); + tessellator.addVertexWithUV(d11, d13, d15, d5, d6); + tessellator.addVertexWithUV(d10, d13, d15, d4, d6); + int i2 = k1; + + if (maturity >= 2) + i2 = k1 - 1; + + d4 = (double)podIcon.getMinU(); + d5 = (double)podIcon.getInterpolatedU((double)i2); + d6 = (double)podIcon.getMinV(); + d7 = (double)podIcon.getInterpolatedV((double)i2); + + tessellator.addVertexWithUV(d10, d13, d15, d4, d7); + tessellator.addVertexWithUV(d11, d13, d15, d5, d7); + tessellator.addVertexWithUV(d11, d13, d14, d5, d6); + tessellator.addVertexWithUV(d10, d13, d14, d4, d6); + tessellator.addVertexWithUV(d10, d12, d14, d4, d6); + tessellator.addVertexWithUV(d11, d12, d14, d5, d6); + tessellator.addVertexWithUV(d11, d12, d15, d5, d7); + tessellator.addVertexWithUV(d10, d12, d15, d4, d7); + d4 = (double)podIcon.getInterpolatedU(12.0D); + d5 = (double)podIcon.getMaxU(); + d6 = (double)podIcon.getMinV(); + d7 = (double)podIcon.getInterpolatedV(4.0D); + d8 = 8.0D; + d9 = 0.0D; + double d16; + + switch (notchDirection) { + case 0: + d8 = 8.0D; + d9 = 12.0D; + d16 = d4; + d4 = d5; + d5 = d16; + break; + case 1: + d8 = 0.0D; + d9 = 8.0D; + break; + case 2: + d8 = 8.0D; + d9 = 0.0D; + break; + case 3: + d8 = 12.0D; + d9 = 8.0D; + d16 = d4; + d4 = d5; + d5 = d16; + } + + d10 = x + d8 / 16.0D; + d11 = x + (d8 + 4.0D) / 16.0D; + d12 = y + 0.75D; + d13 = y + 1.0D; + d14 = z + d9 / 16.0D; + d15 = z + (d9 + 4.0D) / 16.0D; + + if (notchDirection != 2 && notchDirection != 0) { + if (notchDirection == 1 || notchDirection == 3) { + tessellator.addVertexWithUV(d11, d12, d14, d4, d7); + tessellator.addVertexWithUV(d10, d12, d14, d5, d7); + tessellator.addVertexWithUV(d10, d13, d14, d5, d6); + tessellator.addVertexWithUV(d11, d13, d14, d4, d6); + tessellator.addVertexWithUV(d10, d12, d14, d5, d7); + tessellator.addVertexWithUV(d11, d12, d14, d4, d7); + tessellator.addVertexWithUV(d11, d13, d14, d4, d6); + tessellator.addVertexWithUV(d10, d13, d14, d5, d6); + } + } else { + tessellator.addVertexWithUV(d10, d12, d14, d5, d7); + tessellator.addVertexWithUV(d10, d12, d15, d4, d7); + tessellator.addVertexWithUV(d10, d13, d15, d4, d6); + tessellator.addVertexWithUV(d10, d13, d14, d5, d6); + tessellator.addVertexWithUV(d10, d12, d15, d4, d7); + tessellator.addVertexWithUV(d10, d12, d14, d5, d7); + tessellator.addVertexWithUV(d10, d13, d14, d5, d6); + tessellator.addVertexWithUV(d10, d13, d15, d4, d6); + } + + return true; + } + + @Override + public boolean shouldRender3DInInventory(int modelId) { + return false; + } + + @Override + public int getRenderId() { + return PluginArboriculture.modelIdPods; + } + +} diff --git a/forestry_common/arboriculture/forestry/arboriculture/render/LeavesRenderingHandler.java b/forestry_common/arboriculture/forestry/arboriculture/render/LeavesRenderingHandler.java new file mode 100755 index 000000000..4589694e5 --- /dev/null +++ b/forestry_common/arboriculture/forestry/arboriculture/render/LeavesRenderingHandler.java @@ -0,0 +1,96 @@ +/******************************************************************************* + * Copyright 2011-2014 by SirSengir + * + * This work is licensed under a Creative Commons Attribution-NonCommercial-NoDerivs 3.0 Unported License. + * + * To view a copy of this license, visit http://creativecommons.org/licenses/by-nc-nd/3.0/. + ******************************************************************************/ +package forestry.arboriculture.render; + +import net.minecraft.block.Block; +import net.minecraft.client.renderer.EntityRenderer; +import net.minecraft.client.renderer.RenderBlocks; +import net.minecraft.util.IIcon; +import net.minecraft.world.IBlockAccess; + +import forestry.arboriculture.gadgets.BlockLeaves; +import forestry.arboriculture.gadgets.TileLeaves; +import forestry.core.render.OverlayRenderingHandler; +import forestry.plugins.PluginArboriculture; + +/** + * Ugly but serviceable renderer for leaves, taking fruits into account. + */ +public class LeavesRenderingHandler extends OverlayRenderingHandler { + + @Override + public void renderInventoryBlock(Block block, int metadata, int modelID, RenderBlocks renderer) { + } + + @Override + public boolean renderWorldBlock(IBlockAccess world, int x, int y, int z, Block block, int modelId, RenderBlocks renderer) { + + // Render the plain leaf block. + renderer.renderStandardBlock(block, x, y, z); + + // Render overlay for fruit leaves. + TileLeaves tile = BlockLeaves.getLeafTile(world, x, y, z); + IIcon fruitIcon = null; + int fruitColor = 0xffffff; + if (tile != null) { + fruitIcon = tile.getFruitTexture(); + fruitColor = tile.getFruitColour(); + } + + if (fruitIcon != null) + renderFruitOverlay(world, block, x, y, z, renderer, fruitIcon, fruitColor); + + return true; + } + + @Override + public boolean shouldRender3DInInventory(int modelId) { + return false; + } + + @Override + public int getRenderId() { + return PluginArboriculture.modelIdLeaves; + } + + private boolean renderFruitOverlay(IBlockAccess world, Block block, int x, int y, int z, RenderBlocks renderer, IIcon texture, int multiplier) { + + float mR = (multiplier >> 16 & 255) / 255.0F; + float mG = (multiplier >> 8 & 255) / 255.0F; + float mB = (multiplier & 255) / 255.0F; + + if (EntityRenderer.anaglyphEnable) { + mR = (mR * 30.0F + mG * 59.0F + mB * 11.0F) / 100.0F; + mG = (mR * 30.0F + mG * 70.0F) / 100.0F; + mB = (mR * 30.0F + mB * 70.0F) / 100.0F; + } + + return renderFruitOverlayWithColorMultiplier(world, block, x, y, z, mR, mG, mB, renderer, texture); + } + + private boolean renderFruitOverlayWithColorMultiplier(IBlockAccess world, Block block, int x, int y, int z, float r, float g, float b, + RenderBlocks renderer, IIcon texture) { + + int mixedBrightness = block.getMixedBrightnessForBlock(world, x, y, z); + + float adjR = 0.5f * r; + float adjG = 0.5f * g; + float adjB = 0.5f * b; + + // Bottom + renderBottomFace(world, block, x, y, z, renderer, texture, mixedBrightness, adjR, adjG, adjB); + renderTopFace(world, block, x, y, z, renderer, texture, mixedBrightness, adjR, adjG, adjB); + renderEastFace(world, block, x, y, z, renderer, texture, mixedBrightness, adjR, adjG, adjB); + renderWestFace(world, block, x, y, z, renderer, texture, mixedBrightness, adjR, adjG, adjB); + renderNorthFace(world, block, x, y, z, renderer, texture, mixedBrightness, adjR, adjG, adjB); + renderSouthFace(world, block, x, y, z, renderer, texture, mixedBrightness, adjR, adjG, adjB); + + return true; + } + +} diff --git a/forestry_common/arboriculture/forestry/arboriculture/render/SaplingRenderHandler.java b/forestry_common/arboriculture/forestry/arboriculture/render/SaplingRenderHandler.java new file mode 100755 index 000000000..9f916beaa --- /dev/null +++ b/forestry_common/arboriculture/forestry/arboriculture/render/SaplingRenderHandler.java @@ -0,0 +1,117 @@ +/******************************************************************************* + * Copyright 2011-2014 by SirSengir + * + * This work is licensed under a Creative Commons Attribution-NonCommercial-NoDerivs 3.0 Unported License. + * + * To view a copy of this license, visit http://creativecommons.org/licenses/by-nc-nd/3.0/. + ******************************************************************************/ +package forestry.arboriculture.render; + +import net.minecraft.block.Block; +import net.minecraft.client.renderer.EntityRenderer; +import net.minecraft.client.renderer.RenderBlocks; +import net.minecraft.client.renderer.Tessellator; +import net.minecraft.util.IIcon; +import net.minecraft.world.IBlockAccess; + +import cpw.mods.fml.client.registry.ISimpleBlockRenderingHandler; + +import forestry.api.arboriculture.EnumGermlingType; +import forestry.api.arboriculture.IAlleleTreeSpecies; +import forestry.arboriculture.gadgets.BlockSapling; +import forestry.arboriculture.gadgets.TileSapling; +import forestry.plugins.PluginArboriculture; + +public class SaplingRenderHandler implements ISimpleBlockRenderingHandler { + + public static int renderLayer = 0; + + @Override + public void renderInventoryBlock(Block block, int metadata, int modelID, RenderBlocks renderer) { + } + + @Override + public boolean renderWorldBlock(IBlockAccess world, int x, int y, int z, Block block, int modelId, RenderBlocks renderer) { + + if (modelId != this.getRenderId()) + return false; + + TileSapling tile = BlockSapling.getSaplingTile(world, x, y, z); + + IAlleleTreeSpecies species = (IAlleleTreeSpecies) PluginArboriculture.treeInterface.getDefaultTemplate()[0]; + if (tile == null || tile.getTree() == null) + return true; + species = tile.getTree().getGenome().getPrimary(); + + renderCrossedSquares(species, world, block, x, y, z); + renderLayer = 1; + renderCrossedSquares(species, world, block, x, y, z); + renderLayer = 0; + return true; + } + + @Override + public boolean shouldRender3DInInventory(int modelId) { + return false; + } + + @Override + public int getRenderId() { + return PluginArboriculture.modelIdSaplings; + } + + protected boolean renderCrossedSquares(IAlleleTreeSpecies species, IBlockAccess world, Block block, int x, int y, int z) { + + Tessellator tess = Tessellator.instance; + + tess.setBrightness(block.getMixedBrightnessForBlock(world, x, y, z)); + int colourMultiplier = species.getGermlingColour(EnumGermlingType.SAPLING, renderLayer); + float r = (colourMultiplier >> 16 & 255) / 255.0F; + float g = (colourMultiplier >> 8 & 255) / 255.0F; + float b = (colourMultiplier & 255) / 255.0F; + + if (EntityRenderer.anaglyphEnable) { + + r = (r * 30.0F + g * 59.0F + b * 11.0F) / 100.0F; + g = (r * 30.0F + g * 70.0F) / 100.0F; + b = (r * 30.0F + b * 70.0F) / 100.0F; + } + + tess.setColorOpaque_F(r, g, b); + drawCrossedSquares(world, species, block, x, y, z, x, y, z, 1.0f); + return true; + } + + protected void drawCrossedSquares(IBlockAccess world, IAlleleTreeSpecies species, Block block, int x, int y, int z, double par3, double par5, double par7, float mod) { + + Tessellator tess = Tessellator.instance; + IIcon icon = species.getGermlingIcon(EnumGermlingType.SAPLING, renderLayer); + + double d3 = (double)icon.getMinU(); + double d4 = (double)icon.getMinV(); + double d5 = (double)icon.getMaxU(); + double d6 = (double)icon.getMaxV(); + double d7 = 0.45D * mod; + double d8 = par3 + 0.5D - d7; + double d9 = par3 + 0.5D + d7; + double d10 = par7 + 0.5D - d7; + double d11 = par7 + 0.5D + d7; + tess.addVertexWithUV(d8, par5 + mod, d10, d3, d4); + tess.addVertexWithUV(d8, par5 + 0.0D, d10, d3, d6); + tess.addVertexWithUV(d9, par5 + 0.0D, d11, d5, d6); + tess.addVertexWithUV(d9, par5 + mod, d11, d5, d4); + tess.addVertexWithUV(d9, par5 + mod, d11, d3, d4); + tess.addVertexWithUV(d9, par5 + 0.0D, d11, d3, d6); + tess.addVertexWithUV(d8, par5 + 0.0D, d10, d5, d6); + tess.addVertexWithUV(d8, par5 + mod, d10, d5, d4); + tess.addVertexWithUV(d8, par5 + mod, d11, d3, d4); + tess.addVertexWithUV(d8, par5 + 0.0D, d11, d3, d6); + tess.addVertexWithUV(d9, par5 + 0.0D, d10, d5, d6); + tess.addVertexWithUV(d9, par5 + mod, d10, d5, d4); + tess.addVertexWithUV(d9, par5 + mod, d10, d3, d4); + tess.addVertexWithUV(d9, par5 + 0.0D, d10, d3, d6); + tess.addVertexWithUV(d8, par5 + 0.0D, d11, d5, d6); + tess.addVertexWithUV(d8, par5 + mod, d11, d5, d4); + } + +} diff --git a/forestry_common/arboriculture/forestry/arboriculture/render/StairItemRenderer.java b/forestry_common/arboriculture/forestry/arboriculture/render/StairItemRenderer.java new file mode 100755 index 000000000..b3657a682 --- /dev/null +++ b/forestry_common/arboriculture/forestry/arboriculture/render/StairItemRenderer.java @@ -0,0 +1,104 @@ +/******************************************************************************* + * Copyright 2011-2014 by SirSengir + * + * This work is licensed under a Creative Commons Attribution-NonCommercial-NoDerivs 3.0 Unported License. + * + * To view a copy of this license, visit http://creativecommons.org/licenses/by-nc-nd/3.0/. + ******************************************************************************/ +package forestry.arboriculture.render; + +import net.minecraft.block.Block; +import net.minecraft.client.renderer.RenderBlocks; +import net.minecraft.client.renderer.Tessellator; +import net.minecraft.item.ItemStack; +import net.minecraft.util.IIcon; + +import net.minecraftforge.client.IItemRenderer; + +import org.lwjgl.opengl.GL11; + +import forestry.arboriculture.WoodType; +import forestry.core.utils.StackUtils; + +public class StairItemRenderer implements IItemRenderer { + + private void renderStairBlock(RenderBlocks renderBlocks, ItemStack item, float f, float g, float h) { + + Tessellator tessellator = Tessellator.instance; + Block block = StackUtils.getBlock(item); + + IIcon texture = WoodType.getFromCompound(item.getTagCompound()).getPlankIcon(); + + for (int i = 0; i < 2; ++i) { + if (i == 0) + renderBlocks.setRenderBounds(0.0D, 0.0D, 0.0D, 1.0D, 1.0D, 0.5D); + + if (i == 1) + renderBlocks.setRenderBounds(0.0D, 0.0D, 0.5D, 1.0D, 0.5D, 1.0D); + + GL11.glTranslatef(-0.5F, -0.5F, -0.5F); + tessellator.startDrawingQuads(); + tessellator.setNormal(0.0F, -1.0F, 0.0F); + renderBlocks.renderFaceYNeg(block, 0.0D, 0.0D, 0.0D, texture); + tessellator.draw(); + tessellator.startDrawingQuads(); + tessellator.setNormal(0.0F, 1.0F, 0.0F); + renderBlocks.renderFaceYPos(block, 0.0D, 0.0D, 0.0D, texture); + tessellator.draw(); + tessellator.startDrawingQuads(); + tessellator.setNormal(0.0F, 0.0F, -1.0F); + renderBlocks.renderFaceZNeg(block, 0.0D, 0.0D, 0.0D, texture); + tessellator.draw(); + tessellator.startDrawingQuads(); + tessellator.setNormal(0.0F, 0.0F, 1.0F); + renderBlocks.renderFaceZPos(block, 0.0D, 0.0D, 0.0D, texture); + tessellator.draw(); + tessellator.startDrawingQuads(); + tessellator.setNormal(-1.0F, 0.0F, 0.0F); + renderBlocks.renderFaceXNeg(block, 0.0D, 0.0D, 0.0D, texture); + tessellator.draw(); + tessellator.startDrawingQuads(); + tessellator.setNormal(1.0F, 0.0F, 0.0F); + renderBlocks.renderFaceXPos(block, 0.0D, 0.0D, 0.0D, texture); + tessellator.draw(); + GL11.glTranslatef(0.5F, 0.5F, 0.5F); + } + + } + + @Override + public boolean handleRenderType(ItemStack item, ItemRenderType type) { + switch (type) { + case ENTITY: + case EQUIPPED_FIRST_PERSON: + case EQUIPPED: + case INVENTORY: + return true; + default: + return false; + } + } + + @Override + public boolean shouldUseRenderHelper(ItemRenderType type, ItemStack item, ItemRendererHelper helper) { + return true; + } + + @Override + public void renderItem(ItemRenderType type, ItemStack item, Object... data) { + switch (type) { + case ENTITY: + renderStairBlock((RenderBlocks) data[0], item, -0.5f, -0.5f, -0.5f); + break; + case EQUIPPED: + case EQUIPPED_FIRST_PERSON: + renderStairBlock((RenderBlocks) data[0], item, 0f, 0.0f, 0.0f); + break; + case INVENTORY: + renderStairBlock((RenderBlocks) data[0], item, -0.5f, -0.5f, -0.5f); + break; + default: + } + } + +} diff --git a/forestry_common/arboriculture/forestry/arboriculture/worldgen/BlockTypeLeaf.java b/forestry_common/arboriculture/forestry/arboriculture/worldgen/BlockTypeLeaf.java new file mode 100755 index 000000000..a79423cf8 --- /dev/null +++ b/forestry_common/arboriculture/forestry/arboriculture/worldgen/BlockTypeLeaf.java @@ -0,0 +1,28 @@ +/******************************************************************************* + * Copyright 2011-2014 by SirSengir + * + * This work is licensed under a Creative Commons Attribution-NonCommercial-NoDerivs 3.0 Unported License. + * + * To view a copy of this license, visit http://creativecommons.org/licenses/by-nc-nd/3.0/. + ******************************************************************************/ +package forestry.arboriculture.worldgen; + +import net.minecraft.world.World; + +import forestry.api.world.ITreeGenData; +import forestry.core.config.ForestryBlock; +import forestry.core.worldgen.BlockType; + +public class BlockTypeLeaf extends BlockType { + + private String owner; + + public BlockTypeLeaf(String owner) { + super(ForestryBlock.leaves, 0); + } + + @Override + public void setBlock(World world, ITreeGenData tree, int x, int y, int z) { + tree.setLeaves(world, owner, x, y, z); + } +} diff --git a/forestry_common/arboriculture/forestry/arboriculture/worldgen/BlockTypeVoid.java b/forestry_common/arboriculture/forestry/arboriculture/worldgen/BlockTypeVoid.java new file mode 100755 index 000000000..235b395cc --- /dev/null +++ b/forestry_common/arboriculture/forestry/arboriculture/worldgen/BlockTypeVoid.java @@ -0,0 +1,29 @@ +/******************************************************************************* + * Copyright 2011-2014 by SirSengir + * + * This work is licensed under a Creative Commons Attribution-NonCommercial-NoDerivs 3.0 Unported License. + * + * To view a copy of this license, visit http://creativecommons.org/licenses/by-nc-nd/3.0/. + ******************************************************************************/ +package forestry.arboriculture.worldgen; + +import net.minecraft.init.Blocks; +import net.minecraft.world.World; + +import forestry.api.world.ITreeGenData; +import forestry.core.worldgen.BlockType; + +public class BlockTypeVoid extends BlockType { + + public BlockTypeVoid() { + super(Blocks.air, 0); + } + + @Override + public void setBlock(World world, ITreeGenData tree, int x, int y, int z) { + world.setBlockToAir(x, y, z); + if (world.getTileEntity(x, y, z) != null) + world.removeTileEntity(x, y, z); + } + +} diff --git a/forestry_common/arboriculture/forestry/arboriculture/worldgen/WorldGenAcacia.java b/forestry_common/arboriculture/forestry/arboriculture/worldgen/WorldGenAcacia.java new file mode 100755 index 000000000..e5f1e606a --- /dev/null +++ b/forestry_common/arboriculture/forestry/arboriculture/worldgen/WorldGenAcacia.java @@ -0,0 +1,54 @@ +/******************************************************************************* + * Copyright 2011-2014 by SirSengir + * + * This work is licensed under a Creative Commons Attribution-NonCommercial-NoDerivs 3.0 Unported License. + * + * To view a copy of this license, visit http://creativecommons.org/licenses/by-nc-nd/3.0/. + ******************************************************************************/ +package forestry.arboriculture.worldgen; + +import forestry.api.world.ITreeGenData; +import forestry.core.config.ForestryBlock; +import forestry.core.worldgen.BlockType; + +public class WorldGenAcacia extends WorldGenTree { + + public WorldGenAcacia(ITreeGenData tree) { + super(tree); + } + + @Override + public void generate() { + generateTreeTrunk(height, girth); + + int leafSpawn = height + 1; + + float rnd = world.rand.nextFloat(); + int offset = 0; + if(rnd > 0.6f) + offset = rand.nextInt(girth); + else if(rnd > 0.3) + offset = -rand.nextInt(girth); + + + generateAdjustedCylinder(leafSpawn--, offset, 0, 1, leaf, EnumReplaceMode.NONE); + generateAdjustedCylinder(leafSpawn--, offset, 1.5f, 1, leaf, EnumReplaceMode.NONE); + + if (rand.nextBoolean()) + generateAdjustedCylinder(leafSpawn--, offset, 3.9f, 1, leaf, EnumReplaceMode.NONE); + else + generateAdjustedCylinder(leafSpawn--, offset, 2.9f, 1, leaf, EnumReplaceMode.NONE); + } + + @Override + public void preGenerate() { + height = determineHeight(5, 2); + girth = determineGirth(tree.getGirth(world, startX, startY, startZ)); + } + + @Override + public BlockType getWood() { + return new BlockType(ForestryBlock.log1, 2); + } + +} diff --git a/forestry_common/arboriculture/forestry/arboriculture/worldgen/WorldGenArboriculture.java b/forestry_common/arboriculture/forestry/arboriculture/worldgen/WorldGenArboriculture.java new file mode 100755 index 000000000..9496eced8 --- /dev/null +++ b/forestry_common/arboriculture/forestry/arboriculture/worldgen/WorldGenArboriculture.java @@ -0,0 +1,169 @@ +/******************************************************************************* + * Copyright 2011-2014 by SirSengir + * + * This work is licensed under a Creative Commons Attribution-NonCommercial-NoDerivs 3.0 Unported License. + * + * To view a copy of this license, visit http://creativecommons.org/licenses/by-nc-nd/3.0/. + ******************************************************************************/ +package forestry.arboriculture.worldgen; + +import net.minecraft.init.Blocks; +import net.minecraft.tileentity.TileEntity; + +import forestry.api.world.ITreeGenData; +import forestry.arboriculture.gadgets.TileSapling; +import forestry.core.config.Config; +import forestry.core.utils.Utils; +import forestry.core.utils.Vect; +import forestry.core.worldgen.BlockType; +import forestry.core.worldgen.WorldGenBase; + +public abstract class WorldGenArboriculture extends WorldGenBase { + + protected ITreeGenData tree; + protected int startX; + protected int startY; + protected int startZ; + + protected boolean spawnPods = false; + protected int minPodHeight = 3; + + public WorldGenArboriculture(ITreeGenData tree) { + this.tree = tree; + } + + @Override + public boolean subGenerate(int x, int y, int z) { + this.startX = x; + this.startY = y; + this.startZ = z; + + this.spawnPods = tree.allowsFruitBlocks(); + this.leaf = getLeaf(getOwner()); + this.wood = getWood(); + + preGenerate(); + if (!canGrow()) + return false; + else { + generate(); + return true; + } + + } + + private String getOwner() { + TileEntity tile = world.getTileEntity(startX, startY, startZ); + if (!(tile instanceof TileSapling)) + return Config.fakeUserLogin; + + return ((TileSapling) tile).getOwnerName(); + } + + public abstract void preGenerate(); + + public abstract void generate(); + + public abstract boolean canGrow(); + + public abstract BlockType getLeaf(String owner); + + public abstract BlockType getWood(); + + BlockType leaf; + BlockType wood; + BlockType vine = new BlockType(Blocks.vine, 0); + BlockType air = new BlockTypeVoid(); + + public final Vect getStartVector() { + return new Vect(startX, startY, startZ); + } + + protected void generateTreeTrunk(int height, int girth) { + generateTreeTrunk(height, girth, 0); + } + + protected void generateTreeTrunk(int height, int girth, float vines) { + int offset = (girth - 1) / 2; + for (int x = 0; x < girth; x++) + for (int y = 0; y < girth; y++) + for (int i = 0; i < height; i++) { + addWood(x - offset, i, y - offset, EnumReplaceMode.ALL); + + if (rand.nextFloat() < vines) + addVine(x - offset - 1, i, y - offset); + if (rand.nextFloat() < vines) + addVine(x - offset + 1, i, y - offset); + if (rand.nextFloat() < vines) + addVine(x - offset, i, y - offset - 1); + if (rand.nextFloat() < vines) + addVine(x - offset, i, y - offset + 1); + } + + if (!spawnPods) + return; + + for (int y = minPodHeight; y < height; y++) + for (int x = 0; x < girth; x++) + for (int z = 0; z < girth; z++) { + + if ((x > 0 && x < girth) && (z > 0 && z < girth)) + continue; + + tree.trySpawnFruitBlock(world, startX + x + 1, startY + y, startZ + z); + tree.trySpawnFruitBlock(world, startX + x - 1, startY + y, startZ + z); + tree.trySpawnFruitBlock(world, startX + x, startY + y, startZ + z + 1); + tree.trySpawnFruitBlock(world, startX + x, startY + y, startZ + z - 1); + } + + } + + protected void generateSupportStems(int height, int girth, float chance, float maxHeight) { + + int offset = 1; + + for (int x = -offset; x < girth + offset; x++) + for (int z = -offset; z < girth + offset; z++) { + + if (x == -offset && z == -offset) + continue; + if (x == girth + offset && z == girth + offset) + continue; + if (x == -offset && z == girth + offset) + continue; + if (x == girth + offset && z == -offset) + continue; + + int stemHeight = rand.nextInt(Math.round(height * maxHeight)); + if (rand.nextFloat() < chance) + for (int i = 0; i < stemHeight; i++) + addWood(x, i, z, EnumReplaceMode.SOFT); + } + + } + + @Override + protected void addBlock(int x, int y, int z, BlockType type, EnumReplaceMode replace) { + if (replace == EnumReplaceMode.ALL + || replace == EnumReplaceMode.SOFT && Utils.isReplaceableBlock(world, startX + x, startY + y, startZ + z) + || world.isAirBlock(startX + x, startY + y, startZ + z)) + type.setBlock(world, tree, startX + x, startY + y, startZ + z); + } + + protected final void clearBlock(int x, int y, int z) { + air.setBlock(world, tree, startX + x, startY + y, startZ + z); + } + + protected final void addWood(int x, int y, int z, EnumReplaceMode replace) { + addBlock(x, y, z, wood, replace); + } + + protected final void addLeaf(int x, int y, int z, EnumReplaceMode replace) { + addBlock(x, y, z, leaf, replace); + } + + protected final void addVine(int x, int y, int z) { + addBlock(x, y, z, vine, EnumReplaceMode.NONE); + } + +} diff --git a/forestry_common/arboriculture/forestry/arboriculture/worldgen/WorldGenBalsa.java b/forestry_common/arboriculture/forestry/arboriculture/worldgen/WorldGenBalsa.java new file mode 100755 index 000000000..7120a4638 --- /dev/null +++ b/forestry_common/arboriculture/forestry/arboriculture/worldgen/WorldGenBalsa.java @@ -0,0 +1,52 @@ +/******************************************************************************* + * Copyright 2011-2014 by SirSengir + * + * This work is licensed under a Creative Commons Attribution-NonCommercial-NoDerivs 3.0 Unported License. + * + * To view a copy of this license, visit http://creativecommons.org/licenses/by-nc-nd/3.0/. + ******************************************************************************/ +package forestry.arboriculture.worldgen; + +import forestry.api.world.ITreeGenData; +import forestry.core.config.ForestryBlock; +import forestry.core.worldgen.BlockType; + +public class WorldGenBalsa extends WorldGenTree { + + public WorldGenBalsa(ITreeGenData tree) { + super(tree); + } + + @Override + public void generate() { + generateTreeTrunk(height, girth); + + int leafSpawn = height; + + addLeaf(0, leafSpawn--, 0, EnumReplaceMode.NONE); + generateAdjustedCylinder(leafSpawn--, 0, 1, leaf); + + if (height > 10) + generateAdjustedCylinder(leafSpawn--, 0, 1, leaf); + + leafSpawn--; + + while (leafSpawn > 6) { + generateAdjustedCylinder(leafSpawn, 0, 1, leaf); + leafSpawn--; + } + + } + + @Override + public void preGenerate() { + height = determineHeight(6, 6); + girth = determineGirth(tree.getGirth(world, startX, startY, startZ)); + } + + @Override + public BlockType getWood() { + return new BlockType(ForestryBlock.log3, 3); + } + +} diff --git a/forestry_common/arboriculture/forestry/arboriculture/worldgen/WorldGenBaobab.java b/forestry_common/arboriculture/forestry/arboriculture/worldgen/WorldGenBaobab.java new file mode 100755 index 000000000..bb62d5431 --- /dev/null +++ b/forestry_common/arboriculture/forestry/arboriculture/worldgen/WorldGenBaobab.java @@ -0,0 +1,70 @@ +/******************************************************************************* + * Copyright 2011-2014 by SirSengir + * + * This work is licensed under a Creative Commons Attribution-NonCommercial-NoDerivs 3.0 Unported License. + * + * To view a copy of this license, visit http://creativecommons.org/licenses/by-nc-nd/3.0/. + ******************************************************************************/ +package forestry.arboriculture.worldgen; + +import forestry.api.world.ITreeGenData; +import forestry.core.config.ForestryBlock; +import forestry.core.worldgen.BlockType; + +public class WorldGenBaobab extends WorldGenTree { + + public WorldGenBaobab(ITreeGenData tree) { + super(tree); + } + + @Override + public void generate() { + generateTreeTrunk(height - 1, girth); + + if (rand.nextFloat() < 0.3f) + generateCylinder(new Vector(0, height - 1, 0), girth, 1, wood, EnumReplaceMode.NONE); + else if (rand.nextBoolean()) + generateCylinder(new Vector(0, height - 1, 0), girth - 1, 1, wood, EnumReplaceMode.NONE); + + int leafSpawn = height + 1; + + generateAdjustedCylinder(leafSpawn--, 2f, 1, leaf); + generateAdjustedCylinder(leafSpawn--, 1.5f, 1, leaf); + generateAdjustedCylinder(leafSpawn--, 1f, 1, leaf); + + // Add tree top + for (int times = 0; times < height / 2; times++) { + int h = height - 1 + rand.nextInt(4); + if (rand.nextBoolean() && h < height / 2) + h = height / 2 + rand.nextInt(height / 2); + + int x_off = -girth + rand.nextInt(2 * girth); + int y_off = -girth + rand.nextInt(2 * girth); + generateSphere(new Vector(x_off, h, y_off), 1 + (girth > 1 ? rand.nextInt(girth - 1) : 0), leaf, EnumReplaceMode.NONE); + } + + // Add some smaller twigs below for flavour + for (int times = 0; times < height / 4; times++) { + int delim = modifyByHeight(6, 0, height); + int h = delim + (delim < height ? rand.nextInt(height - delim) : 0); + if (rand.nextBoolean() && h < height / 2) + h = height / 2 + rand.nextInt(height / 2); + int x_off = -1 + rand.nextInt(3); + int y_off = -1 + rand.nextInt(3); + generateSphere(new Vector(x_off, h, y_off), 1 + rand.nextInt(2), leaf, EnumReplaceMode.NONE); + } + + } + + @Override + public void preGenerate() { + height = determineHeight(6, 6); + girth = determineGirth(tree.getGirth(world, startX, startY, startZ)); + } + + @Override + public BlockType getWood() { + return new BlockType(ForestryBlock.log2, 2); + } + +} diff --git a/forestry_common/arboriculture/forestry/arboriculture/worldgen/WorldGenBirch.java b/forestry_common/arboriculture/forestry/arboriculture/worldgen/WorldGenBirch.java new file mode 100755 index 000000000..e106ba986 --- /dev/null +++ b/forestry_common/arboriculture/forestry/arboriculture/worldgen/WorldGenBirch.java @@ -0,0 +1,26 @@ +/******************************************************************************* + * Copyright 2011-2014 by SirSengir + * + * This work is licensed under a Creative Commons Attribution-NonCommercial-NoDerivs 3.0 Unported License. + * + * To view a copy of this license, visit http://creativecommons.org/licenses/by-nc-nd/3.0/. + ******************************************************************************/ +package forestry.arboriculture.worldgen; + +import net.minecraft.init.Blocks; + +import forestry.api.world.ITreeGenData; +import forestry.core.worldgen.BlockType; + +public class WorldGenBirch extends WorldGenTree { + + public WorldGenBirch(ITreeGenData tree) { + super(tree); + } + + @Override + public BlockType getWood() { + return new BlockType(Blocks.log, 2); + } + +} diff --git a/forestry_common/arboriculture/forestry/arboriculture/worldgen/WorldGenCherry.java b/forestry_common/arboriculture/forestry/arboriculture/worldgen/WorldGenCherry.java new file mode 100755 index 000000000..400214d58 --- /dev/null +++ b/forestry_common/arboriculture/forestry/arboriculture/worldgen/WorldGenCherry.java @@ -0,0 +1,46 @@ +/******************************************************************************* + * Copyright 2011-2014 by SirSengir + * + * This work is licensed under a Creative Commons Attribution-NonCommercial-NoDerivs 3.0 Unported License. + * + * To view a copy of this license, visit http://creativecommons.org/licenses/by-nc-nd/3.0/. + ******************************************************************************/ +package forestry.arboriculture.worldgen; + +import forestry.api.world.ITreeGenData; +import forestry.core.config.ForestryBlock; +import forestry.core.worldgen.BlockType; + +public class WorldGenCherry extends WorldGenTree { + + public WorldGenCherry(ITreeGenData tree) { + super(tree); + } + + @Override + public void generate() { + generateTreeTrunk(height, girth); + + int leafSpawn = height + 1; + + generateAdjustedCylinder(leafSpawn--, 0, 1, leaf); + generateAdjustedCylinder(leafSpawn--, 1, 1, leaf); + while (leafSpawn > 2) { + generateAdjustedCylinder(leafSpawn--, 2, 1, leaf); + generateAdjustedCylinder(leafSpawn--, 1, 1, leaf); + } + + } + + @Override + public void preGenerate() { + height = determineHeight(4, 4); + girth = determineGirth(tree.getGirth(world, startX, startY, startZ)); + } + + @Override + public BlockType getWood() { + return new BlockType(ForestryBlock.log4, 3); + } + +} diff --git a/forestry_common/arboriculture/forestry/arboriculture/worldgen/WorldGenChestnut.java b/forestry_common/arboriculture/forestry/arboriculture/worldgen/WorldGenChestnut.java new file mode 100755 index 000000000..eb0f7b2b6 --- /dev/null +++ b/forestry_common/arboriculture/forestry/arboriculture/worldgen/WorldGenChestnut.java @@ -0,0 +1,50 @@ +/******************************************************************************* + * Copyright 2011-2014 by SirSengir + * + * This work is licensed under a Creative Commons Attribution-NonCommercial-NoDerivs 3.0 Unported License. + * + * To view a copy of this license, visit http://creativecommons.org/licenses/by-nc-nd/3.0/. + ******************************************************************************/ +package forestry.arboriculture.worldgen; + +import forestry.api.world.ITreeGenData; +import forestry.core.config.ForestryBlock; +import forestry.core.worldgen.BlockType; + +public class WorldGenChestnut extends WorldGenTree { + + public WorldGenChestnut(ITreeGenData tree) { + super(tree); + + minHeight = 7; + } + + @Override + public void generate() { + generateTreeTrunk(height, girth); + + int leafSpawn = height + 1; + + generateAdjustedCylinder(leafSpawn--, 0, 1, leaf); + generateAdjustedCylinder(leafSpawn--, 0.5f, 1, leaf); + + while (leafSpawn > 4) + generateAdjustedCylinder(leafSpawn--, 2f, 1, leaf); + if (rand.nextBoolean()) + generateAdjustedCylinder(leafSpawn--, 2f, 1, leaf); + generateAdjustedCylinder(leafSpawn--, 1.5f, 1, leaf); + + } + + @Override + public void preGenerate() { + height = determineHeight(7, 3); + girth = determineGirth(tree.getGirth(world, startX, startY, startZ)); + } + + @Override + public BlockType getWood() { + return new BlockType(ForestryBlock.log2, 0); + } + +} diff --git a/forestry_common/arboriculture/forestry/arboriculture/worldgen/WorldGenDate.java b/forestry_common/arboriculture/forestry/arboriculture/worldgen/WorldGenDate.java new file mode 100755 index 000000000..846f16dce --- /dev/null +++ b/forestry_common/arboriculture/forestry/arboriculture/worldgen/WorldGenDate.java @@ -0,0 +1,43 @@ +/******************************************************************************* + * Copyright 2011-2014 by SirSengir + * + * This work is licensed under a Creative Commons Attribution-NonCommercial-NoDerivs 3.0 Unported License. + * + * To view a copy of this license, visit http://creativecommons.org/licenses/by-nc-nd/3.0/. + ******************************************************************************/ +package forestry.arboriculture.worldgen; + +import forestry.api.world.ITreeGenData; +import forestry.core.config.ForestryBlock; +import forestry.core.worldgen.BlockType; + +public class WorldGenDate extends WorldGenTree { + + public WorldGenDate(ITreeGenData tree) { + super(tree); + } + + @Override + public void generate() { + generateTreeTrunk(height, girth); + + int leafSpawn = height + 1; + + generateAdjustedCylinder(leafSpawn--, 2f, 1, leaf); + generateAdjustedCylinder(leafSpawn--, 0.5f, 1, leaf); + generateAdjustedCylinder(leafSpawn--, 0, 1, leaf); + + } + + @Override + public BlockType getWood() { + return new BlockType(ForestryBlock.log5, 2); + } + + @Override + public void preGenerate() { + height = determineHeight(6, 2); + girth = determineGirth(tree.getGirth(world, startX, startY, startZ)); + } + +} diff --git a/forestry_common/arboriculture/forestry/arboriculture/worldgen/WorldGenEbony.java b/forestry_common/arboriculture/forestry/arboriculture/worldgen/WorldGenEbony.java new file mode 100755 index 000000000..39f280146 --- /dev/null +++ b/forestry_common/arboriculture/forestry/arboriculture/worldgen/WorldGenEbony.java @@ -0,0 +1,67 @@ +/******************************************************************************* + * Copyright 2011-2014 by SirSengir + * + * This work is licensed under a Creative Commons Attribution-NonCommercial-NoDerivs 3.0 Unported License. + * + * To view a copy of this license, visit http://creativecommons.org/licenses/by-nc-nd/3.0/. + ******************************************************************************/ +package forestry.arboriculture.worldgen; + +import forestry.api.world.ITreeGenData; +import forestry.core.config.ForestryBlock; +import forestry.core.worldgen.BlockType; + +public class WorldGenEbony extends WorldGenTree { + + public WorldGenEbony(ITreeGenData tree) { + super(tree); + } + + @Override + public void generate() { + + int offset = (girth - 1) / 2; + int trunksgenerated = 0; + + for (int x = -offset; x < -offset + girth; x++) + for (int z = -offset; z < -offset + girth; z++) + if (rand.nextFloat() < 0.6f) { + for (int i = 0; i < height; i++) { + addWood(x, i, z, EnumReplaceMode.ALL); + if (i > height / 2 && rand.nextFloat() < 0.1f * (10 / height)) + break; + } + trunksgenerated++; + } else + for (int i = 0; i < 1; i++) + clearBlock(x, i, z); + + // Generate backup trunk, if we failed to generate any. + if (trunksgenerated <= 0) + generateTreeTrunk(height, 1, 0.6f); + + // Add tree top + for (int times = 0; times < 2 * height; times++) { + int h = 2 * girth + rand.nextInt(height - girth); + if (rand.nextBoolean() && h < height / 2) + h = height / 2 + rand.nextInt(height / 2); + + int x_off = -(girth) + rand.nextInt(2 * girth); + int y_off = -(girth) + rand.nextInt(2 * girth); + generateSphere(new Vector(x_off, h, y_off), 1 + rand.nextInt(girth), leaf, EnumReplaceMode.NONE); + } + + } + + @Override + public void preGenerate() { + height = determineHeight(10, 4); + girth = determineGirth(tree.getGirth(world, startX, startY, startZ)); + } + + @Override + public BlockType getWood() { + return new BlockType(ForestryBlock.log3, 1); + } + +} diff --git a/forestry_common/arboriculture/forestry/arboriculture/worldgen/WorldGenGiganteum.java b/forestry_common/arboriculture/forestry/arboriculture/worldgen/WorldGenGiganteum.java new file mode 100755 index 000000000..925a208a2 --- /dev/null +++ b/forestry_common/arboriculture/forestry/arboriculture/worldgen/WorldGenGiganteum.java @@ -0,0 +1,37 @@ +/******************************************************************************* + * Copyright 2011-2014 by SirSengir + * + * This work is licensed under a Creative Commons Attribution-NonCommercial-NoDerivs 3.0 Unported License. + * + * To view a copy of this license, visit http://creativecommons.org/licenses/by-nc-nd/3.0/. + ******************************************************************************/ +package forestry.arboriculture.worldgen; + +import forestry.api.world.ITreeGenData; +import forestry.core.config.ForestryBlock; +import forestry.core.worldgen.BlockType; + +public class WorldGenGiganteum extends WorldGenSequoia { + + public WorldGenGiganteum(ITreeGenData tree) { + super(tree); + } + + @Override + public void generate() { + super.generate(); + //generateSupportStems(height, girth, 0.8f, 0.6f); + } + + @Override + public void preGenerate() { + height = determineHeight(35, 15); + girth = determineGirth(tree.getGirth(world, startX, startY, startZ)); + } + + @Override + public BlockType getWood() { + return new BlockType(ForestryBlock.log7, 0); + } + +} diff --git a/forestry_common/arboriculture/forestry/arboriculture/worldgen/WorldGenGreenheart.java b/forestry_common/arboriculture/forestry/arboriculture/worldgen/WorldGenGreenheart.java new file mode 100755 index 000000000..68097da23 --- /dev/null +++ b/forestry_common/arboriculture/forestry/arboriculture/worldgen/WorldGenGreenheart.java @@ -0,0 +1,61 @@ +/******************************************************************************* + * Copyright 2011-2014 by SirSengir + * + * This work is licensed under a Creative Commons Attribution-NonCommercial-NoDerivs 3.0 Unported License. + * + * To view a copy of this license, visit http://creativecommons.org/licenses/by-nc-nd/3.0/. + ******************************************************************************/ +package forestry.arboriculture.worldgen; + +import forestry.api.world.ITreeGenData; +import forestry.core.config.ForestryBlock; +import forestry.core.worldgen.BlockType; + +public class WorldGenGreenheart extends WorldGenTree { + + public WorldGenGreenheart(ITreeGenData tree) { + super(tree); + } + + @Override + public void generate() { + + generateTreeTrunk(height, girth, 0.4f); + generateSupportStems(height, girth, 0.1f, 0.2f); + + int leafSpawn = height + 1; + + generateAdjustedCylinder(leafSpawn--, 0, 1, leaf); + generateAdjustedCylinder(leafSpawn--, 0.5f, 1, leaf); + + generateAdjustedCylinder(leafSpawn--, 1.5f, 1, leaf); + + while (leafSpawn > height - 4) + generateAdjustedCylinder(leafSpawn--, 1.9f, 1, leaf); + generateAdjustedCylinder(leafSpawn--, 1.5f, 1, leaf); + generateAdjustedCylinder(leafSpawn--, 0.5f, 1, leaf); + + // Add some smaller twigs below for flavour + for (int times = 0; times < height / 4; times++) { + int h = 10 + rand.nextInt(height - 10); + if (rand.nextBoolean() && h < height / 2) + h = height / 2 + rand.nextInt(height / 2); + int x_off = -1 + rand.nextInt(3); + int y_off = -1 + rand.nextInt(3); + generateSphere(new Vector(x_off, h, y_off), 1 + rand.nextInt(1), leaf, EnumReplaceMode.NONE); + } + + } + + @Override + public void preGenerate() { + height = determineHeight(10, 8); + girth = determineGirth(tree.getGirth(world, startX, startY, startZ)); + } + + @Override + public BlockType getWood() { + return new BlockType(ForestryBlock.log4, 2); + } + +} diff --git a/forestry_common/arboriculture/forestry/arboriculture/worldgen/WorldGenJungle.java b/forestry_common/arboriculture/forestry/arboriculture/worldgen/WorldGenJungle.java new file mode 100755 index 000000000..7ac7a3f82 --- /dev/null +++ b/forestry_common/arboriculture/forestry/arboriculture/worldgen/WorldGenJungle.java @@ -0,0 +1,44 @@ +/******************************************************************************* + * Copyright 2011-2014 by SirSengir + * + * This work is licensed under a Creative Commons Attribution-NonCommercial-NoDerivs 3.0 Unported License. + * + * To view a copy of this license, visit http://creativecommons.org/licenses/by-nc-nd/3.0/. + ******************************************************************************/ +package forestry.arboriculture.worldgen; + +import net.minecraft.init.Blocks; + +import forestry.api.world.ITreeGenData; +import forestry.core.worldgen.BlockType; + +/** + * This is a dummy and needs to be replaced with something proper. + */ +public class WorldGenJungle extends WorldGenTree { + + public WorldGenJungle(ITreeGenData tree) { + super(tree); + } + + @Override + public void generate() { + + generateTreeTrunk(height, girth); + + int leafSpawn = height + 1; + + generateAdjustedCylinder(leafSpawn--, 0, 1, leaf); + generateAdjustedCylinder(leafSpawn--, 0.5f, 1, leaf); + + generateAdjustedCylinder(leafSpawn--, 1.9f, 1, leaf); + generateAdjustedCylinder(leafSpawn--, 1.9f, 1, leaf); + + } + + @Override + public BlockType getWood() { + return new BlockType(Blocks.log, 3); + } + +} diff --git a/forestry_common/arboriculture/forestry/arboriculture/worldgen/WorldGenKapok.java b/forestry_common/arboriculture/forestry/arboriculture/worldgen/WorldGenKapok.java new file mode 100755 index 000000000..de0ea2467 --- /dev/null +++ b/forestry_common/arboriculture/forestry/arboriculture/worldgen/WorldGenKapok.java @@ -0,0 +1,60 @@ +/******************************************************************************* + * Copyright 2011-2014 by SirSengir + * + * This work is licensed under a Creative Commons Attribution-NonCommercial-NoDerivs 3.0 Unported License. + * + * To view a copy of this license, visit http://creativecommons.org/licenses/by-nc-nd/3.0/. + ******************************************************************************/ +package forestry.arboriculture.worldgen; + +import forestry.api.world.ITreeGenData; +import forestry.core.config.ForestryBlock; +import forestry.core.worldgen.BlockType; + +public class WorldGenKapok extends WorldGenTree { + + public WorldGenKapok(ITreeGenData tree) { + super(tree); + } + + @Override + public void generate() { + + generateTreeTrunk(height, girth, 0.6f); + generateSupportStems(height, girth, 0.2f, 0.2f); + + int leafSpawn = height + 1; + + generateAdjustedCylinder(leafSpawn--, 0, 1, leaf); + generateAdjustedCylinder(leafSpawn--, 0.5f, 1, leaf); + + generateAdjustedCylinder(leafSpawn--, 1.9f, 1, leaf); + + while (leafSpawn > height - 4) + generateAdjustedCylinder(leafSpawn--, 2.5f, 1, leaf); + generateAdjustedCylinder(leafSpawn--, 1.9f, 1, leaf); + + // Add some smaller twigs below for flavour + for (int times = 0; times < height / 4; times++) { + int h = 10 + rand.nextInt(Math.max(1, height - 10)); + if (rand.nextBoolean() && h < height / 2) + h = height / 2 + rand.nextInt(height / 2); + int x_off = -1 + rand.nextInt(3); + int y_off = -1 + rand.nextInt(3); + generateSphere(new Vector(x_off, h, y_off), 1 + rand.nextInt(1), leaf, EnumReplaceMode.NONE); + } + + } + + @Override + public void preGenerate() { + height = determineHeight(10, 8); + girth = determineGirth(tree.getGirth(world, startX, startY, startZ)); + } + + @Override + public BlockType getWood() { + return new BlockType(ForestryBlock.log3, 0); + } + +} diff --git a/forestry_common/arboriculture/forestry/arboriculture/worldgen/WorldGenLarch.java b/forestry_common/arboriculture/forestry/arboriculture/worldgen/WorldGenLarch.java new file mode 100755 index 000000000..1a565ae48 --- /dev/null +++ b/forestry_common/arboriculture/forestry/arboriculture/worldgen/WorldGenLarch.java @@ -0,0 +1,47 @@ +/******************************************************************************* + * Copyright 2011-2014 by SirSengir + * + * This work is licensed under a Creative Commons Attribution-NonCommercial-NoDerivs 3.0 Unported License. + * + * To view a copy of this license, visit http://creativecommons.org/licenses/by-nc-nd/3.0/. + ******************************************************************************/ +package forestry.arboriculture.worldgen; + +import forestry.api.world.ITreeGenData; +import forestry.core.config.ForestryBlock; +import forestry.core.worldgen.BlockType; + +public class WorldGenLarch extends WorldGenTree { + + public WorldGenLarch(ITreeGenData tree) { + super(tree); + } + + @Override + public void generate() { + generateTreeTrunk(height, girth); + + int leafSpawn = height + 1; + + generateAdjustedCylinder(leafSpawn--, 0, 1, leaf); + generateAdjustedCylinder(leafSpawn--, 1, 1, leaf); + + while (leafSpawn > 2) { + generateAdjustedCylinder(leafSpawn--, 2, 1, leaf); + generateAdjustedCylinder(leafSpawn--, 1, 1, leaf); + } + + } + + @Override + public void preGenerate() { + height = determineHeight(6, 5); + girth = determineGirth(tree.getGirth(world, startX, startY, startZ)); + } + + @Override + public BlockType getWood() { + return new BlockType(ForestryBlock.log1, 0); + } + +} diff --git a/forestry_common/arboriculture/forestry/arboriculture/worldgen/WorldGenLemon.java b/forestry_common/arboriculture/forestry/arboriculture/worldgen/WorldGenLemon.java new file mode 100755 index 000000000..146a97544 --- /dev/null +++ b/forestry_common/arboriculture/forestry/arboriculture/worldgen/WorldGenLemon.java @@ -0,0 +1,41 @@ +/******************************************************************************* + * Copyright 2011-2014 by SirSengir + * + * This work is licensed under a Creative Commons Attribution-NonCommercial-NoDerivs 3.0 Unported License. + * + * To view a copy of this license, visit http://creativecommons.org/licenses/by-nc-nd/3.0/. + ******************************************************************************/ +package forestry.arboriculture.worldgen; + +import forestry.api.world.ITreeGenData; +import forestry.core.config.ForestryBlock; +import forestry.core.worldgen.BlockType; + +public class WorldGenLemon extends WorldGenTree { + + public WorldGenLemon(ITreeGenData tree) { + super(tree); + } + + @Override + public void generate() { + generateTreeTrunk(height, girth); + + int yCenter = height - girth; + yCenter = yCenter > 2 ? yCenter : 3; + generateSphere(getCenteredAt(yCenter, 0), 2 + rand.nextInt(girth), leaf, EnumReplaceMode.NONE); + + } + + @Override + public BlockType getWood() { + return new BlockType(ForestryBlock.log6, 3); + } + + @Override + public void preGenerate() { + height = determineHeight(6, 3); + girth = determineGirth(tree.getGirth(world, startX, startY, startZ)); + } + +} diff --git a/forestry_common/arboriculture/forestry/arboriculture/worldgen/WorldGenLime.java b/forestry_common/arboriculture/forestry/arboriculture/worldgen/WorldGenLime.java new file mode 100755 index 000000000..d9caceb9d --- /dev/null +++ b/forestry_common/arboriculture/forestry/arboriculture/worldgen/WorldGenLime.java @@ -0,0 +1,44 @@ +/******************************************************************************* + * Copyright 2011-2014 by SirSengir + * + * This work is licensed under a Creative Commons Attribution-NonCommercial-NoDerivs 3.0 Unported License. + * + * To view a copy of this license, visit http://creativecommons.org/licenses/by-nc-nd/3.0/. + ******************************************************************************/ +package forestry.arboriculture.worldgen; + +import forestry.api.world.ITreeGenData; +import forestry.core.config.ForestryBlock; +import forestry.core.worldgen.BlockType; + +public class WorldGenLime extends WorldGenTree { + + public WorldGenLime(ITreeGenData tree) { + super(tree); + } + + @Override + public void generate() { + generateTreeTrunk(height, girth); + + int leafSpawn = height + 1; + + generateAdjustedCylinder(leafSpawn--, 0, 1, leaf); + generateAdjustedCylinder(leafSpawn--, 1, 1, leaf); + while (leafSpawn > 1) + generateAdjustedCylinder(leafSpawn--, 1, 1, leaf); + + } + + @Override + public void preGenerate() { + height = determineHeight(6, 4); + girth = determineGirth(tree.getGirth(world, startX, startY, startZ)); + } + + @Override + public BlockType getWood() { + return new BlockType(ForestryBlock.log1, 3); + } + +} diff --git a/forestry_common/arboriculture/forestry/arboriculture/worldgen/WorldGenMahoe.java b/forestry_common/arboriculture/forestry/arboriculture/worldgen/WorldGenMahoe.java new file mode 100755 index 000000000..57602019e --- /dev/null +++ b/forestry_common/arboriculture/forestry/arboriculture/worldgen/WorldGenMahoe.java @@ -0,0 +1,41 @@ +/******************************************************************************* + * Copyright 2011-2014 by SirSengir + * + * This work is licensed under a Creative Commons Attribution-NonCommercial-NoDerivs 3.0 Unported License. + * + * To view a copy of this license, visit http://creativecommons.org/licenses/by-nc-nd/3.0/. + ******************************************************************************/ +package forestry.arboriculture.worldgen; + +import forestry.api.world.ITreeGenData; +import forestry.core.config.ForestryBlock; +import forestry.core.worldgen.BlockType; + +public class WorldGenMahoe extends WorldGenTree { + + public WorldGenMahoe(ITreeGenData tree) { + super(tree); + } + + @Override + public void generate() { + generateTreeTrunk(height, girth); + + int yCenter = height - girth; + yCenter = yCenter > 3 ? yCenter : 4; + generateSphere(getCenteredAt(yCenter, 0), 3 + rand.nextInt(girth), leaf, EnumReplaceMode.NONE); + + } + + @Override + public BlockType getWood() { + return new BlockType(ForestryBlock.log5, 0); + } + + @Override + public void preGenerate() { + height = determineHeight(6, 3); + girth = determineGirth(tree.getGirth(world, startX, startY, startZ)); + } + +} diff --git a/forestry_common/arboriculture/forestry/arboriculture/worldgen/WorldGenMahogany.java b/forestry_common/arboriculture/forestry/arboriculture/worldgen/WorldGenMahogany.java new file mode 100755 index 000000000..4576507c5 --- /dev/null +++ b/forestry_common/arboriculture/forestry/arboriculture/worldgen/WorldGenMahogany.java @@ -0,0 +1,49 @@ +/******************************************************************************* + * Copyright 2011-2014 by SirSengir + * + * This work is licensed under a Creative Commons Attribution-NonCommercial-NoDerivs 3.0 Unported License. + * + * To view a copy of this license, visit http://creativecommons.org/licenses/by-nc-nd/3.0/. + ******************************************************************************/ +package forestry.arboriculture.worldgen; + +import forestry.api.world.ITreeGenData; +import forestry.core.config.ForestryBlock; +import forestry.core.worldgen.BlockType; + +public class WorldGenMahogany extends WorldGenTree { + + public WorldGenMahogany(ITreeGenData tree) { + super(tree); + } + + @Override + public void generate() { + generateTreeTrunk(height, girth, 0.6f); + generateSupportStems(height, girth, 0.4f, 0.4f); + + int leafSpawn = height + 1; + + generateAdjustedCylinder(leafSpawn--, 0, 1, leaf); + + generateAdjustedCylinder(leafSpawn--, 1.5f, 1, leaf); + generateAdjustedCylinder(leafSpawn--, 2f, 1, leaf); + + generateAdjustedCylinder(leafSpawn--, 3f, 1, leaf); + generateAdjustedCylinder(leafSpawn--, 3f, 1, leaf); + generateAdjustedCylinder(leafSpawn--, 2f, 1, leaf); + + } + + @Override + public void preGenerate() { + height = determineHeight(12, 6); + girth = determineGirth(tree.getGirth(world, startX, startY, startZ)); + } + + @Override + public BlockType getWood() { + return new BlockType(ForestryBlock.log3, 2); + } + +} diff --git a/forestry_common/arboriculture/forestry/arboriculture/worldgen/WorldGenMaple.java b/forestry_common/arboriculture/forestry/arboriculture/worldgen/WorldGenMaple.java new file mode 100755 index 000000000..3ea6333ea --- /dev/null +++ b/forestry_common/arboriculture/forestry/arboriculture/worldgen/WorldGenMaple.java @@ -0,0 +1,50 @@ +/******************************************************************************* + * Copyright 2011-2014 by SirSengir + * + * This work is licensed under a Creative Commons Attribution-NonCommercial-NoDerivs 3.0 Unported License. + * + * To view a copy of this license, visit http://creativecommons.org/licenses/by-nc-nd/3.0/. + ******************************************************************************/ +package forestry.arboriculture.worldgen; + +import forestry.api.world.ITreeGenData; +import forestry.core.config.ForestryBlock; +import forestry.core.worldgen.BlockType; + +public class WorldGenMaple extends WorldGenTree { + + public WorldGenMaple(ITreeGenData tree) { + super(tree); + } + + @Override + public void generate() { + generateTreeTrunk(height, girth); + + int leafSpawn = height + 1; + float diameterchange = (float) 1 / height; + int leafSpawned = 2; + + generateAdjustedCylinder(leafSpawn--, 0, 1, leaf); + generateAdjustedCylinder(leafSpawn--, 1, 1, leaf); + + while (leafSpawn > 1) { + generateAdjustedCylinder(leafSpawn--, 3 * diameterchange * leafSpawned, 1, leaf); + generateAdjustedCylinder(leafSpawn--, 2 * diameterchange * leafSpawned, 1, leaf); + leafSpawned += 2; + } + + } + + @Override + public void preGenerate() { + height = determineHeight(7, 5); + girth = determineGirth(tree.getGirth(world, startX, startY, startZ)); + } + + @Override + public BlockType getWood() { + return new BlockType(ForestryBlock.log6, 2); + } + +} diff --git a/forestry_common/arboriculture/forestry/arboriculture/worldgen/WorldGenOak.java b/forestry_common/arboriculture/forestry/arboriculture/worldgen/WorldGenOak.java new file mode 100755 index 000000000..a1b5f0a4d --- /dev/null +++ b/forestry_common/arboriculture/forestry/arboriculture/worldgen/WorldGenOak.java @@ -0,0 +1,26 @@ +/******************************************************************************* + * Copyright 2011-2014 by SirSengir + * + * This work is licensed under a Creative Commons Attribution-NonCommercial-NoDerivs 3.0 Unported License. + * + * To view a copy of this license, visit http://creativecommons.org/licenses/by-nc-nd/3.0/. + ******************************************************************************/ +package forestry.arboriculture.worldgen; + +import net.minecraft.init.Blocks; + +import forestry.api.world.ITreeGenData; +import forestry.core.worldgen.BlockType; + +public class WorldGenOak extends WorldGenTree { + + public WorldGenOak(ITreeGenData tree) { + super(tree); + } + + @Override + public BlockType getWood() { + return new BlockType(Blocks.log, 0); + } + +} diff --git a/forestry_common/arboriculture/forestry/arboriculture/worldgen/WorldGenPapaya.java b/forestry_common/arboriculture/forestry/arboriculture/worldgen/WorldGenPapaya.java new file mode 100755 index 000000000..4df4d813c --- /dev/null +++ b/forestry_common/arboriculture/forestry/arboriculture/worldgen/WorldGenPapaya.java @@ -0,0 +1,41 @@ +/******************************************************************************* + * Copyright 2011-2014 by SirSengir + * + * This work is licensed under a Creative Commons Attribution-NonCommercial-NoDerivs 3.0 Unported License. + * + * To view a copy of this license, visit http://creativecommons.org/licenses/by-nc-nd/3.0/. + ******************************************************************************/ +package forestry.arboriculture.worldgen; + +import forestry.api.world.ITreeGenData; +import forestry.core.config.ForestryBlock; +import forestry.core.worldgen.BlockType; + +public class WorldGenPapaya extends WorldGenTree { + + public WorldGenPapaya(ITreeGenData tree) { + super(tree); + } + + @Override + public void generate() { + generateTreeTrunk(height, girth); + + int yCenter = height - girth; + yCenter = yCenter > 3 ? yCenter : 4; + generateSphere(getCenteredAt(yCenter, 0), 2 + rand.nextInt(girth), leaf, EnumReplaceMode.NONE); + + } + + @Override + public BlockType getWood() { + return new BlockType(ForestryBlock.log5, 3); + } + + @Override + public void preGenerate() { + height = determineHeight(7, 2); + girth = determineGirth(tree.getGirth(world, startX, startY, startZ)); + } + +} diff --git a/forestry_common/arboriculture/forestry/arboriculture/worldgen/WorldGenPine.java b/forestry_common/arboriculture/forestry/arboriculture/worldgen/WorldGenPine.java new file mode 100755 index 000000000..78ff6864b --- /dev/null +++ b/forestry_common/arboriculture/forestry/arboriculture/worldgen/WorldGenPine.java @@ -0,0 +1,50 @@ +/******************************************************************************* + * Copyright 2011-2014 by SirSengir + * + * This work is licensed under a Creative Commons Attribution-NonCommercial-NoDerivs 3.0 Unported License. + * + * To view a copy of this license, visit http://creativecommons.org/licenses/by-nc-nd/3.0/. + ******************************************************************************/ +package forestry.arboriculture.worldgen; + +import forestry.api.world.ITreeGenData; +import forestry.core.config.ForestryBlock; +import forestry.core.worldgen.BlockType; + +public class WorldGenPine extends WorldGenTree { + + public WorldGenPine(ITreeGenData tree) { + super(tree); + } + + @Override + public void generate() { + generateTreeTrunk(height, girth); + + int leafSpawn = height + 1; + float diameterchange = (float) 1 / height; + int leafSpawned = 2; + + generateAdjustedCylinder(leafSpawn--, 0, 1, leaf); + generateAdjustedCylinder(leafSpawn--, 1, 1, leaf); + + while (leafSpawn > 1) { + generateAdjustedCylinder(leafSpawn--, 3 * diameterchange * leafSpawned, 1, leaf); + generateAdjustedCylinder(leafSpawn--, 2 * diameterchange * leafSpawned, 1, leaf); + leafSpawned += 2; + } + + } + + @Override + public void preGenerate() { + height = determineHeight(6, 4); + girth = determineGirth(tree.getGirth(world, startX, startY, startZ)); + } + + @Override + public BlockType getWood() { + return new BlockType(ForestryBlock.log6, 0); + } + +} diff --git a/forestry_common/arboriculture/forestry/arboriculture/worldgen/WorldGenPlum.java b/forestry_common/arboriculture/forestry/arboriculture/worldgen/WorldGenPlum.java new file mode 100755 index 000000000..68207c395 --- /dev/null +++ b/forestry_common/arboriculture/forestry/arboriculture/worldgen/WorldGenPlum.java @@ -0,0 +1,41 @@ +/******************************************************************************* + * Copyright 2011-2014 by SirSengir + * + * This work is licensed under a Creative Commons Attribution-NonCommercial-NoDerivs 3.0 Unported License. + * + * To view a copy of this license, visit http://creativecommons.org/licenses/by-nc-nd/3.0/. + ******************************************************************************/ +package forestry.arboriculture.worldgen; + +import forestry.api.world.ITreeGenData; +import forestry.core.config.ForestryBlock; +import forestry.core.worldgen.BlockType; + +public class WorldGenPlum extends WorldGenTree { + + public WorldGenPlum(ITreeGenData tree) { + super(tree); + } + + @Override + public void generate() { + generateTreeTrunk(height, girth); + + int yCenter = height - girth; + yCenter = yCenter > 2 ? yCenter : 3; + generateSphere(getCenteredAt(yCenter, 0), 2 + rand.nextInt(girth), leaf, EnumReplaceMode.NONE); + + } + + @Override + public BlockType getWood() { + return new BlockType(ForestryBlock.log6, 1); + } + + @Override + public void preGenerate() { + height = determineHeight(6, 3); + girth = determineGirth(tree.getGirth(world, startX, startY, startZ)); + } + +} diff --git a/forestry_common/arboriculture/forestry/arboriculture/worldgen/WorldGenPoplar.java b/forestry_common/arboriculture/forestry/arboriculture/worldgen/WorldGenPoplar.java new file mode 100755 index 000000000..dd7bd2cdb --- /dev/null +++ b/forestry_common/arboriculture/forestry/arboriculture/worldgen/WorldGenPoplar.java @@ -0,0 +1,42 @@ +/******************************************************************************* + * Copyright 2011-2014 by SirSengir + * + * This work is licensed under a Creative Commons Attribution-NonCommercial-NoDerivs 3.0 Unported License. + * + * To view a copy of this license, visit http://creativecommons.org/licenses/by-nc-nd/3.0/. + ******************************************************************************/ +package forestry.arboriculture.worldgen; + +import forestry.api.world.ITreeGenData; +import forestry.core.config.ForestryBlock; +import forestry.core.worldgen.BlockType; + +public class WorldGenPoplar extends WorldGenTree { + + public WorldGenPoplar(ITreeGenData tree) { + super(tree); + } + + @Override + public void generate() { + generateTreeTrunk(height, girth); + + int leafSpawn = height + 1; + + while (leafSpawn > girth - 1) + generateAdjustedCylinder(leafSpawn--, 0, 1, leaf); + + } + + @Override + public BlockType getWood() { + return new BlockType(ForestryBlock.log5, 1); + } + + @Override + public void preGenerate() { + height = determineHeight(8, 3); + girth = determineGirth(tree.getGirth(world, startX, startY, startZ)); + } + +} diff --git a/forestry_common/arboriculture/forestry/arboriculture/worldgen/WorldGenSequoia.java b/forestry_common/arboriculture/forestry/arboriculture/worldgen/WorldGenSequoia.java new file mode 100755 index 000000000..2e424389b --- /dev/null +++ b/forestry_common/arboriculture/forestry/arboriculture/worldgen/WorldGenSequoia.java @@ -0,0 +1,61 @@ +/******************************************************************************* + * Copyright 2011-2014 by SirSengir + * + * This work is licensed under a Creative Commons Attribution-NonCommercial-NoDerivs 3.0 Unported License. + * + * To view a copy of this license, visit http://creativecommons.org/licenses/by-nc-nd/3.0/. + ******************************************************************************/ +package forestry.arboriculture.worldgen; + +import forestry.api.world.ITreeGenData; +import forestry.core.config.ForestryBlock; +import forestry.core.worldgen.BlockType; + +public class WorldGenSequoia extends WorldGenTree { + + public WorldGenSequoia(ITreeGenData tree) { + super(tree); + } + + @Override + public void generate() { + generateTreeTrunk(height, girth); + + int topLength = height / 4; + + int topHeight = height - topLength + rand.nextInt(height / 4); + + int leafSpawn = height + 2; + + generateAdjustedCylinder(leafSpawn--, 0, 1, leaf); + generateAdjustedCylinder(leafSpawn--, 1, 1, leaf); + generateAdjustedCylinder(leafSpawn--, 1, 1, leaf); + + while (leafSpawn > topHeight) + generateAdjustedCylinder(leafSpawn--, 1, 1, leaf); + + generateAdjustedCylinder(leafSpawn--, 0, 1, leaf); + + for (int times = 0; times < height / 4; times++) { + int h = (height/3) + rand.nextInt(height - (height/3)); + if (rand.nextBoolean() && h < height / 3) + h = height / 2 + rand.nextInt(height / 3); + int x_off = -1 + rand.nextInt(3); + int y_off = -1 + rand.nextInt(3); + generateSphere(new Vector(x_off, h, y_off), 1 + rand.nextInt(2), leaf, EnumReplaceMode.NONE); + } + + } + + @Override + public void preGenerate() { + height = determineHeight(20, 5); + girth = determineGirth(tree.getGirth(world, startX, startY, startZ)); + } + + @Override + public BlockType getWood() { + return new BlockType(ForestryBlock.log2, 3); + } + +} diff --git a/forestry_common/arboriculture/forestry/arboriculture/worldgen/WorldGenSpruce.java b/forestry_common/arboriculture/forestry/arboriculture/worldgen/WorldGenSpruce.java new file mode 100755 index 000000000..4554f29a7 --- /dev/null +++ b/forestry_common/arboriculture/forestry/arboriculture/worldgen/WorldGenSpruce.java @@ -0,0 +1,48 @@ +/******************************************************************************* + * Copyright 2011-2014 by SirSengir + * + * This work is licensed under a Creative Commons Attribution-NonCommercial-NoDerivs 3.0 Unported License. + * + * To view a copy of this license, visit http://creativecommons.org/licenses/by-nc-nd/3.0/. + ******************************************************************************/ +package forestry.arboriculture.worldgen; + +import net.minecraft.init.Blocks; + +import forestry.api.world.ITreeGenData; +import forestry.core.worldgen.BlockType; + +public class WorldGenSpruce extends WorldGenTree { + + public WorldGenSpruce(ITreeGenData tree) { + super(tree); + } + + @Override + public void generate() { + generateTreeTrunk(height, girth); + + int leafSpawn = height + 1; + + generateAdjustedCylinder(leafSpawn--, 0, 1, leaf); + generateAdjustedCylinder(leafSpawn--, 1, 1, leaf); + + while (leafSpawn > 2) { + generateAdjustedCylinder(leafSpawn--, 2, 1, leaf); + generateAdjustedCylinder(leafSpawn--, 1, 1, leaf); + } + + } + + @Override + public void preGenerate() { + height = determineHeight(5, 3); + girth = determineGirth(tree.getGirth(world, startX, startY, startZ)); + } + + @Override + public BlockType getWood() { + return new BlockType(Blocks.log, 1); + } + +} diff --git a/forestry_common/arboriculture/forestry/arboriculture/worldgen/WorldGenTeak.java b/forestry_common/arboriculture/forestry/arboriculture/worldgen/WorldGenTeak.java new file mode 100755 index 000000000..23b410258 --- /dev/null +++ b/forestry_common/arboriculture/forestry/arboriculture/worldgen/WorldGenTeak.java @@ -0,0 +1,49 @@ +/******************************************************************************* + * Copyright 2011-2014 by SirSengir + * + * This work is licensed under a Creative Commons Attribution-NonCommercial-NoDerivs 3.0 Unported License. + * + * To view a copy of this license, visit http://creativecommons.org/licenses/by-nc-nd/3.0/. + ******************************************************************************/ +package forestry.arboriculture.worldgen; + +import forestry.api.world.ITreeGenData; +import forestry.core.config.ForestryBlock; +import forestry.core.worldgen.BlockType; + +public class WorldGenTeak extends WorldGenTree { + + public WorldGenTeak(ITreeGenData tree) { + super(tree); + } + + @Override + public void generate() { + generateTreeTrunk(height, girth); + + int leafSpawn = height + 1; + + generateAdjustedCylinder(leafSpawn--, 0, 1, leaf); + generateAdjustedCylinder(leafSpawn--, 0.5f, 1, leaf); + + generateAdjustedCylinder(leafSpawn--, 1.9f, 1, leaf); + generateAdjustedCylinder(leafSpawn--, 1.9f, 1, leaf); + if (rand.nextBoolean()) + generateAdjustedCylinder(leafSpawn--, 1.9f, 1, leaf); + + generateAdjustedCylinder(leafSpawn--, 0.5f, 1, leaf); + + } + + @Override + public void preGenerate() { + height = determineHeight(6, 3); + girth = determineGirth(tree.getGirth(world, startX, startY, startZ)); + } + + @Override + public BlockType getWood() { + return new BlockType(ForestryBlock.log1, 1); + } + +} diff --git a/forestry_common/arboriculture/forestry/arboriculture/worldgen/WorldGenTree.java b/forestry_common/arboriculture/forestry/arboriculture/worldgen/WorldGenTree.java new file mode 100755 index 000000000..54b948fce --- /dev/null +++ b/forestry_common/arboriculture/forestry/arboriculture/worldgen/WorldGenTree.java @@ -0,0 +1,93 @@ +/******************************************************************************* + * Copyright 2011-2014 by SirSengir + * + * This work is licensed under a Creative Commons Attribution-NonCommercial-NoDerivs 3.0 Unported License. + * + * To view a copy of this license, visit http://creativecommons.org/licenses/by-nc-nd/3.0/. + ******************************************************************************/ +package forestry.arboriculture.worldgen; + +import forestry.api.world.ITreeGenData; +import forestry.core.worldgen.BlockType; +import forestry.plugins.PluginArboriculture; + +public abstract class WorldGenTree extends WorldGenArboriculture { + + protected int girth; + protected int height; + + protected int minHeight = 4; + protected int maxHeight = 80; + + public WorldGenTree(ITreeGenData tree) { + super(tree); + } + + @Override + public void generate() { + generateTreeTrunk(height, girth); + + int leafSpawn = height + 1; + + generateAdjustedCylinder(leafSpawn--, 0, 1, leaf, EnumReplaceMode.NONE); + generateAdjustedCylinder(leafSpawn--, 0.5f, 1, leaf, EnumReplaceMode.NONE); + + generateAdjustedCylinder(leafSpawn--, 1.9f, 1, leaf, EnumReplaceMode.NONE); + generateAdjustedCylinder(leafSpawn--, 1.9f, 1, leaf, EnumReplaceMode.NONE); + + } + + protected Vector getCenteredAt(int yCenter, int offset) { + float cent = girth % 2 == 0 ? 0.5f : 0f; + return new Vector(cent + offset, yCenter, cent + offset); + } + + protected void generateAdjustedCylinder(int yCenter, float radius, int height, BlockType block) { + generateAdjustedCylinder(yCenter, 0, radius, height, block, EnumReplaceMode.NONE); + } + + protected void generateAdjustedCylinder(int yCenter, float radius, int height, BlockType block, EnumReplaceMode replace) { + generateAdjustedCylinder(yCenter, 0, radius, height, block, replace); + } + + protected void generateAdjustedCylinder(int yCenter, int offset, float radius, int height, BlockType block, EnumReplaceMode replace) { + generateCylinder(getCenteredAt(yCenter, offset), radius + girth, height, block, replace); + } + + @Override + public boolean canGrow() { + return tree.canGrow(world, startX, startY, startZ, tree.getGirth(world, startX, startY, startZ), height); + + } + + @Override + public void preGenerate() { + height = determineHeight(5, 2); + girth = determineGirth(tree.getGirth(world, startX, startY, startZ)); + } + + protected int determineGirth(int base) { + return base; + } + + protected int modifyByHeight(int val, int min, int max) { + int determined = Math.round(val * tree.getHeightModifier() * PluginArboriculture.treeInterface.getTreekeepingMode(world).getHeightModifier(null, 1f)); + return determined < min ? min : determined > max ? max : determined; + } + + // TODO: Get access to the tree genome for the treekeeping mode + protected int determineHeight(int required, int variation) { + int determined = Math.round((required + rand.nextInt(variation)) * tree.getHeightModifier() + * PluginArboriculture.treeInterface.getTreekeepingMode(world).getHeightModifier(null, 1f)); + return determined < minHeight ? minHeight : determined > maxHeight ? maxHeight : determined; + } + + @Override + public BlockType getLeaf(String owner) { + return new BlockTypeLeaf(owner); + } + + @Override + public abstract BlockType getWood(); + +} diff --git a/forestry_common/arboriculture/forestry/arboriculture/worldgen/WorldGenWalnut.java b/forestry_common/arboriculture/forestry/arboriculture/worldgen/WorldGenWalnut.java new file mode 100755 index 000000000..0a2e5676b --- /dev/null +++ b/forestry_common/arboriculture/forestry/arboriculture/worldgen/WorldGenWalnut.java @@ -0,0 +1,52 @@ +/******************************************************************************* + * Copyright 2011-2014 by SirSengir + * + * This work is licensed under a Creative Commons Attribution-NonCommercial-NoDerivs 3.0 Unported License. + * + * To view a copy of this license, visit http://creativecommons.org/licenses/by-nc-nd/3.0/. + ******************************************************************************/ +package forestry.arboriculture.worldgen; + +import forestry.api.world.ITreeGenData; +import forestry.core.config.ForestryBlock; +import forestry.core.worldgen.BlockType; + +public class WorldGenWalnut extends WorldGenTree { + + public WorldGenWalnut(ITreeGenData tree) { + super(tree); + + minHeight = 7; + } + + @Override + public void generate() { + generateTreeTrunk(height, girth); + + int leafSpawn = height + 1; + + generateAdjustedCylinder(leafSpawn--, 0, 1, leaf); + generateAdjustedCylinder(leafSpawn--, 0.5f, 1, leaf); + + generateAdjustedCylinder(leafSpawn--, 1.5f, 1, leaf); + generateAdjustedCylinder(leafSpawn--, 2f, 1, leaf); + + while (leafSpawn > 3) + generateAdjustedCylinder(leafSpawn--, 3f, 1, leaf); + if (rand.nextBoolean()) + generateAdjustedCylinder(leafSpawn--, 2f, 1, leaf); + + } + + @Override + public void preGenerate() { + height = determineHeight(7, 3); + girth = determineGirth(tree.getGirth(world, startX, startY, startZ)); + } + + @Override + public BlockType getWood() { + return new BlockType(ForestryBlock.log4, 1); + } + +} diff --git a/forestry_common/arboriculture/forestry/arboriculture/worldgen/WorldGenWenge.java b/forestry_common/arboriculture/forestry/arboriculture/worldgen/WorldGenWenge.java new file mode 100755 index 000000000..4f7acaaaa --- /dev/null +++ b/forestry_common/arboriculture/forestry/arboriculture/worldgen/WorldGenWenge.java @@ -0,0 +1,49 @@ +/******************************************************************************* + * Copyright 2011-2014 by SirSengir + * + * This work is licensed under a Creative Commons Attribution-NonCommercial-NoDerivs 3.0 Unported License. + * + * To view a copy of this license, visit http://creativecommons.org/licenses/by-nc-nd/3.0/. + ******************************************************************************/ +package forestry.arboriculture.worldgen; + +import forestry.api.world.ITreeGenData; +import forestry.core.config.ForestryBlock; +import forestry.core.worldgen.BlockType; + +public class WorldGenWenge extends WorldGenTree { + + public WorldGenWenge(ITreeGenData tree) { + super(tree); + minHeight = 6; + } + + @Override + public void generate() { + generateTreeTrunk(height, girth); + + int leafSpawn = height + 1; + + generateAdjustedCylinder(leafSpawn--, 0, 1, leaf); + generateAdjustedCylinder(leafSpawn--, 0.5f, 1, leaf); + + generateAdjustedCylinder(leafSpawn--, 1.5f, 1, leaf); + generateAdjustedCylinder(leafSpawn--, 2f, 1, leaf); + + while (leafSpawn > 1) + generateAdjustedCylinder(leafSpawn--, 3f, 1, leaf); + + } + + @Override + public void preGenerate() { + height = determineHeight(6, 2); + girth = determineGirth(tree.getGirth(world, startX, startY, startZ)); + } + + @Override + public BlockType getWood() { + return new BlockType(ForestryBlock.log2, 1); + } + +} diff --git a/forestry_common/arboriculture/forestry/arboriculture/worldgen/WorldGenWillow.java b/forestry_common/arboriculture/forestry/arboriculture/worldgen/WorldGenWillow.java new file mode 100755 index 000000000..9ece73043 --- /dev/null +++ b/forestry_common/arboriculture/forestry/arboriculture/worldgen/WorldGenWillow.java @@ -0,0 +1,53 @@ +/******************************************************************************* + * Copyright 2011-2014 by SirSengir + * + * This work is licensed under a Creative Commons Attribution-NonCommercial-NoDerivs 3.0 Unported License. + * + * To view a copy of this license, visit http://creativecommons.org/licenses/by-nc-nd/3.0/. + ******************************************************************************/ +package forestry.arboriculture.worldgen; + +import forestry.api.world.ITreeGenData; +import forestry.core.config.ForestryBlock; +import forestry.core.worldgen.BlockType; + +public class WorldGenWillow extends WorldGenTree { + + public WorldGenWillow(ITreeGenData tree) { + super(tree); + } + + @Override + public void generate() { + + generateTreeTrunk(height, girth, 0.8f); + generateSupportStems(height, girth, 0.2f, 0.2f); + + int leafSpawn = height + 1; + + generateAdjustedCylinder(leafSpawn--, 0, 1, leaf); + generateAdjustedCylinder(leafSpawn--, 1.5f, 1, leaf); + + generateAdjustedCylinder(leafSpawn--, 2.5f, 1, leaf); + generateAdjustedCylinder(leafSpawn--, 3f, 1, leaf); + generateAdjustedCylinder(leafSpawn--, 3f, 1, leaf); + while (leafSpawn > 2) + generateCircle(new Vector(0f, leafSpawn--, 0f), 4f, 2, 1, leaf, EnumReplaceMode.NONE); + generateCircle(new Vector(0f, leafSpawn--, 0f), 4f, 1, 1, leaf, EnumReplaceMode.NONE); + generateCircle(new Vector(0f, leafSpawn--, 0f), 4f, 1, 1, leaf, EnumReplaceMode.NONE); + generateCircle(new Vector(0f, leafSpawn--, 0f), 4f, 1, 1, leaf, 0.4f, EnumReplaceMode.NONE); + + } + + @Override + public void preGenerate() { + height = determineHeight(5, 2); + girth = determineGirth(tree.getGirth(world, startX, startY, startZ)); + } + + @Override + public BlockType getWood() { + return new BlockType(ForestryBlock.log4, 0); + } + +} diff --git a/forestry_common/arboriculture/forestry/plugins/PluginArboriculture.java b/forestry_common/arboriculture/forestry/plugins/PluginArboriculture.java new file mode 100755 index 000000000..48cf4b833 --- /dev/null +++ b/forestry_common/arboriculture/forestry/plugins/PluginArboriculture.java @@ -0,0 +1,1130 @@ +/******************************************************************************* + * Copyright 2011-2014 by SirSengir + * + * This work is licensed under a Creative Commons Attribution-NonCommercial-NoDerivs 3.0 Unported License. + * + * To view a copy of this license, visit http://creativecommons.org/licenses/by-nc-nd/3.0/. + ******************************************************************************/ +package forestry.plugins; + +import java.util.ArrayList; +import java.util.List; + +import net.minecraft.block.Block; +import net.minecraft.block.material.Material; +import net.minecraft.command.ICommand; +import net.minecraft.init.Blocks; +import net.minecraft.init.Items; +import net.minecraft.item.ItemStack; +import net.minecraft.item.crafting.FurnaceRecipes; +import net.minecraft.nbt.NBTTagCompound; +import net.minecraft.util.WeightedRandomChestContent; + +import cpw.mods.fml.common.IFuelHandler; +import cpw.mods.fml.common.SidedProxy; +import cpw.mods.fml.common.event.FMLInterModComms; +import cpw.mods.fml.common.event.FMLInterModComms.IMCMessage; +import cpw.mods.fml.common.network.IGuiHandler; +import cpw.mods.fml.common.registry.GameData; +import cpw.mods.fml.common.registry.GameRegistry; +import cpw.mods.fml.common.registry.VillagerRegistry; + +import net.minecraftforge.common.ChestGenHooks; +import net.minecraftforge.common.MinecraftForge; +import net.minecraftforge.oredict.OreDictionary; + +import forestry.api.arboriculture.EnumGermlingType; +import forestry.api.arboriculture.ITree; +import forestry.api.arboriculture.ITreeRoot; +import forestry.api.arboriculture.TreeManager; +import forestry.api.core.PluginInfo; +import forestry.api.core.Tabs; +import forestry.api.genetics.AlleleManager; +import forestry.api.genetics.IAllele; +import forestry.api.genetics.IClassification; +import forestry.api.genetics.IClassification.EnumClassLevel; +import forestry.api.genetics.IFruitFamily; +import forestry.api.recipes.RecipeManagers; +import forestry.api.storage.BackpackManager; +import forestry.arboriculture.CommandSpawnForest; +import forestry.arboriculture.CommandSpawnTree; +import forestry.arboriculture.CommandTreekeepingMode; +import forestry.arboriculture.EventHandlerArboriculture; +import forestry.arboriculture.FruitProviderNone; +import forestry.arboriculture.FruitProviderPod; +import forestry.arboriculture.FruitProviderPod.EnumPodType; +import forestry.arboriculture.FruitProviderRandom; +import forestry.arboriculture.FruitProviderRipening; +import forestry.arboriculture.GuiHandlerArboriculture; +import forestry.arboriculture.PacketHandlerArboriculture; +import forestry.arboriculture.VillageHandlerArboriculture; +import forestry.arboriculture.WoodType; +import forestry.arboriculture.gadgets.BlockArbFence; +import forestry.arboriculture.gadgets.BlockArbFence.FenceCat; +import forestry.arboriculture.gadgets.BlockArbStairs; +import forestry.arboriculture.gadgets.BlockFruitPod; +import forestry.arboriculture.gadgets.BlockLeaves; +import forestry.arboriculture.gadgets.BlockLog; +import forestry.arboriculture.gadgets.BlockLog.LogCat; +import forestry.arboriculture.gadgets.BlockPlanks; +import forestry.arboriculture.gadgets.BlockPlanks.PlankCat; +import forestry.arboriculture.gadgets.BlockSapling; +import forestry.arboriculture.gadgets.BlockSlab; +import forestry.arboriculture.gadgets.BlockSlab.SlabCat; +import forestry.arboriculture.gadgets.TileArboristChest; +import forestry.arboriculture.gadgets.TileFruitPod; +import forestry.arboriculture.gadgets.TileLeaves; +import forestry.arboriculture.gadgets.TileSapling; +import forestry.arboriculture.gadgets.TileStairs; +import forestry.arboriculture.genetics.AlleleFruit; +import forestry.arboriculture.genetics.AlleleGrowth; +import forestry.arboriculture.genetics.AlleleLeafEffectNone; +import forestry.arboriculture.genetics.AlleleTreeSpecies; +import forestry.arboriculture.genetics.BranchTrees; +import forestry.arboriculture.genetics.GrowthProvider; +import forestry.arboriculture.genetics.GrowthProviderTropical; +import forestry.arboriculture.genetics.Tree; +import forestry.arboriculture.genetics.TreeHelper; +import forestry.arboriculture.genetics.TreeMutation; +import forestry.arboriculture.genetics.TreeTemplates; +import forestry.arboriculture.genetics.TreekeepingMode; +import forestry.arboriculture.items.ItemGermlingGE; +import forestry.arboriculture.items.ItemGrafter; +import forestry.arboriculture.items.ItemStairs; +import forestry.arboriculture.items.ItemTreealyzer; +import forestry.arboriculture.items.ItemWoodBlock; +import forestry.arboriculture.proxy.ProxyArboriculture; +import forestry.arboriculture.worldgen.WorldGenAcacia; +import forestry.arboriculture.worldgen.WorldGenBalsa; +import forestry.arboriculture.worldgen.WorldGenBaobab; +import forestry.arboriculture.worldgen.WorldGenBirch; +import forestry.arboriculture.worldgen.WorldGenCherry; +import forestry.arboriculture.worldgen.WorldGenChestnut; +import forestry.arboriculture.worldgen.WorldGenDate; +import forestry.arboriculture.worldgen.WorldGenEbony; +import forestry.arboriculture.worldgen.WorldGenGiganteum; +import forestry.arboriculture.worldgen.WorldGenGreenheart; +import forestry.arboriculture.worldgen.WorldGenJungle; +import forestry.arboriculture.worldgen.WorldGenKapok; +import forestry.arboriculture.worldgen.WorldGenLarch; +import forestry.arboriculture.worldgen.WorldGenLemon; +import forestry.arboriculture.worldgen.WorldGenLime; +import forestry.arboriculture.worldgen.WorldGenMahoe; +import forestry.arboriculture.worldgen.WorldGenMahogany; +import forestry.arboriculture.worldgen.WorldGenMaple; +import forestry.arboriculture.worldgen.WorldGenOak; +import forestry.arboriculture.worldgen.WorldGenPapaya; +import forestry.arboriculture.worldgen.WorldGenPine; +import forestry.arboriculture.worldgen.WorldGenPlum; +import forestry.arboriculture.worldgen.WorldGenPoplar; +import forestry.arboriculture.worldgen.WorldGenSequoia; +import forestry.arboriculture.worldgen.WorldGenSpruce; +import forestry.arboriculture.worldgen.WorldGenTeak; +import forestry.arboriculture.worldgen.WorldGenWalnut; +import forestry.arboriculture.worldgen.WorldGenWenge; +import forestry.arboriculture.worldgen.WorldGenWillow; +import forestry.core.GameMode; +import forestry.core.config.Config; +import forestry.core.config.Defaults; +import forestry.core.config.ForestryBlock; +import forestry.core.config.ForestryItem; +import forestry.core.gadgets.BlockBase; +import forestry.core.gadgets.MachineDefinition; +import forestry.core.genetics.Allele; +import forestry.core.genetics.FruitFamily; +import forestry.core.interfaces.IOreDictionaryHandler; +import forestry.core.interfaces.IPacketHandler; +import forestry.core.interfaces.ISaveEventHandler; +import forestry.core.items.ItemForestryBlock; +import forestry.core.items.ItemFruit.EnumFruit; +import forestry.core.proxy.Proxies; +import forestry.core.utils.LiquidHelper; +import forestry.core.utils.RecipeUtil; +import forestry.core.utils.ShapedRecipeCustom; + +@PluginInfo(pluginID = "Arboriculture", name = "Arboriculture", author = "Binnie & SirSengir", url = Defaults.URL, description = "Adds additional tree species and products.") +public class PluginArboriculture extends NativePlugin implements IFuelHandler { + + @SidedProxy(clientSide = "forestry.arboriculture.proxy.ClientProxyArboriculture", serverSide = "forestry.arboriculture.proxy.ProxyArboriculture") + public static ProxyArboriculture proxy; + public static String treekeepingMode = "NORMAL"; + public static int modelIdSaplings; + public static int modelIdLeaves; + public static int modelIdFences; + public static int modelIdPods; + public static ITreeRoot treeInterface; + public static MachineDefinition definitionChest; + public static List validFences = new ArrayList(); + + @Override + public boolean isAvailable() { + return !Config.disableArboriculture; + } + + @Override + public void preInit() { + super.preInit(); + + ForestryBlock.log1 = new BlockLog(LogCat.CAT0).setBlockName("for.log1"); + Proxies.common.registerBlock(ForestryBlock.log1, ItemWoodBlock.class); + ForestryBlock.log1.setHarvestLevel("axe", 0); + + // Send to BC for facades + for (int i = 0; i < 4; i++) { + FMLInterModComms.sendMessage("BuildCraft|Transport", "add-facade", + GameData.blockRegistry.getNameForObject(ForestryBlock.log1) + "@" + i); + } + + ForestryBlock.log2 = new BlockLog(LogCat.CAT1).setBlockName("for.log2"); + Proxies.common.registerBlock(ForestryBlock.log2, ItemWoodBlock.class); + ForestryBlock.log2.setHarvestLevel("axe", 0); + + for (int i = 0; i < 4; i++) { + FMLInterModComms.sendMessage("BuildCraft|Transport", "add-facade", + GameData.blockRegistry.getNameForObject(ForestryBlock.log2) + "@" + i); + } + + ForestryBlock.log3 = new BlockLog(LogCat.CAT2).setBlockName("for.log3"); + Proxies.common.registerBlock(ForestryBlock.log3, ItemWoodBlock.class); + ForestryBlock.log3.setHarvestLevel("axe", 0); + + for (int i = 0; i < 4; i++) { + FMLInterModComms.sendMessage("BuildCraft|Transport", "add-facade", + GameData.blockRegistry.getNameForObject(ForestryBlock.log3) + "@" + i); + } + + ForestryBlock.log4 = new BlockLog(LogCat.CAT3).setBlockName("for.log4"); + Proxies.common.registerBlock(ForestryBlock.log4, ItemWoodBlock.class); + ForestryBlock.log4.setHarvestLevel("axe", 0); + + for (int i = 0; i < 4; i++) { + FMLInterModComms.sendMessage("BuildCraft|Transport", "add-facade", + GameData.blockRegistry.getNameForObject(ForestryBlock.log4) + "@" + i); + } + + ForestryBlock.log5 = new BlockLog(LogCat.CAT4).setBlockName("for.log5"); + Proxies.common.registerBlock(ForestryBlock.log5, ItemWoodBlock.class); + ForestryBlock.log5.setHarvestLevel("axe", 0); + + for (int i = 0; i < 4; i++) { + FMLInterModComms.sendMessage("BuildCraft|Transport", "add-facade", + GameData.blockRegistry.getNameForObject(ForestryBlock.log5) + "@" + i); + } + + ForestryBlock.log6 = new BlockLog(LogCat.CAT5).setBlockName("for.log6"); + Proxies.common.registerBlock(ForestryBlock.log6, ItemWoodBlock.class); + ForestryBlock.log6.setHarvestLevel("axe", 0); + + for (int i = 0; i < 4; i++) { + FMLInterModComms.sendMessage("BuildCraft|Transport", "add-facade", + GameData.blockRegistry.getNameForObject(ForestryBlock.log6) + "@" + i); + } + + ForestryBlock.log7 = new BlockLog(LogCat.CAT6).setBlockName("for.log7"); + Proxies.common.registerBlock(ForestryBlock.log7, ItemWoodBlock.class); + ForestryBlock.log7.setHarvestLevel("axe", 0); + + // Register as workableLogs + OreDictionary.registerOre("logWood", + new ItemStack(ForestryBlock.log1, 1, Defaults.WILDCARD)); + OreDictionary.registerOre("logWood", + new ItemStack(ForestryBlock.log2, 1, Defaults.WILDCARD)); + OreDictionary.registerOre("logWood", + new ItemStack(ForestryBlock.log3, 1, Defaults.WILDCARD)); + OreDictionary.registerOre("logWood", + new ItemStack(ForestryBlock.log4, 1, Defaults.WILDCARD)); + OreDictionary.registerOre("logWood", + new ItemStack(ForestryBlock.log5, 1, Defaults.WILDCARD)); + OreDictionary.registerOre("logWood", + new ItemStack(ForestryBlock.log6, 1, Defaults.WILDCARD)); + OreDictionary.registerOre("logWood", + new ItemStack(ForestryBlock.log7, 1, Defaults.WILDCARD)); + + // Register smelting + FurnaceRecipes.smelting().func_151393_a(ForestryBlock.log1, + new ItemStack(Items.coal, 1, 1), 0.15F); + FurnaceRecipes.smelting().func_151393_a(ForestryBlock.log2, + new ItemStack(Items.coal, 1, 1), 0.15F); + FurnaceRecipes.smelting().func_151393_a(ForestryBlock.log3, + new ItemStack(Items.coal, 1, 1), 0.15F); + FurnaceRecipes.smelting().func_151393_a(ForestryBlock.log4, + new ItemStack(Items.coal, 1, 1), 0.15F); + FurnaceRecipes.smelting().func_151393_a(ForestryBlock.log5, + new ItemStack(Items.coal, 1, 1), 0.15F); + FurnaceRecipes.smelting().func_151393_a(ForestryBlock.log6, + new ItemStack(Items.coal, 1, 1), 0.15F); + + ForestryBlock.planks1 = new BlockPlanks(PlankCat.CAT0).setBlockName("for.planks"); + Proxies.common.registerBlock(ForestryBlock.planks1, ItemWoodBlock.class); + ForestryBlock.planks1.setHarvestLevel("axe", 0); + + ForestryBlock.planks2 = new BlockPlanks(PlankCat.CAT1).setBlockName("for.planks2"); + Proxies.common.registerBlock(ForestryBlock.planks2, ItemWoodBlock.class); + ForestryBlock.planks2.setHarvestLevel("axe", 0); + + // Register as craftablePlanks + OreDictionary.registerOre("plankWood", new ItemStack(ForestryBlock.planks1, 1, + Defaults.WILDCARD)); + OreDictionary.registerOre("plankWood", new ItemStack(ForestryBlock.planks2, 1, + Defaults.WILDCARD)); + + // Send to BC for facades + for (int i = 0; i < 16; i++) { + FMLInterModComms.sendMessage("BuildCraft|Transport", "add-facade", + GameData.blockRegistry.getNameForObject(ForestryBlock.planks1) + "@" + i); + } + + ForestryBlock.slabs1 = new BlockSlab(SlabCat.CAT0).setBlockName("for.slabs1"); + Proxies.common.registerBlock(ForestryBlock.slabs1, ItemWoodBlock.class); + ForestryBlock.slabs1.setHarvestLevel("axe", 0); + + ForestryBlock.slabs2 = new BlockSlab(SlabCat.CAT1).setBlockName("for.slabs2"); + Proxies.common.registerBlock(ForestryBlock.slabs2, ItemWoodBlock.class); + ForestryBlock.slabs2.setHarvestLevel("axe", 0); + + ForestryBlock.slabs3 = new BlockSlab(SlabCat.CAT2).setBlockName("for.slabs3"); + Proxies.common.registerBlock(ForestryBlock.slabs3, ItemWoodBlock.class); + ForestryBlock.slabs3.setHarvestLevel("axe", 0); + + OreDictionary.registerOre("slabWood", new ItemStack(ForestryBlock.slabs1, 1, + Defaults.WILDCARD)); + OreDictionary.registerOre("slabWood", new ItemStack(ForestryBlock.slabs2, 1, + Defaults.WILDCARD)); + OreDictionary.registerOre("slabWood", new ItemStack(ForestryBlock.slabs3, 1, + Defaults.WILDCARD)); + + // Fences + ForestryBlock.fences1 = new BlockArbFence(FenceCat.CAT0).setBlockName("for.fences"); + Proxies.common.registerBlock(ForestryBlock.fences1, ItemWoodBlock.class); + ForestryBlock.fences1.setHarvestLevel("axe", 0); + + ForestryBlock.fences2 = new BlockArbFence(FenceCat.CAT1).setBlockName("for.fences2"); + Proxies.common.registerBlock(ForestryBlock.fences2, ItemWoodBlock.class); + ForestryBlock.fences2.setHarvestLevel("axe", 0); + + // Stairs + ForestryBlock.stairs = new BlockArbStairs(ForestryBlock.planks1, 0) .setBlockName("for.stairs"); + Proxies.common.registerBlock(ForestryBlock.stairs, ItemStairs.class); + ForestryBlock.stairs.setHarvestLevel("axe", 0); + + // Saplings + ForestryBlock.saplingGE = new BlockSapling().setBlockName("saplingGE"); + Proxies.common.registerBlock(ForestryBlock.saplingGE, ItemForestryBlock.class); + + // Leaves + ForestryBlock.leaves = new BlockLeaves().setBlockName("leaves"); + Proxies.common.registerBlock(ForestryBlock.leaves, ItemForestryBlock.class); + + // Pods + ForestryBlock.pods = new BlockFruitPod().setBlockName("for.pods"); + Proxies.common.registerBlock(ForestryBlock.pods, ItemForestryBlock.class); + + // Machines + ForestryBlock.arboriculture = new BlockBase(Material.iron); + ForestryBlock.arboriculture.setBlockName("for.arboriculture").setCreativeTab(Tabs.tabArboriculture); + Proxies.common.registerBlock(ForestryBlock.arboriculture, ItemForestryBlock.class); + + definitionChest = ForestryBlock.arboriculture.addDefinition(new MachineDefinition(Defaults.DEFINITION_ARBCHEST_META, + "forestry.ArbChest", TileArboristChest.class, + ShapedRecipeCustom.createShapedRecipe(new ItemStack(ForestryBlock.arboriculture, + 1, Defaults.DEFINITION_ARBCHEST_META), new Object[] { " # ", "XYX", "XXX", '#', + Blocks.glass, 'X', "treeSapling", 'Y', Blocks.chest })).setFaces(0, 1, 2, 3, 4, 4, 0, 7)); + + + + // Init tree interface + AlleleManager.alleleRegistry + .registerSpeciesRoot(PluginArboriculture.treeInterface = TreeManager.treeInterface = new TreeHelper()); + + // Init rendering + proxy.initializeRendering(); + + // Create alleles + createAlleles(); + + // Register vanilla and forestry fence ids + validFences.add(ForestryBlock.fences1); + validFences.add(ForestryBlock.fences2); + validFences.add(Blocks.fence); + validFences.add(Blocks.fence_gate); + validFences.add(Blocks.nether_brick_fence); + + } + + @Override + public void doInit() { + super.doInit(); + + proxy.addLocalizations(); + + GameRegistry.registerTileEntity(TileSapling.class, "forestry.Sapling"); + GameRegistry.registerTileEntity(TileLeaves.class, "forestry.Leaves"); + GameRegistry.registerTileEntity(TileStairs.class, "forestry.Stairs"); + GameRegistry.registerTileEntity(TileFruitPod.class, "forestry.Pods"); + definitionChest.register(); + + createMutations(); + registerTemplates(); + registerErsatzGenomes(); + + PluginArboriculture.treeInterface.registerTreekeepingMode(TreekeepingMode.easy); + PluginArboriculture.treeInterface.registerTreekeepingMode(TreekeepingMode.normal); + PluginArboriculture.treeInterface.registerTreekeepingMode(TreekeepingMode.hard); + PluginArboriculture.treeInterface.registerTreekeepingMode(TreekeepingMode.hardcore); + PluginArboriculture.treeInterface.registerTreekeepingMode(TreekeepingMode.insane); + + MinecraftForge.EVENT_BUS.register(new EventHandlerArboriculture()); + + VillagerRegistry.instance().registerVillagerId(Defaults.ID_VILLAGER_LUMBERJACK); + Proxies.render.registerVillagerSkin(Defaults.ID_VILLAGER_LUMBERJACK, Defaults.TEXTURE_SKIN_LUMBERJACK); + VillagerRegistry.instance().registerVillageTradeHandler(Defaults.ID_VILLAGER_LUMBERJACK, + new VillageHandlerArboriculture()); + } + + @Override + public void postInit() { + super.postInit(); + registerDungeonLoot(); + + } + + @Override + protected void registerItems() { + + ForestryItem.sapling.registerItem(new ItemGermlingGE(EnumGermlingType.SAPLING), "sapling"); + OreDictionary.registerOre("treeSapling", ForestryItem.sapling.getItemStack(1, -1)); + + ForestryItem.pollenFertile.registerItem(new ItemGermlingGE(EnumGermlingType.POLLEN), "pollenFertile"); + + ForestryItem.treealyzer.registerItem(new ItemTreealyzer(), "treealyzer"); + ForestryItem.grafter.registerItem(new ItemGrafter(4), "grafter"); + ForestryItem.grafterProven.registerItem(new ItemGrafter(149), "grafterProven"); + + } + + @Override + protected void registerBackpackItems() { + if (BackpackManager.backpackItems == null) + return; + + BackpackManager.definitions.get("forester").addValidItem(new ItemStack(ForestryBlock.log1, 1, Defaults.WILDCARD)); + BackpackManager.definitions.get("forester").addValidItem(new ItemStack(ForestryBlock.log2, 1, Defaults.WILDCARD)); + BackpackManager.definitions.get("forester").addValidItem(new ItemStack(ForestryBlock.log3, 1, Defaults.WILDCARD)); + BackpackManager.definitions.get("forester").addValidItem(new ItemStack(ForestryBlock.log4, 1, Defaults.WILDCARD)); + BackpackManager.definitions.get("forester").addValidItem(new ItemStack(ForestryBlock.log5, 1, Defaults.WILDCARD)); + BackpackManager.definitions.get("forester").addValidItem(new ItemStack(ForestryBlock.log6, 1, Defaults.WILDCARD)); + BackpackManager.definitions.get("forester").addValidItem(new ItemStack(ForestryBlock.log7, 1, Defaults.WILDCARD)); + BackpackManager.definitions.get("forester").addValidItem(new ItemStack(ForestryItem.sapling.item(), 1, Defaults.WILDCARD)); + BackpackManager.definitions.get("forester").addValidItem(new ItemStack(ForestryItem.fruits.item(), 1, Defaults.WILDCARD)); + + BackpackManager.definitions.get("builder").addValidItem( + new ItemStack(ForestryBlock.stairs, 1, Defaults.WILDCARD)); + BackpackManager.definitions.get("builder").addValidItem( + new ItemStack(ForestryBlock.slabs1, 1, Defaults.WILDCARD)); + BackpackManager.definitions.get("builder").addValidItem( + new ItemStack(ForestryBlock.slabs2, 1, Defaults.WILDCARD)); + BackpackManager.definitions.get("builder").addValidItem( + new ItemStack(ForestryBlock.slabs3, 1, Defaults.WILDCARD)); + // BackpackManager.definitions.item("builder").addValidItem(new + // ItemStack(ForestryBlock.slabs4, 1, Defaults.WILDCARD)); + BackpackManager.definitions.get("builder").addValidItem( + new ItemStack(ForestryBlock.fences1, 1, Defaults.WILDCARD)); + BackpackManager.definitions.get("builder").addValidItem( + new ItemStack(ForestryBlock.fences2, 1, Defaults.WILDCARD)); + BackpackManager.definitions.get("builder").addValidItem( + new ItemStack(ForestryBlock.planks1, 1, Defaults.WILDCARD)); + BackpackManager.definitions.get("builder").addValidItem( + new ItemStack(ForestryBlock.planks2, 1, Defaults.WILDCARD)); + } + + @Override + protected void registerCrates() { + } + + @Override + protected void registerRecipes() { + + // / Plank recipes + for (int i = 0; i < 4; i++) { + Proxies.common.addShapelessRecipe(new ItemStack(ForestryBlock.planks1, 4, i), + new ItemStack(ForestryBlock.log1, 1, i)); + } + for (int i = 0; i < 4; i++) { + Proxies.common.addShapelessRecipe(new ItemStack(ForestryBlock.planks1, 4, 4 + i), + new ItemStack(ForestryBlock.log2, 1, i)); + } + for (int i = 0; i < 4; i++) { + Proxies.common.addShapelessRecipe(new ItemStack(ForestryBlock.planks1, 4, 8 + i), + new ItemStack(ForestryBlock.log3, 1, i)); + } + for (int i = 0; i < 4; i++) { + Proxies.common.addShapelessRecipe(new ItemStack(ForestryBlock.planks1, 4, 12 + i), + new ItemStack(ForestryBlock.log4, 1, i)); + } + for (int i = 0; i < 4; i++) { + Proxies.common.addShapelessRecipe(new ItemStack(ForestryBlock.planks2, 4, i), + new ItemStack(ForestryBlock.log5, 1, i)); + } + for (int i = 0; i < 4; i++) { + Proxies.common.addShapelessRecipe(new ItemStack(ForestryBlock.planks2, 4, 4 + i), + new ItemStack(ForestryBlock.log6, 1, i)); + } + + // Slab recipes + for (int i = 0; i < 8; i++) { + Proxies.common.addPriorityRecipe(new ItemStack(ForestryBlock.slabs1, 6, i), "###", '#', new ItemStack(ForestryBlock.planks1, 1, i)); + } + for (int i = 0; i < 8; i++) { + Proxies.common.addPriorityRecipe(new ItemStack(ForestryBlock.slabs2, 6, i), "###", '#', new ItemStack(ForestryBlock.planks1, 1, 8 + i)); + } + for (int i = 0; i < 8; i++) { + Proxies.common.addPriorityRecipe(new ItemStack(ForestryBlock.slabs3, 6, i), "###", '#', new ItemStack(ForestryBlock.planks2, 1, i)); + } + + // Fence recipes + for (int i = 0; i < 16; i++) { + Proxies.common.addRecipe(new ItemStack(ForestryBlock.fences1, 4, i), "###", "# #", '#', new ItemStack(ForestryBlock.planks1, 1, i)); + } + for (int i = 0; i < 8; i++) { + Proxies.common.addRecipe(new ItemStack(ForestryBlock.fences2, 4, i), "###", "# #", '#', new ItemStack(ForestryBlock.planks2, 1, i)); + } + + // Treealyzer + RecipeManagers.carpenterManager.addRecipe(100, LiquidHelper.getLiquid(Defaults.LIQUID_WATER, 2000), null, ForestryItem.treealyzer.getItemStack(), new Object[] { + "X#X", "X#X", "RDR", + '#', Blocks.glass_pane, + 'X', "ingotCopper", + 'R', Items.redstone, + 'D', Items.diamond }); + + // SQUEEZER RECIPES + RecipeManagers.squeezerManager.addRecipe(20, new ItemStack[] { ForestryItem.fruits.getItemStack(1, EnumFruit.CHERRY.ordinal()) }, LiquidHelper.getLiquid(Defaults.LIQUID_SEEDOIL, 5 * GameMode.getGameMode().getIntegerSetting("squeezer.liquid.seed")), ForestryItem.mulch.getItemStack(), 5); + RecipeManagers.squeezerManager.addRecipe(60, new ItemStack[] { ForestryItem.fruits.getItemStack(1, EnumFruit.WALNUT.ordinal()) }, LiquidHelper.getLiquid(Defaults.LIQUID_SEEDOIL, 18 * GameMode.getGameMode().getIntegerSetting("squeezer.liquid.seed")), ForestryItem.mulch.getItemStack(), 5); + RecipeManagers.squeezerManager.addRecipe(70, new ItemStack[] { ForestryItem.fruits.getItemStack(1, EnumFruit.CHESTNUT.ordinal()) }, LiquidHelper.getLiquid(Defaults.LIQUID_SEEDOIL, 22 * GameMode.getGameMode().getIntegerSetting("squeezer.liquid.seed")), ForestryItem.mulch.getItemStack(), 2); + RecipeManagers.squeezerManager.addRecipe(10, new ItemStack[] { ForestryItem.fruits.getItemStack(1, EnumFruit.LEMON.ordinal()) }, LiquidHelper.getLiquid(Defaults.LIQUID_JUICE, GameMode.getGameMode().getIntegerSetting("squeezer.liquid.apple") * 2), ForestryItem.mulch.getItemStack(), (int) Math.floor(GameMode.getGameMode().getIntegerSetting("squeezer.mulch.apple") * 0.5f)); + RecipeManagers.squeezerManager.addRecipe(10, new ItemStack[] { ForestryItem.fruits.getItemStack(1, EnumFruit.PLUM.ordinal()) }, LiquidHelper.getLiquid(Defaults.LIQUID_JUICE, (int) Math.floor(GameMode.getGameMode().getIntegerSetting("squeezer.liquid.apple") * 0.5f)), ForestryItem.mulch.getItemStack(), GameMode.getGameMode().getIntegerSetting("squeezer.mulch.apple") * 3); + RecipeManagers.squeezerManager.addRecipe(10, new ItemStack[] { ForestryItem.fruits.getItemStack(1, EnumFruit.PAPAYA.ordinal()) }, LiquidHelper.getLiquid(Defaults.LIQUID_JUICE, GameMode.getGameMode().getIntegerSetting("squeezer.liquid.apple") * 3), ForestryItem.mulch.getItemStack(), (int) Math.floor(GameMode.getGameMode().getIntegerSetting("squeezer.mulch.apple") * 0.5f)); + RecipeManagers.squeezerManager.addRecipe(10, new ItemStack[] { ForestryItem.fruits.getItemStack(1, EnumFruit.DATES.ordinal()) }, LiquidHelper.getLiquid(Defaults.LIQUID_JUICE, (int) Math.floor(GameMode.getGameMode().getIntegerSetting("squeezer.liquid.apple") * 0.25)), ForestryItem.mulch.getItemStack(), (int) Math.floor(GameMode.getGameMode().getIntegerSetting("squeezer.mulch.apple"))); + + RecipeUtil.injectLeveledRecipe(ForestryItem.sapling.getItemStack(), GameMode.getGameMode().getIntegerSetting("fermenter.yield.sapling"), Defaults.LIQUID_BIOMASS); + + // Stairs + for (int i = 0; i < 16; i++) { + WoodType type = WoodType.VALUES[i]; + NBTTagCompound compound = new NBTTagCompound(); + type.saveToCompound(compound); + + ItemStack stairs = new ItemStack(ForestryBlock.stairs, 4, 0); + stairs.setTagCompound(compound); + Proxies.common.addPriorityRecipe(stairs, new Object[] { "# ", "## ", "###", '#', + new ItemStack(ForestryBlock.planks1, 1, i) }); + } + for (int i = 0; i < 8; i++) { + WoodType type = WoodType.VALUES[16 + i]; + NBTTagCompound compound = new NBTTagCompound(); + type.saveToCompound(compound); + + ItemStack stairs = new ItemStack(ForestryBlock.stairs, 4, 0); + stairs.setTagCompound(compound); + Proxies.common.addPriorityRecipe(stairs, new Object[] { "# ", "## ", "###", '#', + new ItemStack(ForestryBlock.planks2, 1, i) }); + } + + // Grafter + Proxies.common.addRecipe(ForestryItem.grafter.getItemStack(), " B", " # ", "# ", 'B', "ingotBronze", '#', Items.stick); + } + + private void createAlleles() { + + // Divisions + IClassification angiosperms = AlleleManager.alleleRegistry.createAndRegisterClassification( + EnumClassLevel.DIVISION, "angiosperms", "Angiosperms"); + AlleleManager.alleleRegistry.getClassification("kingdom.plantae").addMemberGroup( + angiosperms); + IClassification pinophyta = AlleleManager.alleleRegistry.createAndRegisterClassification( + EnumClassLevel.DIVISION, "pinophyta", "Pinophyta"); + AlleleManager.alleleRegistry.getClassification("kingdom.plantae").addMemberGroup(pinophyta); + IClassification magnoliophyta = AlleleManager.alleleRegistry + .createAndRegisterClassification(EnumClassLevel.DIVISION, "magnoliophyta", + "Magnoliophyta"); + AlleleManager.alleleRegistry.getClassification("kingdom.plantae").addMemberGroup( + magnoliophyta); + + // Classes + IClassification rosids = AlleleManager.alleleRegistry.createAndRegisterClassification( + EnumClassLevel.CLASS, "rosids", "Rosids"); + angiosperms.addMemberGroup(rosids); + IClassification asterids = AlleleManager.alleleRegistry.createAndRegisterClassification( + EnumClassLevel.CLASS, "asterids", "Asterids"); + angiosperms.addMemberGroup(asterids); + IClassification pinopsida = AlleleManager.alleleRegistry.createAndRegisterClassification( + EnumClassLevel.CLASS, "pinopsida", "Pinopsida"); + pinophyta.addMemberGroup(pinopsida); + IClassification magnoliopsida = AlleleManager.alleleRegistry + .createAndRegisterClassification(EnumClassLevel.CLASS, "magnoliopsida", + "Magnoliopsida"); + pinophyta.addMemberGroup(magnoliopsida); + + // Orders + IClassification fabales = AlleleManager.alleleRegistry.createAndRegisterClassification( + EnumClassLevel.ORDER, "fabales", "Fabales"); + rosids.addMemberGroup(fabales); + IClassification rosales = AlleleManager.alleleRegistry.createAndRegisterClassification( + EnumClassLevel.ORDER, "rosales", "Rosales"); + rosids.addMemberGroup(rosales); + IClassification fagales = AlleleManager.alleleRegistry.createAndRegisterClassification( + EnumClassLevel.ORDER, "fagales", "Fagales"); + rosids.addMemberGroup(fagales); + IClassification malvales = AlleleManager.alleleRegistry.createAndRegisterClassification( + EnumClassLevel.ORDER, "malvales", "Malvales"); + rosids.addMemberGroup(malvales); + IClassification malpighiales = AlleleManager.alleleRegistry + .createAndRegisterClassification(EnumClassLevel.ORDER, "malpighiales", + "Malpighiales"); + rosids.addMemberGroup(malpighiales); + + IClassification ericales = AlleleManager.alleleRegistry.createAndRegisterClassification( + EnumClassLevel.ORDER, "ericales", "Ericales"); + asterids.addMemberGroup(ericales); + IClassification lamiales = AlleleManager.alleleRegistry.createAndRegisterClassification( + EnumClassLevel.ORDER, "lamiales", "Lamiales"); + asterids.addMemberGroup(lamiales); + + IClassification pinales = AlleleManager.alleleRegistry.createAndRegisterClassification( + EnumClassLevel.ORDER, "pinales", "Pinales"); + pinopsida.addMemberGroup(pinales); + + IClassification laurales = AlleleManager.alleleRegistry.createAndRegisterClassification( + EnumClassLevel.ORDER, "laurales", "Laurales"); + rosids.addMemberGroup(laurales); + IClassification sapindales = AlleleManager.alleleRegistry.createAndRegisterClassification( + EnumClassLevel.ORDER, "sapindales", "Sapindales"); + rosids.addMemberGroup(sapindales); + IClassification brassicales = AlleleManager.alleleRegistry.createAndRegisterClassification( + EnumClassLevel.ORDER, "brassicales", "Brassicales"); + rosids.addMemberGroup(brassicales); + + // Families + IClassification betulaceae = AlleleManager.alleleRegistry.createAndRegisterClassification( + EnumClassLevel.FAMILY, "betulaceae", "Betulaceae"); + fagales.addMemberGroup(betulaceae); + IClassification fagaceae = AlleleManager.alleleRegistry.createAndRegisterClassification( + EnumClassLevel.FAMILY, "fagaceae", "Fagaceae"); + fagales.addMemberGroup(fagaceae); + IClassification juglandaceae = AlleleManager.alleleRegistry + .createAndRegisterClassification(EnumClassLevel.FAMILY, "juglandaceae", + "Juglandaceae"); + fagales.addMemberGroup(juglandaceae); + + IClassification malvaceae = AlleleManager.alleleRegistry.createAndRegisterClassification( + EnumClassLevel.FAMILY, "malvaceae", "Malvaceae"); + malvales.addMemberGroup(malvaceae); + IClassification dipterocarpaceae = AlleleManager.alleleRegistry + .createAndRegisterClassification(EnumClassLevel.FAMILY, "dipterocarpaceae", + "Dipterocarpaceae"); + malvales.addMemberGroup(dipterocarpaceae); + + IClassification pinaceae = AlleleManager.alleleRegistry.createAndRegisterClassification( + EnumClassLevel.FAMILY, "pinaceae", "Pinaceae"); + pinales.addMemberGroup(pinaceae); + IClassification cupressaceae = AlleleManager.alleleRegistry + .createAndRegisterClassification(EnumClassLevel.FAMILY, "cupressaceae", + "Cupressaceae"); + pinales.addMemberGroup(cupressaceae); + + IClassification lamiaceae = AlleleManager.alleleRegistry.createAndRegisterClassification( + EnumClassLevel.FAMILY, "lamiaceae", "Lamiaceae"); + lamiales.addMemberGroup(lamiaceae); + + IClassification ebenaceae = AlleleManager.alleleRegistry.createAndRegisterClassification( + EnumClassLevel.FAMILY, "ebenaceae", "Ebenaceae"); + ericales.addMemberGroup(ebenaceae); + + IClassification fabaceae = AlleleManager.alleleRegistry.createAndRegisterClassification( + EnumClassLevel.FAMILY, "fabaceae", "Fabaceae"); + ericales.addMemberGroup(fabaceae); + + IClassification rosaceae = AlleleManager.alleleRegistry.createAndRegisterClassification( + EnumClassLevel.FAMILY, "rosaceae", "Rosaceae"); + rosales.addMemberGroup(rosaceae); + + IClassification salicaceae = AlleleManager.alleleRegistry.createAndRegisterClassification( + EnumClassLevel.FAMILY, "salicaceae", "Salicaceae"); + malpighiales.addMemberGroup(salicaceae); + + IClassification lauraceae = AlleleManager.alleleRegistry.createAndRegisterClassification( + EnumClassLevel.FAMILY, "lauraceae", "Lauraceae"); + malpighiales.addMemberGroup(lauraceae); + + IClassification rutaceae = AlleleManager.alleleRegistry.createAndRegisterClassification( + EnumClassLevel.FAMILY, "rutaceae", "Rutaceae"); + sapindales.addMemberGroup(rutaceae); + IClassification sapindaceae = AlleleManager.alleleRegistry.createAndRegisterClassification( + EnumClassLevel.FAMILY, "sapindaceae", "Sapindaceae"); + sapindales.addMemberGroup(sapindaceae); + + IClassification caricaceae = AlleleManager.alleleRegistry.createAndRegisterClassification( + EnumClassLevel.FAMILY, "caricaceae", "Caricaceae"); + brassicales.addMemberGroup(caricaceae); + + // Genii + IClassification quercus = new BranchTrees("quercus", "Quercus"); + fagaceae.addMemberGroup(quercus); + IClassification castanea = new BranchTrees("castanea", "Castanea"); + fagaceae.addMemberGroup(castanea); + + IClassification betula = new BranchTrees("betula", "Betula"); + betulaceae.addMemberGroup(betula); + + IClassification tilia = new BranchTrees("tilia", "Tilia"); + malvaceae.addMemberGroup(tilia); + IClassification ceiba = new BranchTrees("ceiba", "Ceiba"); + malvaceae.addMemberGroup(ceiba); + IClassification adansonia = new BranchTrees("adansonia", "Adansonia"); + malvaceae.addMemberGroup(adansonia); + + IClassification picea = new BranchTrees("picea", "Picea"); + pinaceae.addMemberGroup(picea); + IClassification pinus = new BranchTrees("pinus", "Pinus"); + pinaceae.addMemberGroup(pinus); + IClassification larix = new BranchTrees("larix", "Larix"); + pinaceae.addMemberGroup(larix); + + IClassification juglans = new BranchTrees("juglans", "Juglans"); + juglandaceae.addMemberGroup(juglans); + + IClassification sequoia = new BranchTrees("sequoia", "Sequoia"); + cupressaceae.addMemberGroup(sequoia); + IClassification sequoiadendron = new BranchTrees("sequoiadendron", "Sequoiadendron"); + cupressaceae.addMemberGroup(sequoiadendron); + + IClassification tectona = new BranchTrees("tectona", "Tectona"); + lamiaceae.addMemberGroup(tectona); + + IClassification diospyros = new BranchTrees("ebony", "Diospyros"); + ebenaceae.addMemberGroup(diospyros); + + IClassification shorea = new BranchTrees("mahogany", "Shorea"); + dipterocarpaceae.addMemberGroup(shorea); + + IClassification acacia = new BranchTrees("acacia", "Acacia"); + fabaceae.addMemberGroup(acacia); + IClassification millettia = new BranchTrees("millettia", "Millettia"); + fabaceae.addMemberGroup(millettia); + + IClassification ochroma = new BranchTrees("ochroma", "Ochroma"); + malvaceae.addMemberGroup(ochroma); + + IClassification prunus = new BranchTrees("prunus", "Prunus"); + rosaceae.addMemberGroup(prunus); + + IClassification salix = new BranchTrees("salix", "Salix"); + salicaceae.addMemberGroup(salix); + + IClassification chlorocardium = new BranchTrees("chlorocardium", "Chlorocardium"); + salicaceae.addMemberGroup(chlorocardium); + + IClassification talipariti = new BranchTrees("talipariti", "Talipariti"); + malvaceae.addMemberGroup(talipariti); + + IClassification populus = new BranchTrees("populus", "Populus"); + salicaceae.addMemberGroup(populus); + + IClassification citrus = new BranchTrees("citrus", "Citrus"); + rutaceae.addMemberGroup(citrus); + IClassification acer = new BranchTrees("acer", "Acer"); + sapindaceae.addMemberGroup(acer); + + IClassification tropical = new BranchTrees("Tropical", ""); + + IClassification carica = new BranchTrees("carica", "Carica"); + + IFruitFamily prunes = new FruitFamily("prunes", "Prunus domestica"); + IFruitFamily pomes = new FruitFamily("pomes", "Pomum"); + IFruitFamily jungle = new FruitFamily("jungle", "Tropicus"); + IFruitFamily nux = new FruitFamily("nuts", "Nux"); + + // Deciduous + Allele.treeOak = new AlleleTreeSpecies("treeOak", false, "Apple Oak", quercus, "robur", + proxy.getFoliageColorBasic(), WorldGenOak.class, new ItemStack(Blocks.log, 1, 0)).addFruitFamily(pomes) + .setVanillaMap(0).setIsSecret(); + Allele.treeBirch = new AlleleTreeSpecies("treeBirch", false, "Silver Birch", betula, + "pendula", proxy.getFoliageColorBirch(), 0xb0c648, WorldGenBirch.class, new ItemStack(Blocks.log, 1, 2)) + .setVanillaMap(2).setIsSecret(); + Allele.treeLime = new AlleleTreeSpecies("treeLime", true, "Silver Lime", tilia, + "tomentosa", 0x5ea107, WorldGenLime.class, new ItemStack(ForestryBlock.log1, 1, 3)).addFruitFamily(nux) + .addFruitFamily(prunes).addFruitFamily(pomes); + + // Nucifera + Allele.treeWalnut = new AlleleTreeSpecies("treeWalnut", true, "Common Walnut", juglans, + "regia", 0x798c55, 0xb0c648, WorldGenWalnut.class, new ItemStack(ForestryBlock.log4, 1, 1)).addFruitFamily(nux) + .addFruitFamily(prunes).addFruitFamily(pomes).setGirth(2); + Allele.treeChestnut = new AlleleTreeSpecies("treeChestnut", true, "Sweet Chestnut", + castanea, "sativa", 0x5ea107, 0xb0c648, WorldGenChestnut.class, new ItemStack(ForestryBlock.log2, 1, 0)).addFruitFamily(nux) + .addFruitFamily(prunes).addFruitFamily(pomes).setGirth(2); + + // Prunus & Citrus + // fructifer, annifer, bifer, aurifer = bearing fruit, + // bearing fruit year round, bearing fruit twice a year, bearing golden + // fruit + Allele.treeCherry = new AlleleTreeSpecies("treeCherry", true, "Hill Cherry", prunus, + "serrulata", 0xe691da, 0xe63e59, WorldGenCherry.class, new ItemStack(ForestryBlock.log4, 1, 3)).addFruitFamily(prunes) + .addFruitFamily(pomes); + Allele.treeLemon = new AlleleTreeSpecies("treeLemon", true, "Lemon", citrus, "limon", + 0x88af54, 0xa3b850, WorldGenLemon.class, new ItemStack(ForestryBlock.log6, 1, 3)).addFruitFamily(pomes).addFruitFamily( + prunes); + Allele.treePlum = new AlleleTreeSpecies("treePlum", true, "Plum", prunus, "domestica", + 0x589246, 0xa3b850, WorldGenPlum.class, new ItemStack(ForestryBlock.log6, 1, 1)).addFruitFamily(pomes) + .addFruitFamily(prunes); + + // Maples + Allele.treeMaple = new AlleleTreeSpecies("treeMaple", true, "Sugar Maple", acer, + "saccharum", 0xd4f425, 0x619a3c, WorldGenMaple.class, new ItemStack(ForestryBlock.log6, 1, 2)).addFruitFamily(prunes) + .addFruitFamily(pomes).setLeafIndices("maple"); + + Allele.treeSpruce = new AlleleTreeSpecies("treeSpruce", false, "Red Spruce", picea, + "abies", proxy.getFoliageColorPine(), 0x539d12, WorldGenSpruce.class, new ItemStack(Blocks.log, 1, 1)) + .setLeafIndices("conifers").setVanillaMap(1).setIsSecret(); + Allele.treeLarch = new AlleleTreeSpecies("treeLarch", true, "Mundane Larch", larix, + "decidua", 0x698f90, 0x569896, WorldGenLarch.class, new ItemStack(ForestryBlock.log1, 1, 0)).setLeafIndices("conifers"); + Allele.treePine = new AlleleTreeSpecies("treePine", true, "Bull Pine", pinus, "sabiniana", + 0xfeff8f, 0xffd98f, WorldGenPine.class, new ItemStack(ForestryBlock.log6, 1, 0)).setLeafIndices("conifers"); + + Allele.treeSequioa = new AlleleTreeSpecies("treeSequioa", false, "Coast Sequoia", sequoia, + "sempervirens", 0x418e71, 0x569896, WorldGenSequoia.class, new ItemStack(ForestryBlock.log2, 1, 3)).setLeafIndices( + "conifers").setGirth(3); + Allele.treeGiganteum = new AlleleTreeSpecies("treeGigant", false, "Giant Sequoia", + sequoiadendron, "giganteum", 0x738434, WorldGenGiganteum.class, new ItemStack(ForestryBlock.log2, 1, 3)).setLeafIndices( + "conifers").setGirth(4); + + // Jungle + Allele.treeJungle = new AlleleTreeSpecies("treeJungle", false, "Jungle", tropical, + "tectona", proxy.getFoliageColorBasic(), 0x539d12, WorldGenJungle.class, new ItemStack(Blocks.log, 1, 3)) + .addFruitFamily(jungle).setLeafIndices("jungle").setVanillaMap(3).setIsSecret(); + Allele.treeTeak = new AlleleTreeSpecies("treeTeak", true, "Teak", tectona, "grandis", + 0xfeff8f, 0xffd98f, WorldGenTeak.class, new ItemStack(ForestryBlock.log1, 1, 3)).addFruitFamily(jungle).setLeafIndices( + "jungle"); + Allele.treeKapok = new AlleleTreeSpecies("treeKapok", true, "Kapok", ceiba, "pentandra", + 0x89987b, 0x89aa9e, WorldGenKapok.class, new ItemStack(ForestryBlock.log3, 1, 0)).addFruitFamily(jungle) + .addFruitFamily(prunes).setLeafIndices("jungle"); + + // Ebony + Allele.treeEbony = new AlleleTreeSpecies("treeEbony", true, "Myrtle Ebony", diospyros, + "pentamera", 0xa2d24a, 0xc4d24a, WorldGenEbony.class, new ItemStack(ForestryBlock.log3, 1, 1)).addFruitFamily(jungle) + .addFruitFamily(prunes).setGirth(3).setLeafIndices("jungle"); + + // Diospyros mespiliformis, the Jackalberry (also known as African Ebony + // The Gaub Tree, Malabar ebony, Black-and-white Ebony or Pale Moon + // Ebony (Diospyros malabarica) + // Diospyros fasciculosa, is a rainforest tree in the Ebony family. + // Usually seen as a medium sized tree, but it may grow to 30 metres + // tall. + // http://en.wikipedia.org/wiki/Diospyros_ebenum + // http://en.wikipedia.org/wiki/Diospyros_crassiflora - + // "The wood this particular tree produces is believed to be the blackest of all timber-producing Diospyros species" + // Coromandel Ebony or East Indian Ebony (Diospyros melanoxylon) - + // " locally it is known as temburini or by its Hindi name tendu. In Orissa and Jharkhand it known as kendu." + + // Mahogany + Allele.treeMahogany = new AlleleTreeSpecies("treeMahogony", true, "Yellow Meranti", shorea, + "gibbosa", 0x8ab154, 0xa9b154, WorldGenMahogany.class, new ItemStack(ForestryBlock.log3, 1, 2)).addFruitFamily(jungle) + .setGirth(2).setLeafIndices("jungle"); + + // 80+ meters tall: + // Shorea argentifolia (also called Dark Red Meranti) + // Shorea gibbosa (also called Yellow Meranti) + // Shorea smithiana (also called Light Red Meranti) + // Shorea superba + + // Malva + Allele.treeAcacia = new AlleleTreeSpecies("treeAcacia", true, "Desert Acacia", acacia, + "erioloba", 0x616101, 0xb3b302, WorldGenAcacia.class, new ItemStack(ForestryBlock.log1, 1, 2)).addFruitFamily(jungle) + .addFruitFamily(nux); + Allele.treeBalsa = new AlleleTreeSpecies("treeBalsa", true, "Balsa", ochroma, "pyramidale", + 0x59ac00, 0xfeff8f, WorldGenBalsa.class, new ItemStack(ForestryBlock.log3, 1, 3)).addFruitFamily(jungle).addFruitFamily(nux); + Allele.treeWenge = new AlleleTreeSpecies("treeWenge", true, "Wenge", millettia, + "laurentii", 0xada157, 0xad8a57, WorldGenWenge.class, new ItemStack(ForestryBlock.log2, 1, 1)).addFruitFamily(jungle) + .addFruitFamily(nux).setGirth(2); + Allele.treeBaobab = new AlleleTreeSpecies("treeBaobab", true, "Grandidier's Baobab", + adansonia, "digitata", 0xfeff8f, 0xffd98f, WorldGenBaobab.class, new ItemStack(ForestryBlock.log2, 1, 2)) + .addFruitFamily(jungle).addFruitFamily(nux).setGirth(3); + Allele.treeMahoe = new AlleleTreeSpecies("treeMahoe", true, "Blue Mahoe", talipariti, + "elatum", 0xa0ba1b, 0x79a175, WorldGenMahoe.class, new ItemStack(ForestryBlock.log5, 1, 0)).addFruitFamily(jungle) + .addFruitFamily(pomes).addFruitFamily(prunes); + + // Willows + Allele.treeWillow = new AlleleTreeSpecies("treeWillow", true, "White Willow", salix, + "alba", 0xa3b8a5, 0xa3b850, WorldGenWillow.class, new ItemStack(ForestryBlock.log4, 1, 0)).addFruitFamily(nux) + .addFruitFamily(prunes).addFruitFamily(pomes).setLeafIndices("willow"); + + // Lauraceae + Allele.treeSipiri = new AlleleTreeSpecies("treeSipiri", true, "Sipiri", chlorocardium, + "rodiei", 0x678911, 0x79a175, WorldGenGreenheart.class, new ItemStack(ForestryBlock.log3, 1, 2)).addFruitFamily(jungle); + + // Unclassified + Allele.treePapaya = new AlleleTreeSpecies("treePapaya", true, "Papaya", carica, "papaya", + 0x6d9f58, 0x9ee67f, WorldGenPapaya.class, new ItemStack(ForestryBlock.log5, 1, 3)).addFruitFamily(jungle) + .addFruitFamily(nux).setLeafIndices("palm"); + Allele.treeDate = new AlleleTreeSpecies("treeDate", true, "Date Palm", null, "dactylifera", + 0xcbcd79, 0xf0f38f, WorldGenDate.class, new ItemStack(ForestryBlock.log4, 1, 2)).addFruitFamily(jungle).addFruitFamily(nux) + .setLeafIndices("palm"); + + Allele.treePoplar = new AlleleTreeSpecies("treePoplar", true, "White Poplar", populus, + "alba", 0xa3b8a5, 0x539d12, WorldGenPoplar.class, new ItemStack(ForestryBlock.log5, 1, 1)).addFruitFamily(pomes) + .addFruitFamily(prunes); + + // FRUITS + Allele.fruitNone = new AlleleFruit("fruitNone", new FruitProviderNone("none", null)); + Allele.fruitApple = new AlleleFruit("fruitApple", new FruitProviderRandom("apple", pomes, new ItemStack(Items.apple), 1.0f).setColour(0xff2e2e).setOverlay("pomes")); + Allele.fruitCocoa = new AlleleFruit("fruitCocoa", new FruitProviderPod("cocoa", jungle, EnumPodType.COCOA)); + // .setColours(0xecdca5, 0xc4d24a), true); + Allele.fruitChestnut = new AlleleFruit("fruitChestnut", new FruitProviderRipening("chestnut", nux, ForestryItem.fruits.getItemStack(1, EnumFruit.CHESTNUT.ordinal()), 1.0f).setRipeningPeriod(6).setColours(0x7f333d, 0xc4d24a).setOverlay("nuts"), true); + Allele.fruitWalnut = new AlleleFruit("fruitWalnut", new FruitProviderRipening("walnut", nux, ForestryItem.fruits.getItemStack(1, EnumFruit.WALNUT.ordinal()), 1.0f).setRipeningPeriod(8).setColours(0xfba248, 0xc4d24a).setOverlay("nuts"), true); + Allele.fruitCherry = new AlleleFruit("fruitCherry", new FruitProviderRipening("cherry", prunes, ForestryItem.fruits.getItemStack(1, EnumFruit.CHERRY.ordinal()), 1.0f).setColours(0xff2e2e, 0xc4d24a).setOverlay("berries"), true); + Allele.fruitDates = new AlleleFruit("fruitDates", new FruitProviderPod("dates", jungle, EnumPodType.DATES, ForestryItem.fruits.getItemStack(4, EnumFruit.DATES.ordinal()))); + Allele.fruitPapaya = new AlleleFruit("fruitPapaya", new FruitProviderPod("papaya", jungle, EnumPodType.PAPAYA, ForestryItem.fruits.getItemStack(1, EnumFruit.PAPAYA.ordinal()))); + // Allele.fruitCoconut = new AlleleFruit("fruitCoconut", new + // FruitProviderPod("coconut", jungle, EnumPodType.COCONUT, new + // ItemStack[] { new ItemStack( + // ForestryItem.fruits, 1, EnumFruit.COCONUT.ordinal()) })); + Allele.fruitLemon = new AlleleFruit("fruitLemon", new FruitProviderRipening("lemon", prunes, ForestryItem.fruits.getItemStack(1, EnumFruit.LEMON.ordinal()), 1.0f).setColours(0xeeee00, 0x99ff00).setOverlay("citrus"), true); + Allele.fruitPlum = new AlleleFruit("fruitPlum", new FruitProviderRipening("plum", prunes, ForestryItem.fruits.getItemStack(1, EnumFruit.PLUM.ordinal()), 1.0f).setColours(0x663446, 0xeeff1a).setOverlay("plums"), true); + + // / TREES // GROWTH PROVIDER 1350 - 1399 + Allele.growthLightlevel = new AlleleGrowth("growthLightlevel", new GrowthProvider()); + Allele.growthAcacia = new AlleleGrowth("growthAcacia", new GrowthProvider()); + Allele.growthTropical = new AlleleGrowth("growthTropical", new GrowthProviderTropical()); + + // / TREES // EFFECTS 1900 - 1999 + Allele.leavesNone = new AlleleLeafEffectNone("leavesNone"); + + } + + private void registerTemplates() { + treeInterface.registerTemplate(TreeTemplates.getOakTemplate()); + treeInterface.registerTemplate(TreeTemplates.getBirchTemplate()); + treeInterface.registerTemplate(TreeTemplates.getSpruceTemplate()); + treeInterface.registerTemplate(TreeTemplates.getJungleTemplate()); + + treeInterface.registerTemplate(TreeTemplates.getLimeTemplate()); + treeInterface.registerTemplate(TreeTemplates.getCherryTemplate()); + treeInterface.registerTemplate(TreeTemplates.getChestnutTemplate()); + treeInterface.registerTemplate(TreeTemplates.getWalnutTemplate()); + + treeInterface.registerTemplate(TreeTemplates.getLarchTemplate()); + treeInterface.registerTemplate(TreeTemplates.getPineTemplate()); + treeInterface.registerTemplate(TreeTemplates.getSequoiaTemplate()); + treeInterface.registerTemplate(TreeTemplates.getGiganteumTemplate()); + + treeInterface.registerTemplate(TreeTemplates.getBalsaTemplate()); + treeInterface.registerTemplate(TreeTemplates.getAcaciaTemplate()); + treeInterface.registerTemplate(TreeTemplates.getWengeTemplate()); + treeInterface.registerTemplate(TreeTemplates.getBaobabTemplate()); + + treeInterface.registerTemplate(TreeTemplates.getTeakTemplate()); + treeInterface.registerTemplate(TreeTemplates.getKapokTemplate()); + treeInterface.registerTemplate(TreeTemplates.getEbonyTemplate()); + treeInterface.registerTemplate(TreeTemplates.getMahoganyTemplate()); + + treeInterface.registerTemplate(TreeTemplates.getWillowTemplate()); + + treeInterface.registerTemplate(TreeTemplates.getSipiriTemplate()); + + treeInterface.registerTemplate(TreeTemplates.getMahoeTemplate()); + treeInterface.registerTemplate(TreeTemplates.getPoplarTemplate()); + + treeInterface.registerTemplate(TreeTemplates.getLemonTemplate()); + treeInterface.registerTemplate(TreeTemplates.getPlumTemplate()); + treeInterface.registerTemplate(TreeTemplates.getMapleTemplate()); + + treeInterface.registerTemplate(TreeTemplates.getPapayaTemplate()); + treeInterface.registerTemplate(TreeTemplates.getDateTemplate()); + } + + private void registerErsatzGenomes() { + AlleleManager.ersatzSpecimen.put(new ItemStack(Blocks.leaves, 1, 0), new Tree( + TreeTemplates.templateAsGenome(TreeTemplates.getOakTemplate()))); + AlleleManager.ersatzSpecimen.put(new ItemStack(Blocks.leaves, 1, 1), new Tree( + TreeTemplates.templateAsGenome(TreeTemplates.getSpruceTemplate()))); + AlleleManager.ersatzSpecimen.put(new ItemStack(Blocks.leaves, 1, 2), new Tree( + TreeTemplates.templateAsGenome(TreeTemplates.getBirchTemplate()))); + AlleleManager.ersatzSpecimen.put(new ItemStack(Blocks.leaves, 1, 3), new Tree( + TreeTemplates.templateAsGenome(TreeTemplates.getJungleTemplate()))); + + AlleleManager.ersatzSaplings.put(new ItemStack(Blocks.sapling, 1, 0), new Tree( + TreeTemplates.templateAsGenome(TreeTemplates.getOakTemplate()))); + AlleleManager.ersatzSaplings.put(new ItemStack(Blocks.sapling, 1, 1), new Tree( + TreeTemplates.templateAsGenome(TreeTemplates.getSpruceTemplate()))); + AlleleManager.ersatzSaplings.put(new ItemStack(Blocks.sapling, 1, 2), new Tree( + TreeTemplates.templateAsGenome(TreeTemplates.getBirchTemplate()))); + AlleleManager.ersatzSaplings.put(new ItemStack(Blocks.sapling, 1, 3), new Tree( + TreeTemplates.templateAsGenome(TreeTemplates.getJungleTemplate()))); + } + + private void createMutations() { + + // Decidious + TreeTemplates.limeA = new TreeMutation(Allele.treeBirch, Allele.treeOak, + TreeTemplates.getLimeTemplate(), 15); + TreeTemplates.mapleA = new TreeMutation(Allele.treeLime, Allele.treeLarch, + TreeTemplates.getMapleTemplate(), 5); + + // Fructifera + TreeTemplates.cherryA = new TreeMutation(Allele.treeLime, Allele.treeOak, + TreeTemplates.getCherryTemplate(), 10); + TreeTemplates.cherryB = new TreeMutation(Allele.treeLime, Allele.treeBirch, + TreeTemplates.getCherryTemplate(), 10); + TreeTemplates.lemonA = new TreeMutation(Allele.treeLime, Allele.treeCherry, + TreeTemplates.getLemonTemplate(), 5); + TreeTemplates.plumA = new TreeMutation(Allele.treeLemon, Allele.treeCherry, + TreeTemplates.getPlumTemplate(), 5); + + // Nucifera + TreeTemplates.walnutA = new TreeMutation(Allele.treeLime, Allele.treeCherry, + TreeTemplates.getWalnutTemplate(), 10); + TreeTemplates.chestnutA = new TreeMutation(Allele.treeWalnut, Allele.treeLime, + TreeTemplates.getChestnutTemplate(), 10); + TreeTemplates.chestnutB = new TreeMutation(Allele.treeWalnut, Allele.treeCherry, + TreeTemplates.getChestnutTemplate(), 10); + + // Conifera + TreeTemplates.larchA = new TreeMutation(Allele.treeSpruce, Allele.treeBirch, + TreeTemplates.getLarchTemplate(), 10); + TreeTemplates.larchB = new TreeMutation(Allele.treeSpruce, Allele.treeOak, + TreeTemplates.getLarchTemplate(), 10); + TreeTemplates.pineA = new TreeMutation(Allele.treeSpruce, Allele.treeLarch, + TreeTemplates.getPineTemplate(), 10); + TreeTemplates.sequoiaA = new TreeMutation(Allele.treeLarch, Allele.treePine, + TreeTemplates.getSequoiaTemplate(), 5); + + // Tropical + TreeTemplates.teakA = new TreeMutation(Allele.treeLime, Allele.treeJungle, + TreeTemplates.getTeakTemplate(), 10); + TreeTemplates.kapokA = new TreeMutation(Allele.treeJungle, Allele.treeTeak, + TreeTemplates.getKapokTemplate(), 10); + TreeTemplates.ebonyA = new TreeMutation(Allele.treeKapok, Allele.treeTeak, + TreeTemplates.getEbonyTemplate(), 10); + TreeTemplates.mahoganyA = new TreeMutation(Allele.treeKapok, Allele.treeEbony, + TreeTemplates.getMahoganyTemplate(), 10); + + TreeTemplates.papayaA = new TreeMutation(Allele.treeJungle, Allele.treeCherry, + TreeTemplates.getPapayaTemplate(), 5); + TreeTemplates.dateA = new TreeMutation(Allele.treeJungle, Allele.treePapaya, + TreeTemplates.getDateTemplate(), 5); + + // Malva + TreeTemplates.balsaA = new TreeMutation(Allele.treeTeak, Allele.treeLime, + TreeTemplates.getBalsaTemplate(), 10); + TreeTemplates.acaciaA = new TreeMutation(Allele.treeTeak, Allele.treeBalsa, + TreeTemplates.getAcaciaTemplate(), 10); + TreeTemplates.wengeA = new TreeMutation(Allele.treeAcacia, Allele.treeBalsa, + TreeTemplates.getWengeTemplate(), 10); + TreeTemplates.baobabA = new TreeMutation(Allele.treeBalsa, Allele.treeWenge, + TreeTemplates.getBaobabTemplate(), 10); + TreeTemplates.mahoeA = new TreeMutation(Allele.treeBirch, Allele.treeAcacia, + TreeTemplates.getMahoeTemplate(), 5); + + TreeTemplates.willowA = new TreeMutation(Allele.treeOak, Allele.treeBirch, + TreeTemplates.getWillowTemplate(), 10).setTemperatureRainfall(0.7f, 1.5f, 0.9f, + 2.0f); + TreeTemplates.willowB = new TreeMutation(Allele.treeOak, Allele.treeLime, + TreeTemplates.getWillowTemplate(), 10).setTemperatureRainfall(0.7f, 1.5f, 0.9f, + 2.0f); + TreeTemplates.willowC = new TreeMutation(Allele.treeLime, Allele.treeBirch, + TreeTemplates.getWillowTemplate(), 10).setTemperatureRainfall(0.7f, 1.5f, 0.9f, + 2.0f); + + TreeTemplates.sipiriA = new TreeMutation(Allele.treeKapok, Allele.treeMahogany, + TreeTemplates.getSipiriTemplate(), 10).setTemperatureRainfall(0.9f, 1.9f, 0.9f, + 2.0f); + + TreeTemplates.poplarA = new TreeMutation(Allele.treeBirch, Allele.treeWillow, + TreeTemplates.getPoplarTemplate(), 5); + TreeTemplates.poplarB = new TreeMutation(Allele.treeOak, Allele.treeWillow, + TreeTemplates.getPoplarTemplate(), 5); + TreeTemplates.poplarB = new TreeMutation(Allele.treeLime, Allele.treeWillow, + TreeTemplates.getPoplarTemplate(), 5); + + } + + @Override + public IGuiHandler getGuiHandler() { + return new GuiHandlerArboriculture(); + } + + @Override + public ISaveEventHandler getSaveEventHandler() { + return null; + } + + @Override + public IOreDictionaryHandler getDictionaryHandler() { + return null; + } + + @Override + public ICommand[] getConsoleCommands() { + return new ICommand[] { new CommandSpawnTree(), new CommandSpawnForest(), + new CommandTreekeepingMode() }; + } + + @Override + public int getBurnTime(ItemStack fuel) { + if (ForestryItem.sapling.isItemEqual(fuel)) + return 100; + + return 0; + } + + @Override + public IPacketHandler getPacketHandler() { + return new PacketHandlerArboriculture(); + } + + @Override + public boolean processIMCMessage(IMCMessage message) { + if (message.key.equals("add-fence-block") && message.isStringMessage()) { + Block block = GameData.blockRegistry.getObject(message.getStringValue()); + + if (block == null || block == Blocks.air) { + Proxies.log.warning("invalid add-fence-block IMC: can't resolve block name %s.", message.getStringValue()); + } else { + validFences.add(block); + } + } + return super.processIMCMessage(message); + } + + private void registerDungeonLoot() { + ChestGenHooks.addItem(Defaults.CHEST_GEN_HOOK_NATURALIST_CHEST, new WeightedRandomChestContent(ForestryItem.grafter.getItemStack(), 1, 1, 8)); + + ChestGenHooks.addItem(Defaults.CHEST_GEN_HOOK_NATURALIST_CHEST, new WeightedRandomChestContent(this.getTreeItemFromTemplate(TreeTemplates.getOakTemplate(), EnumGermlingType.SAPLING), 2, 3, 6)); + ChestGenHooks.addItem(Defaults.CHEST_GEN_HOOK_NATURALIST_CHEST, new WeightedRandomChestContent(this.getTreeItemFromTemplate(TreeTemplates.getSpruceTemplate(), EnumGermlingType.SAPLING), 2, 3, 6)); + ChestGenHooks.addItem(Defaults.CHEST_GEN_HOOK_NATURALIST_CHEST, new WeightedRandomChestContent(this.getTreeItemFromTemplate(TreeTemplates.getBirchTemplate(), EnumGermlingType.SAPLING), 2, 3, 6)); + ChestGenHooks.addItem(Defaults.CHEST_GEN_HOOK_NATURALIST_CHEST, new WeightedRandomChestContent(this.getTreeItemFromTemplate(TreeTemplates.getLarchTemplate(), EnumGermlingType.SAPLING), 1, 2, 4)); + ChestGenHooks.addItem(Defaults.CHEST_GEN_HOOK_NATURALIST_CHEST, new WeightedRandomChestContent(this.getTreeItemFromTemplate(TreeTemplates.getLimeTemplate(), EnumGermlingType.SAPLING), 1, 2, 4)); + + ChestGenHooks.addItem(Defaults.CHEST_GEN_HOOK_NATURALIST_CHEST, new WeightedRandomChestContent(this.getTreeItemFromTemplate(TreeTemplates.getOakTemplate(), EnumGermlingType.POLLEN), 2, 3, 4)); + ChestGenHooks.addItem(Defaults.CHEST_GEN_HOOK_NATURALIST_CHEST, new WeightedRandomChestContent(this.getTreeItemFromTemplate(TreeTemplates.getSpruceTemplate(), EnumGermlingType.POLLEN), 2, 3, 4)); + ChestGenHooks.addItem(Defaults.CHEST_GEN_HOOK_NATURALIST_CHEST, new WeightedRandomChestContent(this.getTreeItemFromTemplate(TreeTemplates.getBirchTemplate(), EnumGermlingType.POLLEN), 2, 3, 4)); + ChestGenHooks.addItem(Defaults.CHEST_GEN_HOOK_NATURALIST_CHEST, new WeightedRandomChestContent(this.getTreeItemFromTemplate(TreeTemplates.getLarchTemplate(), EnumGermlingType.POLLEN), 1, 2, 3)); + ChestGenHooks.addItem(Defaults.CHEST_GEN_HOOK_NATURALIST_CHEST, new WeightedRandomChestContent(this.getTreeItemFromTemplate(TreeTemplates.getLimeTemplate(), EnumGermlingType.POLLEN), 1, 2, 3)); + } + + private ItemStack getTreeItemFromTemplate(IAllele[] template, EnumGermlingType type) { + ITree tree = new Tree(PluginArboriculture.treeInterface.templateAsGenome(template)); + ItemStack treeItem; + switch (type) { + default: + case POLLEN: + treeItem = ForestryItem.pollenFertile.getItemStack(); + break; + case SAPLING: + treeItem = ForestryItem.sapling.getItemStack(); + } + NBTTagCompound nbtTagCompound = new NBTTagCompound(); + tree.writeToNBT(nbtTagCompound); + treeItem.setTagCompound(nbtTagCompound); + return treeItem; + } +} diff --git a/forestry_common/core/forestry/Forestry.java b/forestry_common/core/forestry/Forestry.java new file mode 100755 index 000000000..5a80b8c35 --- /dev/null +++ b/forestry_common/core/forestry/Forestry.java @@ -0,0 +1,96 @@ +/******************************************************************************* + * Copyright 2011-2014 by SirSengir + * + * This work is licensed under a Creative Commons Attribution-NonCommercial-NoDerivs 3.0 Unported License. + * + * To view a copy of this license, visit http://creativecommons.org/licenses/by-nc-nd/3.0/. + ******************************************************************************/ +package forestry; + +import cpw.mods.fml.common.Mod; +import cpw.mods.fml.common.Mod.EventHandler; +import cpw.mods.fml.common.SidedProxy; +import cpw.mods.fml.common.event.FMLInitializationEvent; +import cpw.mods.fml.common.event.FMLInterModComms.IMCEvent; +import cpw.mods.fml.common.event.FMLPostInitializationEvent; +import cpw.mods.fml.common.event.FMLPreInitializationEvent; +import cpw.mods.fml.common.event.FMLServerStartingEvent; + +import forestry.api.fuels.EngineBronzeFuel; +import forestry.api.fuels.EngineCopperFuel; +import forestry.api.fuels.FermenterFuel; +import forestry.api.fuels.FuelManager; +import forestry.api.fuels.MoistenerFuel; +import forestry.api.fuels.RainSubstrate; +import forestry.core.ForestryCore; +import forestry.core.config.Defaults; +import forestry.core.config.Version; +import forestry.core.network.PacketHandler; +import forestry.core.utils.FluidMap; +import forestry.core.utils.ItemStackMap; + +/** + * Forestry Minecraft Mod + * + * @author SirSengir + */ +@Mod( + modid = Defaults.MOD, + name = "Forestry", + version = Version.VERSION, + dependencies = "" + + "after:Buildcraft|Core;" + + "after:ExtrabiomesXL;" + + "after:BiomesOPlenty;" + + "after:IC2") +//, certificateFingerprint = Version.FINGERPRINT) +public class Forestry { + + @Mod.Instance(Defaults.MOD) + public static Forestry instance; + + public Forestry() { + FuelManager.fermenterFuel = new ItemStackMap(); + FuelManager.moistenerResource = new ItemStackMap(); + FuelManager.rainSubstrate = new ItemStackMap(); + FuelManager.bronzeEngineFuel = new FluidMap(); + FuelManager.copperEngineFuel = new ItemStackMap(); + } + @SidedProxy(clientSide = "forestry.core.ForestryClient", serverSide = "forestry.core.ForestryCore") + public static ForestryCore core = new ForestryCore(); + public static PacketHandler packetHandler; + + @EventHandler + public void preInit(FMLPreInitializationEvent event) { + packetHandler = new PacketHandler(); + + core.preInit(event.getSourceFile(), this); + } + + @EventHandler + public void init(FMLInitializationEvent event) { + core.init(this); + } + + @EventHandler + public void postInit(FMLPostInitializationEvent event) { + core.postInit(); + } + + @EventHandler + public void serverStarting(FMLServerStartingEvent event) { + core.serverStarting(event.getServer()); + } + + /*@EventHandler + public void fingerprintWarning(FMLFingerprintViolationEvent event) { + Proxies.log.info("Fingerprint of the mod jar is invalid. The jar file was tampered with."); + FMLInterModComms.sendMessage("Railcraft", "securityViolation", "Fingerprint of jar file did not match."); + FMLInterModComms.sendMessage("Thaumcraft", "securityViolation", "Fingerprint of jar file did not match."); + FMLInterModComms.sendMessage("IC2", "securityViolation", "Fingerprint of jar file did not match."); + }*/ + @EventHandler + public void processIMCMessages(IMCEvent event) { + core.processIMCMessages(event.getMessages()); + } +} diff --git a/forestry_common/core/forestry/api/apiculture/BeeManager.java b/forestry_common/core/forestry/api/apiculture/BeeManager.java new file mode 100755 index 000000000..7b65c0451 --- /dev/null +++ b/forestry_common/core/forestry/api/apiculture/BeeManager.java @@ -0,0 +1,48 @@ +/******************************************************************************* + * Copyright 2011-2014 by SirSengir + * + * This work is licensed under a Creative Commons Attribution-NonCommercial-NoDerivs 3.0 Unported License. + * + * To view a copy of this license, visit http://creativecommons.org/licenses/by-nc-nd/3.0/. + ******************************************************************************/ +package forestry.api.apiculture; + +import java.util.ArrayList; +import java.util.HashMap; + +import net.minecraft.item.ItemStack; + +import forestry.api.genetics.IMutation; +/** + * + * Some miscellaneous lists and settings for bees. + * + * @author SirSengir + */ +public class BeeManager { + + /** + * Get your own reference to this via AlleleManager.alleleRegistry.getSpeciesRoot("rootBees") and save it somewhere. + */ + @Deprecated + public static IBeeRoot beeInterface; + + /** + * Species templates for bees that can drop from hives. + * + * 0 - Forest 1 - Meadows 2 - Desert 3 - Jungle 4 - End 5 - Snow 6 - Swamp + * + * see {@link IMutation} for template format + */ + public static ArrayList[] hiveDrops; + + /** + * 0 - Common Village Bees 1 - Uncommon Village Bees (20 % of spawns) + */ + public static ArrayList[] villageBees; + + /** + * List of items that can induce swarming. Integer denotes x in 1000 chance. + */ + public static HashMap inducers = new HashMap(); +} diff --git a/forestry_common/core/forestry/api/apiculture/EnumBeeChromosome.java b/forestry_common/core/forestry/api/apiculture/EnumBeeChromosome.java new file mode 100755 index 000000000..f1d3031e4 --- /dev/null +++ b/forestry_common/core/forestry/api/apiculture/EnumBeeChromosome.java @@ -0,0 +1,105 @@ +/******************************************************************************* + * Copyright 2011-2014 by SirSengir + * + * This work is licensed under a Creative Commons Attribution-NonCommercial-NoDerivs 3.0 Unported License. + * + * To view a copy of this license, visit http://creativecommons.org/licenses/by-nc-nd/3.0/. + ******************************************************************************/ +package forestry.api.apiculture; + +import forestry.api.genetics.AlleleManager; +import forestry.api.genetics.IAllele; +import forestry.api.genetics.IAlleleArea; +import forestry.api.genetics.IAlleleBoolean; +import forestry.api.genetics.IAlleleFloat; +import forestry.api.genetics.IAlleleFlowers; +import forestry.api.genetics.IAlleleInteger; +import forestry.api.genetics.IAlleleTolerance; +import forestry.api.genetics.IChromosomeType; +import forestry.api.genetics.ISpeciesRoot; + +/** + * Enum representing the order of chromosomes in a bee's genome and what they control. + * + * @author SirSengir + */ +public enum EnumBeeChromosome implements IChromosomeType { + /** + * Species of the bee. Alleles here must implement {@link IAlleleBeeSpecies}. + */ + SPECIES(IAlleleBeeSpecies.class), + /** + * (Production) Speed of the bee. + */ + SPEED(IAlleleFloat.class), + /** + * Lifespan of the bee. + */ + LIFESPAN(IAlleleInteger.class), + /** + * Fertility of the bee. Determines number of offspring. + */ + FERTILITY(IAlleleInteger.class), + /** + * Temperature difference to its native supported one the bee can tolerate. + */ + TEMPERATURE_TOLERANCE(IAlleleTolerance.class), + /** + * Slightly incorrectly named. If true, a naturally dirunal bee can work during the night. If true, a naturally nocturnal bee can work during the day. + */ + NOCTURNAL(IAlleleBoolean.class), + /** + * Not used / superseded by fixed values for the species. Probably going to be replaced with a boolean for FIRE_RESIST. + */ + @Deprecated + HUMIDITY(IAllele.class), + /** + * Humidity difference to its native supported one the bee can tolerate. + */ + HUMIDITY_TOLERANCE(IAlleleTolerance.class), + /** + * If true the bee can work during rain. + */ + TOLERANT_FLYER(IAlleleBoolean.class), + /** + * If true, the bee can work without a clear view of the sky. + */ + CAVE_DWELLING(IAlleleBoolean.class), + /** + * Contains the supported flower provider. + */ + FLOWER_PROVIDER(IAlleleFlowers.class), + /** + * Determines pollination speed. + */ + FLOWERING(IAlleleInteger.class), + /** + * Determines the size of the bee's territory. + */ + TERRITORY(IAlleleArea.class), + /** + * Determines the bee's effect. + */ + EFFECT(IAlleleBeeEffect.class); + + Class clss; + + EnumBeeChromosome(Class clss) { + this.clss = clss; + } + + @Override + public Class getAlleleClass() { + return clss; + } + + @Override + public String getName() { + return this.toString().toLowerCase(); + } + + @Override + public ISpeciesRoot getSpeciesRoot() { + return AlleleManager.alleleRegistry.getSpeciesRoot("rootBees"); + } +} diff --git a/forestry_common/core/forestry/api/apiculture/EnumBeeType.java b/forestry_common/core/forestry/api/apiculture/EnumBeeType.java new file mode 100755 index 000000000..a3d22e5a5 --- /dev/null +++ b/forestry_common/core/forestry/api/apiculture/EnumBeeType.java @@ -0,0 +1,26 @@ +/******************************************************************************* + * Copyright 2011-2014 by SirSengir + * + * This work is licensed under a Creative Commons Attribution-NonCommercial-NoDerivs 3.0 Unported License. + * + * To view a copy of this license, visit http://creativecommons.org/licenses/by-nc-nd/3.0/. + ******************************************************************************/ +package forestry.api.apiculture; + +import java.util.Locale; + +public enum EnumBeeType { + DRONE, PRINCESS, QUEEN, LARVAE, NONE; + + public static final EnumBeeType[] VALUES = values(); + + String name; + + private EnumBeeType() { + this.name = "bees." + this.toString().toLowerCase(Locale.ENGLISH); + } + + public String getName() { + return name; + } +} diff --git a/forestry_common/core/forestry/api/apiculture/FlowerManager.java b/forestry_common/core/forestry/api/apiculture/FlowerManager.java new file mode 100755 index 000000000..144852121 --- /dev/null +++ b/forestry_common/core/forestry/api/apiculture/FlowerManager.java @@ -0,0 +1,21 @@ +/******************************************************************************* + * Copyright 2011-2014 by SirSengir + * + * This work is licensed under a Creative Commons Attribution-NonCommercial-NoDerivs 3.0 Unported License. + * + * To view a copy of this license, visit http://creativecommons.org/licenses/by-nc-nd/3.0/. + ******************************************************************************/ +package forestry.api.apiculture; + +import java.util.ArrayList; + +import net.minecraft.item.ItemStack; + +import forestry.api.genetics.IFlowerProvider; + +public class FlowerManager { + /** + * ItemStacks representing simple flower blocks. Meta-sensitive, processed by the basic {@link IFlowerProvider}. + */ + public static ArrayList plainFlowers = new ArrayList(); +} diff --git a/forestry_common/core/forestry/api/apiculture/IAlleleBeeEffect.java b/forestry_common/core/forestry/api/apiculture/IAlleleBeeEffect.java new file mode 100755 index 000000000..dd568bba5 --- /dev/null +++ b/forestry_common/core/forestry/api/apiculture/IAlleleBeeEffect.java @@ -0,0 +1,38 @@ +/******************************************************************************* + * Copyright 2011-2014 by SirSengir + * + * This work is licensed under a Creative Commons Attribution-NonCommercial-NoDerivs 3.0 Unported License. + * + * To view a copy of this license, visit http://creativecommons.org/licenses/by-nc-nd/3.0/. + ******************************************************************************/ +package forestry.api.apiculture; + +import forestry.api.genetics.IAlleleEffect; +import forestry.api.genetics.IEffectData; + +public interface IAlleleBeeEffect extends IAlleleEffect { + + /** + * Called by apiaries to cause an effect in the world. + * + * @param genome + * Genome of the bee queen causing this effect + * @param storedData + * Object containing the stored effect data for the apiary/hive the bee is in. + * @param housing {@link IBeeHousing} the bee currently resides in. + * @return storedData, may have been manipulated. + */ + IEffectData doEffect(IBeeGenome genome, IEffectData storedData, IBeeHousing housing); + + /** + * Is called to produce bee effects. + * + * @param genome + * @param storedData + * Object containing the stored effect data for the apiary/hive the bee is in. + * @param housing {@link IBeeHousing} the bee currently resides in. + * @return storedData, may have been manipulated. + */ + IEffectData doFX(IBeeGenome genome, IEffectData storedData, IBeeHousing housing); + +} diff --git a/forestry_common/core/forestry/api/apiculture/IAlleleBeeSpecies.java b/forestry_common/core/forestry/api/apiculture/IAlleleBeeSpecies.java new file mode 100755 index 000000000..54f5fad42 --- /dev/null +++ b/forestry_common/core/forestry/api/apiculture/IAlleleBeeSpecies.java @@ -0,0 +1,55 @@ +/******************************************************************************* + * Copyright 2011-2014 by SirSengir + * + * This work is licensed under a Creative Commons Attribution-NonCommercial-NoDerivs 3.0 Unported License. + * + * To view a copy of this license, visit http://creativecommons.org/licenses/by-nc-nd/3.0/. + ******************************************************************************/ +package forestry.api.apiculture; + +import java.util.Map; + +import net.minecraft.item.ItemStack; +import net.minecraft.util.IIcon; + +import cpw.mods.fml.relauncher.Side; +import cpw.mods.fml.relauncher.SideOnly; + +import forestry.api.genetics.IAlleleSpecies; + +public interface IAlleleBeeSpecies extends IAlleleSpecies { + + /** + * @return the IBeeRoot + */ + IBeeRoot getRoot(); + + /** + * @return true if this species is only active at night. + */ + boolean isNocturnal(); + + /** + * @return Map of possible products with the chance for drop each bee cycle. (0 - 100) + */ + Map getProducts(); + + /** + * @return Map of possible specialities with the chance for drop each bee cycle. (0 - 100) + */ + Map getSpecialty(); + + /** + * Only jubilant bees produce specialities. + * @return true if the bee is jubilant, false otherwise. + */ + boolean isJubilant(IBeeGenome genome, IBeeHousing housing); + + @SideOnly(Side.CLIENT) + IIcon getIcon(EnumBeeType type, int renderPass); + + /** + * @return Path of the texture to use for entity rendering. + */ + String getEntityTexture(); +} diff --git a/forestry_common/core/forestry/api/apiculture/IAlvearyComponent.java b/forestry_common/core/forestry/api/apiculture/IAlvearyComponent.java new file mode 100755 index 000000000..29bf153cb --- /dev/null +++ b/forestry_common/core/forestry/api/apiculture/IAlvearyComponent.java @@ -0,0 +1,34 @@ +/******************************************************************************* + * Copyright 2011-2014 by SirSengir + * + * This work is licensed under a Creative Commons Attribution-NonCommercial-NoDerivs 3.0 Unported License. + * + * To view a copy of this license, visit http://creativecommons.org/licenses/by-nc-nd/3.0/. + ******************************************************************************/ +package forestry.api.apiculture; + +import forestry.api.core.ITileStructure; + +/** + * Needs to be implemented by TileEntities that want to be part of an alveary. + */ +public interface IAlvearyComponent extends ITileStructure { + + void registerBeeModifier(IBeeModifier modifier); + + void removeBeeModifier(IBeeModifier modifier); + + void registerBeeListener(IBeeListener event); + + void removeBeeListener(IBeeListener event); + + void addTemperatureChange(float change, float boundaryDown, float boundaryUp); + + void addHumidityChange(float change, float boundaryDown, float boundaryUp); + + /** + * @return true if this TE has a function other than a plain alveary block. Returning true prevents the TE from becoming master. + */ + boolean hasFunction(); + +} diff --git a/forestry_common/core/forestry/api/apiculture/IApiaristTracker.java b/forestry_common/core/forestry/api/apiculture/IApiaristTracker.java new file mode 100755 index 000000000..d4657c01a --- /dev/null +++ b/forestry_common/core/forestry/api/apiculture/IApiaristTracker.java @@ -0,0 +1,59 @@ +/******************************************************************************* + * Copyright 2011-2014 by SirSengir + * + * This work is licensed under a Creative Commons Attribution-NonCommercial-NoDerivs 3.0 Unported License. + * + * To view a copy of this license, visit http://creativecommons.org/licenses/by-nc-nd/3.0/. + ******************************************************************************/ +package forestry.api.apiculture; + +import forestry.api.genetics.IBreedingTracker; +import forestry.api.genetics.IIndividual; + +/** + * Can be used to garner information on bee breeding. See {@link forestry.api.genetics.ISpeciesRoot} for retrieval functions. + * + * @author SirSengir + */ +public interface IApiaristTracker extends IBreedingTracker { + + /** + * Register the birth of a queen. Will mark species as discovered. + * + * @param queen + * Created queen. + */ + void registerQueen(IIndividual queen); + + /** + * @return Amount of queens bred with this tracker. + */ + int getQueenCount(); + + /** + * Register the birth of a princess. Will mark species as discovered. + * + * @param princess + * Created princess. + */ + void registerPrincess(IIndividual princess); + + /** + * @return Amount of princesses bred with this tracker. + */ + int getPrincessCount(); + + /** + * Register the birth of a drone. Will mark species as discovered. + * + * @param drone + * Created drone. + */ + void registerDrone(IIndividual drone); + + /** + * @return Amount of drones bred with this tracker. + */ + int getDroneCount(); + +} diff --git a/forestry_common/core/forestry/api/apiculture/IArmorApiarist.java b/forestry_common/core/forestry/api/apiculture/IArmorApiarist.java new file mode 100755 index 000000000..8033a79da --- /dev/null +++ b/forestry_common/core/forestry/api/apiculture/IArmorApiarist.java @@ -0,0 +1,31 @@ +/******************************************************************************* + * Copyright 2011-2014 by SirSengir + * + * This work is licensed under a Creative Commons Attribution-NonCommercial-NoDerivs 3.0 Unported License. + * + * To view a copy of this license, visit http://creativecommons.org/licenses/by-nc-nd/3.0/. + ******************************************************************************/ +package forestry.api.apiculture; + +import net.minecraft.entity.player.EntityPlayer; +import net.minecraft.item.ItemStack; + +/** + * When implemented by armor piece items, allows them to act as apiarist's armor. + */ +public interface IArmorApiarist { + /** + * Called when the apiarist's armor acts as protection against an attack. + * + * @param player + * Player being attacked + * @param armor + * Armor item + * @param cause + * Optional cause of attack, such as a bee effect identifier + * @param doProtect + * Whether or not to actually do the side effects of protection + * @return Whether or not the armor should protect the player from that attack + */ + public boolean protectPlayer(EntityPlayer player, ItemStack armor, String cause, boolean doProtect); +} diff --git a/forestry_common/core/forestry/api/apiculture/IBee.java b/forestry_common/core/forestry/api/apiculture/IBee.java new file mode 100755 index 000000000..45042c416 --- /dev/null +++ b/forestry_common/core/forestry/api/apiculture/IBee.java @@ -0,0 +1,93 @@ +/******************************************************************************* + * Copyright 2011-2014 by SirSengir + * + * This work is licensed under a Creative Commons Attribution-NonCommercial-NoDerivs 3.0 Unported License. + * + * To view a copy of this license, visit http://creativecommons.org/licenses/by-nc-nd/3.0/. + ******************************************************************************/ +package forestry.api.apiculture; + +import java.util.ArrayList; + +import net.minecraft.item.ItemStack; + +import forestry.api.genetics.IEffectData; +import forestry.api.genetics.IIndividual; +import forestry.api.genetics.IIndividualLiving; + +/** + * Other implementations than Forestry's default one are not supported. + * + * @author SirSengir + */ +public interface IBee extends IIndividualLiving { + + /** + * @return Bee's genetic information. + */ + IBeeGenome getGenome(); + + /** + * @return Genetic information of the bee's mate, null if unmated. + */ + IBeeGenome getMate(); + + /** + * @return true if the individual is originally of natural origin. + */ + boolean isNatural(); + + /** + * @return generation this individual is removed from the original individual. + */ + int getGeneration(); + + /** + * Set the natural flag on this bee. + * @param flag + */ + void setIsNatural(boolean flag); + + /** + * @return true if the bee is mated with another whose isNatural() doesn't match. + */ + boolean isIrregularMating(); + + IEffectData[] doEffect(IEffectData[] storedData, IBeeHousing housing); + + IEffectData[] doFX(IEffectData[] storedData, IBeeHousing housing); + + /** + * @return true if the bee may spawn offspring + */ + boolean canSpawn(); + + /** + * Determines whether the queen can work. + * + * @param housing the {@link IBeeHousing} the bee currently resides in. + * @return Ordinal of the error code encountered. 0 - EnumErrorCode.OK + */ + int isWorking(IBeeHousing housing); + + boolean hasFlower(IBeeHousing housing); + + ArrayList getSuitableBiomeIds(); + + ItemStack[] getProduceList(); + + ItemStack[] getSpecialtyList(); + + ItemStack[] produceStacks(IBeeHousing housing); + + IBee spawnPrincess(IBeeHousing housing); + + IBee[] spawnDrones(IBeeHousing housing); + + void plantFlowerRandom(IBeeHousing housing); + + IIndividual retrievePollen(IBeeHousing housing); + + boolean pollinateRandom(IBeeHousing housing, IIndividual pollen); + +} diff --git a/forestry_common/core/forestry/api/apiculture/IBeeGenome.java b/forestry_common/core/forestry/api/apiculture/IBeeGenome.java new file mode 100755 index 000000000..1142a6619 --- /dev/null +++ b/forestry_common/core/forestry/api/apiculture/IBeeGenome.java @@ -0,0 +1,50 @@ +/******************************************************************************* + * Copyright 2011-2014 by SirSengir + * + * This work is licensed under a Creative Commons Attribution-NonCommercial-NoDerivs 3.0 Unported License. + * + * To view a copy of this license, visit http://creativecommons.org/licenses/by-nc-nd/3.0/. + ******************************************************************************/ +package forestry.api.apiculture; + +import forestry.api.genetics.EnumTolerance; +import forestry.api.genetics.IFlowerProvider; +import forestry.api.genetics.IGenome; + +/** + * Only the default implementation is supported. + * + * @author SirSengir + * + */ +public interface IBeeGenome extends IGenome { + + IAlleleBeeSpecies getPrimary(); + + IAlleleBeeSpecies getSecondary(); + + float getSpeed(); + + int getLifespan(); + + int getFertility(); + + EnumTolerance getToleranceTemp(); + + EnumTolerance getToleranceHumid(); + + boolean getNocturnal(); + + boolean getTolerantFlyer(); + + boolean getCaveDwelling(); + + IFlowerProvider getFlowerProvider(); + + int getFlowering(); + + int[] getTerritory(); + + IAlleleBeeEffect getEffect(); + +} diff --git a/forestry_common/core/forestry/api/apiculture/IBeeHousing.java b/forestry_common/core/forestry/api/apiculture/IBeeHousing.java new file mode 100755 index 000000000..3a9456464 --- /dev/null +++ b/forestry_common/core/forestry/api/apiculture/IBeeHousing.java @@ -0,0 +1,29 @@ +/******************************************************************************* + * Copyright 2011-2014 by SirSengir + * + * This work is licensed under a Creative Commons Attribution-NonCommercial-NoDerivs 3.0 Unported License. + * + * To view a copy of this license, visit http://creativecommons.org/licenses/by-nc-nd/3.0/. + ******************************************************************************/ +package forestry.api.apiculture; + +import net.minecraft.item.ItemStack; + +import forestry.api.genetics.IHousing; + +public interface IBeeHousing extends IBeeModifier, IBeeListener, IHousing { + + ItemStack getQueen(); + + ItemStack getDrone(); + + void setQueen(ItemStack itemstack); + + void setDrone(ItemStack itemstack); + + /** + * @return true if princesses and drones can (currently) mate in this housing to generate queens. + */ + boolean canBreed(); + +} diff --git a/forestry_common/core/forestry/api/apiculture/IBeeListener.java b/forestry_common/core/forestry/api/apiculture/IBeeListener.java new file mode 100755 index 000000000..a5cdcbd63 --- /dev/null +++ b/forestry_common/core/forestry/api/apiculture/IBeeListener.java @@ -0,0 +1,48 @@ +/******************************************************************************* + * Copyright 2011-2014 by SirSengir + * + * This work is licensed under a Creative Commons Attribution-NonCommercial-NoDerivs 3.0 Unported License. + * + * To view a copy of this license, visit http://creativecommons.org/licenses/by-nc-nd/3.0/. + ******************************************************************************/ +package forestry.api.apiculture; + +import net.minecraft.item.ItemStack; + +import forestry.api.genetics.IIndividual; + +public interface IBeeListener { + + /** + * Called on queen update. + * + * @param queen + */ + void onQueenChange(ItemStack queen); + + /** + * Called when the bees wear out the housing's equipment. + * + * @param amount + * Integer indicating the amount worn out. + */ + void wearOutEquipment(int amount); + + /** + * Called just before the children are generated, and the queen removed. + * + * @param queen + */ + void onQueenDeath(IBee queen); + + /** + * Called after the children have been spawned, but before the queen appears + * + * @param queen + */ + void onPostQueenDeath(IBee queen); + + boolean onPollenRetrieved(IBee queen, IIndividual pollen, boolean isHandled); + + boolean onEggLaid(IBee queen); +} diff --git a/forestry_common/core/forestry/api/apiculture/IBeeModifier.java b/forestry_common/core/forestry/api/apiculture/IBeeModifier.java new file mode 100755 index 000000000..3fc996493 --- /dev/null +++ b/forestry_common/core/forestry/api/apiculture/IBeeModifier.java @@ -0,0 +1,73 @@ +/******************************************************************************* + * Copyright 2011-2014 by SirSengir + * + * This work is licensed under a Creative Commons Attribution-NonCommercial-NoDerivs 3.0 Unported License. + * + * To view a copy of this license, visit http://creativecommons.org/licenses/by-nc-nd/3.0/. + ******************************************************************************/ +package forestry.api.apiculture; + +public interface IBeeModifier { + + /** + * @param genome Genome of the bee this modifier is called for. + * @param currentModifier Current modifier. + * @return Float used to modify the base territory. + */ + float getTerritoryModifier(IBeeGenome genome, float currentModifier); + + /** + * @param genome Genome of the bee this modifier is called for. + * @param mate + * @param currentModifier Current modifier. + * @return Float used to modify the base mutation chance. + */ + float getMutationModifier(IBeeGenome genome, IBeeGenome mate, float currentModifier); + + /** + * @param genome Genome of the bee this modifier is called for. + * @param currentModifier Current modifier. + * @return Float used to modify the life span of queens. + */ + float getLifespanModifier(IBeeGenome genome, IBeeGenome mate, float currentModifier); + + /** + * @param genome Genome of the bee this modifier is called for. + * @param currentModifier Current modifier. + * @return Float modifying the production speed of queens. + */ + float getProductionModifier(IBeeGenome genome, float currentModifier); + + /** + * @param genome Genome of the bee this modifier is called for. + * @return Float modifying the flowering of queens. + */ + float getFloweringModifier(IBeeGenome genome, float currentModifier); + + /** + * @param genome Genome of the bee this modifier is called for. + * @return Float modifying the chance for a swarmer queen to die off. + */ + float getGeneticDecay(IBeeGenome genome, float currentModifier); + + /** + * @return Boolean indicating if housing can ignore rain + */ + boolean isSealed(); + + /** + * @return Boolean indicating if housing can ignore darkness/night + */ + boolean isSelfLighted(); + + /** + * @return Boolean indicating if housing can ignore not seeing the sky + */ + boolean isSunlightSimulated(); + + /** + * @return Boolean indicating whether this housing simulates the nether + */ + boolean isHellish(); + +} diff --git a/forestry_common/core/forestry/api/apiculture/IBeeMutation.java b/forestry_common/core/forestry/api/apiculture/IBeeMutation.java new file mode 100755 index 000000000..50409be09 --- /dev/null +++ b/forestry_common/core/forestry/api/apiculture/IBeeMutation.java @@ -0,0 +1,27 @@ +/******************************************************************************* + * Copyright 2011-2014 by SirSengir + * + * This work is licensed under a Creative Commons Attribution-NonCommercial-NoDerivs 3.0 Unported License. + * + * To view a copy of this license, visit http://creativecommons.org/licenses/by-nc-nd/3.0/. + ******************************************************************************/ +package forestry.api.apiculture; + +import forestry.api.genetics.IAllele; +import forestry.api.genetics.IGenome; +import forestry.api.genetics.IMutation; + +public interface IBeeMutation extends IMutation { + + IBeeRoot getRoot(); + + /** + * @param housing + * @param allele0 + * @param allele1 + * @param genome0 + * @param genome1 + * @return float representing the chance for mutation to occur. note that this is 0 - 100 based, since it was an integer previously! + */ + float getChance(IBeeHousing housing, IAllele allele0, IAllele allele1, IGenome genome0, IGenome genome1); +} diff --git a/forestry_common/core/forestry/api/apiculture/IBeeRoot.java b/forestry_common/core/forestry/api/apiculture/IBeeRoot.java new file mode 100755 index 000000000..d88c71904 --- /dev/null +++ b/forestry_common/core/forestry/api/apiculture/IBeeRoot.java @@ -0,0 +1,119 @@ +/******************************************************************************* + * Copyright 2011-2014 by SirSengir + * + * This work is licensed under a Creative Commons Attribution-NonCommercial-NoDerivs 3.0 Unported License. + * + * To view a copy of this license, visit http://creativecommons.org/licenses/by-nc-nd/3.0/. + ******************************************************************************/ +package forestry.api.apiculture; + +import java.util.ArrayList; +import java.util.Collection; + +import net.minecraft.item.ItemStack; +import net.minecraft.nbt.NBTTagCompound; +import net.minecraft.world.World; + +import forestry.api.core.IStructureLogic; +import forestry.api.genetics.IAllele; +import forestry.api.genetics.ISpeciesRoot; + +public interface IBeeRoot extends ISpeciesRoot { + + /** + * @return true if passed item is a Forestry bee. Equal to getType(ItemStack stack) != EnumBeeType.NONE + */ + boolean isMember(ItemStack stack); + + /** + * @return {@link IBee} pattern parsed from the passed stack's nbt data. + */ + IBee getMember(ItemStack stack); + + IBee getMember(NBTTagCompound compound); + + /* GENOME CONVERSION */ + IBee templateAsIndividual(IAllele[] template); + + IBee templateAsIndividual(IAllele[] templateActive, IAllele[] templateInactive); + + IBeeGenome templateAsGenome(IAllele[] template); + + IBeeGenome templateAsGenome(IAllele[] templateActive, IAllele[] templateInactive); + + /* BREEDING TRACKER */ + /** + * @param world + * @return {@link IApiaristTracker} associated with the passed world. + */ + IApiaristTracker getBreedingTracker(World world, String player); + + /* BEE SPECIFIC */ + /** + * @return type of bee encoded on the itemstack. EnumBeeType.NONE if it isn't a bee. + */ + EnumBeeType getType(ItemStack stack); + + /** + * @return true if passed item is a drone. Equal to getType(ItemStack stack) == EnumBeeType.DRONE + */ + boolean isDrone(ItemStack stack); + + /** + * @return true if passed item is mated (i.e. a queen) + */ + boolean isMated(ItemStack stack); + + /** + * @param genome + * Valid {@link IBeeGenome} + * @return {@link IBee} from the passed genome + */ + IBee getBee(World world, IBeeGenome genome); + + /** + * Creates an IBee suitable for a queen containing the necessary second genome for the mate. + * + * @param genome + * Valid {@link IBeeGenome} + * @param mate + * Valid {@link IBee} representing the mate. + * @return Mated {@link IBee} from the passed genomes. + */ + IBee getBee(World world, IBeeGenome genome, IBee mate); + + /* TEMPLATES */ + ArrayList getIndividualTemplates(); + + /* MUTATIONS */ + Collection getMutations(boolean shuffle); + + /* GAME MODE */ + void resetBeekeepingMode(); + + ArrayList getBeekeepingModes(); + + IBeekeepingMode getBeekeepingMode(World world); + + IBeekeepingMode getBeekeepingMode(String name); + + void registerBeekeepingMode(IBeekeepingMode mode); + + void setBeekeepingMode(World world, String name); + + /* MISC */ + /** + * @param housing + * Object implementing IBeeHousing. + * @return IBeekeepingLogic + */ + IBeekeepingLogic createBeekeepingLogic(IBeeHousing housing); + + /** + * TileEntities wanting to function as alveary components need to implement structure logic for validation. + * + * @return IStructureLogic for alvearies. + */ + IStructureLogic createAlvearyStructureLogic(IAlvearyComponent structure); + +} diff --git a/forestry_common/core/forestry/api/apiculture/IBeekeepingLogic.java b/forestry_common/core/forestry/api/apiculture/IBeekeepingLogic.java new file mode 100755 index 000000000..dbcd71bb9 --- /dev/null +++ b/forestry_common/core/forestry/api/apiculture/IBeekeepingLogic.java @@ -0,0 +1,29 @@ +/******************************************************************************* + * Copyright 2011-2014 by SirSengir + * + * This work is licensed under a Creative Commons Attribution-NonCommercial-NoDerivs 3.0 Unported License. + * + * To view a copy of this license, visit http://creativecommons.org/licenses/by-nc-nd/3.0/. + ******************************************************************************/ +package forestry.api.apiculture; + +import forestry.api.core.INBTTagable; +import forestry.api.genetics.IEffectData; + +public interface IBeekeepingLogic extends INBTTagable { + + /* STATE INFORMATION */ + int getBreedingTime(); + + int getTotalBreedingTime(); + + IBee getQueen(); + + IBeeHousing getHousing(); + + IEffectData[] getEffectData(); + + /* UPDATING */ + void update(); + +} diff --git a/forestry_common/core/forestry/api/apiculture/IBeekeepingMode.java b/forestry_common/core/forestry/api/apiculture/IBeekeepingMode.java new file mode 100755 index 000000000..d9545a720 --- /dev/null +++ b/forestry_common/core/forestry/api/apiculture/IBeekeepingMode.java @@ -0,0 +1,72 @@ +/******************************************************************************* + * Copyright 2011-2014 by SirSengir + * + * This work is licensed under a Creative Commons Attribution-NonCommercial-NoDerivs 3.0 Unported License. + * + * To view a copy of this license, visit http://creativecommons.org/licenses/by-nc-nd/3.0/. + ******************************************************************************/ +package forestry.api.apiculture; + +import java.util.ArrayList; + +import net.minecraft.world.World; + +public interface IBeekeepingMode extends IBeeModifier { + + /** + * @return Localized name of this beekeeping mode. + */ + String getName(); + + /** + * @return Localized list of strings outlining the behaviour of this beekeeping mode. + */ + ArrayList getDescription(); + + /** + * @return Float used to modify the wear on comb frames. + */ + float getWearModifier(); + + /** + * @param queen + * @return fertility taking into account the birthing queen and surroundings. + */ + int getFinalFertility(IBee queen, World world, int x, int y, int z); + + /** + * @param queen + * @return true if the queen is genetically "fatigued" and should not be reproduced anymore. + */ + boolean isFatigued(IBee queen, IBeeHousing housing); + + /** + * @param queen + * @param housing + * @return true if the queen is being overworked in the bee housing (with chance). will trigger a negative effect. + */ + boolean isOverworked(IBee queen, IBeeHousing housing); + + /** + * + * @param queen + * @param offspring + * @param housing + * @return true if the genetic structure of the queen is breaking down during spawning of the offspring (with chance). will trigger a negative effect. + */ + boolean isDegenerating(IBee queen, IBee offspring, IBeeHousing housing); + + /** + * @param queen + * @return true if an offspring of this queen is considered a natural + */ + boolean isNaturalOffspring(IBee queen); + + /** + * @param queen + * @return true if this mode allows the passed queen or princess to be multiplied + */ + boolean mayMultiplyPrincess(IBee queen); + + +} diff --git a/forestry_common/core/forestry/api/apiculture/IHiveDrop.java b/forestry_common/core/forestry/api/apiculture/IHiveDrop.java new file mode 100755 index 000000000..95e6d467d --- /dev/null +++ b/forestry_common/core/forestry/api/apiculture/IHiveDrop.java @@ -0,0 +1,40 @@ +/******************************************************************************* + * Copyright 2011-2014 by SirSengir + * + * This work is licensed under a Creative Commons Attribution-NonCommercial-NoDerivs 3.0 Unported License. + * + * To view a copy of this license, visit http://creativecommons.org/licenses/by-nc-nd/3.0/. + ******************************************************************************/ +package forestry.api.apiculture; + +import java.util.Collection; + +import net.minecraft.item.ItemStack; +import net.minecraft.world.World; + +/** + * Bees can be seeded either as hive drops or as mutation results. + * + * Add IHiveDrops to BeeManager.hiveDrops + * + * @author SirSengir + */ +public interface IHiveDrop { + + ItemStack getPrincess(World world, int x, int y, int z, int fortune); + + Collection getDrones(World world, int x, int y, int z, int fortune); + + Collection getAdditional(World world, int x, int y, int z, int fortune); + + /** + * Chance to drop. Default drops have 80 (= 80 %). + * + * @param world Minecraft world this is called for. + * @param x x-Coordinate of the broken hive. + * @param y y-Coordinate of the broken hive. + * @param z z-Coordinate of the broken hive. + * @return Chance for drop as an integer of 0 - 100. + */ + int getChance(World world, int x, int y, int z); +} diff --git a/forestry_common/core/forestry/api/apiculture/IHiveFrame.java b/forestry_common/core/forestry/api/apiculture/IHiveFrame.java new file mode 100755 index 000000000..f1f6d3082 --- /dev/null +++ b/forestry_common/core/forestry/api/apiculture/IHiveFrame.java @@ -0,0 +1,29 @@ +/******************************************************************************* + * Copyright 2011-2014 by SirSengir + * + * This work is licensed under a Creative Commons Attribution-NonCommercial-NoDerivs 3.0 Unported License. + * + * To view a copy of this license, visit http://creativecommons.org/licenses/by-nc-nd/3.0/. + ******************************************************************************/ +package forestry.api.apiculture; + +import net.minecraft.item.ItemStack; + +public interface IHiveFrame extends IBeeModifier { + + /** + * Wears out a frame. + * + * @param housing + * IBeeHousing the frame is contained in. + * @param frame + * ItemStack containing the actual frame. + * @param queen + * Current queen in the caller. + * @param wear + * Integer denoting the amount worn out. The wear modifier of the current beekeeping mode has already been taken into account. + * @return ItemStack containing the actual frame with adjusted damage. + */ + ItemStack frameUsed(IBeeHousing housing, ItemStack frame, IBee queen, int wear); + +} diff --git a/forestry_common/core/forestry/api/apiculture/package-info.java b/forestry_common/core/forestry/api/apiculture/package-info.java new file mode 100755 index 000000000..38dfe392f --- /dev/null +++ b/forestry_common/core/forestry/api/apiculture/package-info.java @@ -0,0 +1,10 @@ +/******************************************************************************* + * Copyright 2011-2014 by SirSengir + * + * This work is licensed under a Creative Commons Attribution-NonCommercial-NoDerivs 3.0 Unported License. + * + * To view a copy of this license, visit http://creativecommons.org/licenses/by-nc-nd/3.0/. + ******************************************************************************/ +@API(apiVersion="1.0", owner="ForestryAPI|core", provides="ForestryAPI|apiculture") +package forestry.api.apiculture; +import cpw.mods.fml.common.API; diff --git a/forestry_common/core/forestry/api/arboriculture/EnumGermlingType.java b/forestry_common/core/forestry/api/arboriculture/EnumGermlingType.java new file mode 100755 index 000000000..bf7244881 --- /dev/null +++ b/forestry_common/core/forestry/api/arboriculture/EnumGermlingType.java @@ -0,0 +1,25 @@ +/******************************************************************************* + * Copyright 2011-2014 by SirSengir + * + * This work is licensed under a Creative Commons Attribution-NonCommercial-NoDerivs 3.0 Unported License. + * + * To view a copy of this license, visit http://creativecommons.org/licenses/by-nc-nd/3.0/. + ******************************************************************************/ +package forestry.api.arboriculture; + +public enum EnumGermlingType { + SAPLING("Sapling"), BLOSSOM("Blossom"), POLLEN("Pollen"), GERMLING("Germling"), NONE("None"); + + public static final EnumGermlingType[] VALUES = values(); + + String name; + + private EnumGermlingType(String name) { + this.name = name; + } + + public String getName() { + return name; + } + +} diff --git a/forestry_common/core/forestry/api/arboriculture/EnumGrowthConditions.java b/forestry_common/core/forestry/api/arboriculture/EnumGrowthConditions.java new file mode 100755 index 000000000..fdb1bb6c7 --- /dev/null +++ b/forestry_common/core/forestry/api/arboriculture/EnumGrowthConditions.java @@ -0,0 +1,12 @@ +/******************************************************************************* + * Copyright 2011-2014 by SirSengir + * + * This work is licensed under a Creative Commons Attribution-NonCommercial-NoDerivs 3.0 Unported License. + * + * To view a copy of this license, visit http://creativecommons.org/licenses/by-nc-nd/3.0/. + ******************************************************************************/ +package forestry.api.arboriculture; + +public enum EnumGrowthConditions { + HOSTILE, PALTRY, NORMAL, GOOD, EXCELLENT +} diff --git a/forestry_common/core/forestry/api/arboriculture/EnumTreeChromosome.java b/forestry_common/core/forestry/api/arboriculture/EnumTreeChromosome.java new file mode 100755 index 000000000..6478353db --- /dev/null +++ b/forestry_common/core/forestry/api/arboriculture/EnumTreeChromosome.java @@ -0,0 +1,94 @@ +/******************************************************************************* + * Copyright 2011-2014 by SirSengir + * + * This work is licensed under a Creative Commons Attribution-NonCommercial-NoDerivs 3.0 Unported License. + * + * To view a copy of this license, visit http://creativecommons.org/licenses/by-nc-nd/3.0/. + ******************************************************************************/ +package forestry.api.arboriculture; + +import net.minecraftforge.common.EnumPlantType; + +import forestry.api.genetics.AlleleManager; +import forestry.api.genetics.IAllele; +import forestry.api.genetics.IAlleleArea; +import forestry.api.genetics.IAlleleFloat; +import forestry.api.genetics.IAlleleInteger; +import forestry.api.genetics.IAllelePlantType; +import forestry.api.genetics.IChromosomeType; +import forestry.api.genetics.IFruitFamily; +import forestry.api.genetics.ISpeciesRoot; + +public enum EnumTreeChromosome implements IChromosomeType { + + /** + * Determines the following: - WorldGen, including the used wood blocks - {@link IFruitFamily}s supported. Limits which {@link IFruitProvider} + * will actually yield fruit with this species. - Native {@link EnumPlantType} for this tree. Combines with the PLANT chromosome. + */ + SPECIES(IAlleleTreeSpecies.class), + /** + * {@link IGrowthProvider}, determines conditions required by the tree to grow. + */ + GROWTH(IAlleleGrowth.class), + /** + * A float modifying the height of the tree. Taken into account at worldgen. + */ + HEIGHT(IAlleleFloat.class), + /** + * Chance for saplings. + */ + FERTILITY(IAlleleFloat.class), + /** + * {@link IFruitProvider}, determines if and what fruits are grown on the tree. Limited by the {@link IFruitFamily}s the species supports. + */ + FRUITS(IAlleleFruit.class), + /** + * Chance for fruit leaves and/or drops. + */ + YIELD(IAlleleFloat.class), + /** + * May add additional tolerances for {@link EnumPlantTypes}. + */ + PLANT(IAllelePlantType.class), + /** + * Determines the speed at which fruit will ripen on this tree. + */ + SAPPINESS(IAlleleFloat.class), + /** + * Territory for leaf effects. Unused. + */ + TERRITORY(IAlleleArea.class), + /** + * Leaf effect. Unused. + */ + EFFECT(IAlleleLeafEffect.class), + /** + * Amount of random ticks which need to elapse before a sapling will grow into a tree. + */ + MATURATION(IAlleleInteger.class), + + GIRTH(IAlleleInteger.class), + ; + + Class clss; + + EnumTreeChromosome(Class clss) { + this.clss = clss; + } + + @Override + public Class getAlleleClass() { + return clss; + } + + @Override + public String getName() { + return this.toString().toLowerCase(); + } + + @Override + public ISpeciesRoot getSpeciesRoot() { + return AlleleManager.alleleRegistry.getSpeciesRoot("rootTrees"); + } + +} diff --git a/forestry_common/core/forestry/api/arboriculture/IAlleleFruit.java b/forestry_common/core/forestry/api/arboriculture/IAlleleFruit.java new file mode 100755 index 000000000..00e96bf83 --- /dev/null +++ b/forestry_common/core/forestry/api/arboriculture/IAlleleFruit.java @@ -0,0 +1,19 @@ +/******************************************************************************* + * Copyright 2011-2014 by SirSengir + * + * This work is licensed under a Creative Commons Attribution-NonCommercial-NoDerivs 3.0 Unported License. + * + * To view a copy of this license, visit http://creativecommons.org/licenses/by-nc-nd/3.0/. + ******************************************************************************/ +package forestry.api.arboriculture; + +import forestry.api.genetics.IAllele; + +/** + * Simple allele encapsulating an {@link IFruitProvider}. + */ +public interface IAlleleFruit extends IAllele { + + IFruitProvider getProvider(); + +} diff --git a/forestry_common/core/forestry/api/arboriculture/IAlleleGrowth.java b/forestry_common/core/forestry/api/arboriculture/IAlleleGrowth.java new file mode 100755 index 000000000..63704d3f5 --- /dev/null +++ b/forestry_common/core/forestry/api/arboriculture/IAlleleGrowth.java @@ -0,0 +1,19 @@ +/******************************************************************************* + * Copyright 2011-2014 by SirSengir + * + * This work is licensed under a Creative Commons Attribution-NonCommercial-NoDerivs 3.0 Unported License. + * + * To view a copy of this license, visit http://creativecommons.org/licenses/by-nc-nd/3.0/. + ******************************************************************************/ +package forestry.api.arboriculture; + +import forestry.api.genetics.IAllele; + +/** + * Simple allele encapsulating an {@link IGrowthProvider}. + */ +public interface IAlleleGrowth extends IAllele { + + IGrowthProvider getProvider(); + +} diff --git a/forestry_common/core/forestry/api/arboriculture/IAlleleLeafEffect.java b/forestry_common/core/forestry/api/arboriculture/IAlleleLeafEffect.java new file mode 100755 index 000000000..8ecd3fe1f --- /dev/null +++ b/forestry_common/core/forestry/api/arboriculture/IAlleleLeafEffect.java @@ -0,0 +1,22 @@ +/******************************************************************************* + * Copyright 2011-2014 by SirSengir + * + * This work is licensed under a Creative Commons Attribution-NonCommercial-NoDerivs 3.0 Unported License. + * + * To view a copy of this license, visit http://creativecommons.org/licenses/by-nc-nd/3.0/. + ******************************************************************************/ +package forestry.api.arboriculture; + +import net.minecraft.world.World; + +import forestry.api.genetics.IAlleleEffect; +import forestry.api.genetics.IEffectData; + +/** + * Simple allele encapsulating a leaf effect. (Not implemented) + */ +public interface IAlleleLeafEffect extends IAlleleEffect { + + IEffectData doEffect(ITreeGenome genome, IEffectData storedData, World world, int x, int y, int z); + +} diff --git a/forestry_common/core/forestry/api/arboriculture/IAlleleTreeSpecies.java b/forestry_common/core/forestry/api/arboriculture/IAlleleTreeSpecies.java new file mode 100755 index 000000000..624e1a409 --- /dev/null +++ b/forestry_common/core/forestry/api/arboriculture/IAlleleTreeSpecies.java @@ -0,0 +1,77 @@ +/******************************************************************************* + * Copyright 2011-2014 by SirSengir + * + * This work is licensed under a Creative Commons Attribution-NonCommercial-NoDerivs 3.0 Unported License. + * + * To view a copy of this license, visit http://creativecommons.org/licenses/by-nc-nd/3.0/. + ******************************************************************************/ +package forestry.api.arboriculture; + +import java.util.Collection; + +import net.minecraft.item.ItemStack; +import net.minecraft.util.IIcon; +import net.minecraft.world.World; +import net.minecraft.world.gen.feature.WorldGenerator; + +import cpw.mods.fml.relauncher.Side; +import cpw.mods.fml.relauncher.SideOnly; + +import net.minecraftforge.common.EnumPlantType; + +import forestry.api.genetics.IAlleleSpecies; +import forestry.api.genetics.IFruitFamily; + +public interface IAlleleTreeSpecies extends IAlleleSpecies { + + ITreeRoot getRoot(); + + /** + * @return Native plant type of this species. + */ + EnumPlantType getPlantType(); + + /** + * @return List of all {@link IFruitFamily}s which can grow on leaves generated by this species. + */ + Collection getSuitableFruit(); + + /** + * @return Trunk girth. 1 = 1x1, 2 = 2x2, etc. + */ + @Deprecated + int getGirth(); + + /** + * @param tree + * @param world + * @param x + * @param y + * @param z + * @return Tree generator for the tree at the given location. + */ + WorldGenerator getGenerator(ITree tree, World world, int x, int y, int z); + + /** + * @return All available generator classes for this species. + */ + Class[] getGeneratorClasses(); + + /* TEXTURES AND OVERRIDES */ + int getLeafColour(ITree tree); + + short getLeafIconIndex(ITree tree, boolean fancy); + + @SideOnly(Side.CLIENT) + IIcon getGermlingIcon(EnumGermlingType type, int renderPass); + + @SideOnly(Side.CLIENT) + int getGermlingColour(EnumGermlingType type, int renderPass); + + /** + * + * @return Array of ItemStacks representing logs that these tree produces, the first one being the primary one + */ + ItemStack[] getLogStacks(); + +} diff --git a/forestry_common/core/forestry/api/arboriculture/IArboristTracker.java b/forestry_common/core/forestry/api/arboriculture/IArboristTracker.java new file mode 100755 index 000000000..a0b8ed7ac --- /dev/null +++ b/forestry_common/core/forestry/api/arboriculture/IArboristTracker.java @@ -0,0 +1,14 @@ +/******************************************************************************* + * Copyright 2011-2014 by SirSengir + * + * This work is licensed under a Creative Commons Attribution-NonCommercial-NoDerivs 3.0 Unported License. + * + * To view a copy of this license, visit http://creativecommons.org/licenses/by-nc-nd/3.0/. + ******************************************************************************/ +package forestry.api.arboriculture; + +import forestry.api.genetics.IBreedingTracker; + +public interface IArboristTracker extends IBreedingTracker { + +} diff --git a/forestry_common/core/forestry/api/arboriculture/IFruitProvider.java b/forestry_common/core/forestry/api/arboriculture/IFruitProvider.java new file mode 100755 index 000000000..a8c6e62ca --- /dev/null +++ b/forestry_common/core/forestry/api/arboriculture/IFruitProvider.java @@ -0,0 +1,76 @@ +/******************************************************************************* + * Copyright 2011-2014 by SirSengir + * + * This work is licensed under a Creative Commons Attribution-NonCommercial-NoDerivs 3.0 Unported License. + * + * To view a copy of this license, visit http://creativecommons.org/licenses/by-nc-nd/3.0/. + ******************************************************************************/ +package forestry.api.arboriculture; + +import net.minecraft.client.renderer.texture.IIconRegister; +import net.minecraft.item.ItemStack; +import net.minecraft.world.IBlockAccess; +import net.minecraft.world.World; + +import cpw.mods.fml.relauncher.Side; +import cpw.mods.fml.relauncher.SideOnly; + +import forestry.api.genetics.IFruitFamily; + +public interface IFruitProvider { + + IFruitFamily getFamily(); + + int getColour(ITreeGenome genome, IBlockAccess world, int x, int y, int z, int ripeningTime); + + boolean markAsFruitLeaf(ITreeGenome genome, World world, int x, int y, int z); + + int getRipeningPeriod(); + + // / Products, Chance + ItemStack[] getProducts(); + + // / Specialty, Chance + ItemStack[] getSpecialty(); + + ItemStack[] getFruits(ITreeGenome genome, World world, int x, int y, int z, int ripeningTime); + + /** + * @return Short, human-readable identifier used in the treealyzer. + */ + String getDescription(); + + /* TEXTURE OVERLAY */ + /** + * @param genome + * @param world + * @param x + * @param y + * @param z + * @param ripeningTime + * Elapsed ripening time for the fruit. + * @param fancy + * @return IIcon index of the texture to overlay on the leaf block. + */ + short getIconIndex(ITreeGenome genome, IBlockAccess world, int x, int y, int z, int ripeningTime, boolean fancy); + + /** + * @return true if this fruit provider requires fruit blocks to spawn, false otherwise. + */ + boolean requiresFruitBlocks(); + + /** + * Tries to spawn a fruit block at the potential position when the tree generates. + * + * @param genome + * @param world + * @param x + * @param y + * @param z + * @return true if a fruit block was spawned, false otherwise. + */ + boolean trySpawnFruitBlock(ITreeGenome genome, World world, int x, int y, int z); + + @SideOnly(Side.CLIENT) + void registerIcons(IIconRegister register); +} diff --git a/forestry_common/core/forestry/api/arboriculture/IGrowthProvider.java b/forestry_common/core/forestry/api/arboriculture/IGrowthProvider.java new file mode 100755 index 000000000..74f02d631 --- /dev/null +++ b/forestry_common/core/forestry/api/arboriculture/IGrowthProvider.java @@ -0,0 +1,40 @@ +/******************************************************************************* + * Copyright 2011-2014 by SirSengir + * + * This work is licensed under a Creative Commons Attribution-NonCommercial-NoDerivs 3.0 Unported License. + * + * To view a copy of this license, visit http://creativecommons.org/licenses/by-nc-nd/3.0/. + ******************************************************************************/ +package forestry.api.arboriculture; + +import net.minecraft.world.World; + +public interface IGrowthProvider { + + /** + * Check to see whether a sapling at the given location with the given genome can grow into a tree. + * + * @param genome Genome of the tree this is called for. + * @param world Minecraft world the tree will inhabit. + * @param xPos x-Coordinate to attempt growth at. + * @param yPos y-Coordinate to attempt growth at. + * @param zPos z-Coordinate to attempt growth at. + * @param expectedGirth Trunk size of the tree to generate. + * @param expectedHeight Height of the tree to generate. + * @return true if the tree can grow at the given coordinates, false otherwise. + */ + boolean canGrow(ITreeGenome genome, World world, int xPos, int yPos, int zPos, int expectedGirth, int expectedHeight); + + EnumGrowthConditions getGrowthConditions(ITreeGenome genome, World world, int xPos, int yPos, int zPos); + + /** + * @return Short, human-readable identifier used in the treealyzer. + */ + String getDescription(); + + /** + * @return Detailed description of growth behaviour used in the treealyzer. + */ + String[] getInfo(); + +} diff --git a/forestry_common/core/forestry/api/arboriculture/ILeafTickHandler.java b/forestry_common/core/forestry/api/arboriculture/ILeafTickHandler.java new file mode 100755 index 000000000..4711e1b7d --- /dev/null +++ b/forestry_common/core/forestry/api/arboriculture/ILeafTickHandler.java @@ -0,0 +1,14 @@ +/******************************************************************************* + * Copyright 2011-2014 by SirSengir + * + * This work is licensed under a Creative Commons Attribution-NonCommercial-NoDerivs 3.0 Unported License. + * + * To view a copy of this license, visit http://creativecommons.org/licenses/by-nc-nd/3.0/. + ******************************************************************************/ +package forestry.api.arboriculture; + +import net.minecraft.world.World; + +public interface ILeafTickHandler { + boolean onRandomLeafTick(ITree tree, World world, int biomeId, int x, int y, int z, boolean isDestroyed); +} diff --git a/forestry_common/core/forestry/api/arboriculture/IToolGrafter.java b/forestry_common/core/forestry/api/arboriculture/IToolGrafter.java new file mode 100755 index 000000000..9c3f51c3f --- /dev/null +++ b/forestry_common/core/forestry/api/arboriculture/IToolGrafter.java @@ -0,0 +1,26 @@ +/******************************************************************************* + * Copyright 2011-2014 by SirSengir + * + * This work is licensed under a Creative Commons Attribution-NonCommercial-NoDerivs 3.0 Unported License. + * + * To view a copy of this license, visit http://creativecommons.org/licenses/by-nc-nd/3.0/. + ******************************************************************************/ +package forestry.api.arboriculture; + +import net.minecraft.entity.player.EntityPlayer; +import net.minecraft.item.ItemStack; +import net.minecraft.world.World; + +public interface IToolGrafter { + /** + * Called by leaves to determine the increase in sapling droprate. + * + * @param stack ItemStack containing the grafter. + * @param world Minecraft world the player and the target block inhabit. + * @param x x-Coordinate of the broken leaf block. + * @param y y-Coordinate of the broken leaf block. + * @param z z-Coordinate of the broken leaf block. + * @return Float representing the factor the usual drop chance is to be multiplied by. + */ + float getSaplingModifier(ItemStack stack, World world, EntityPlayer player, int x, int y, int z); +} diff --git a/forestry_common/core/forestry/api/arboriculture/ITree.java b/forestry_common/core/forestry/api/arboriculture/ITree.java new file mode 100755 index 000000000..3a492eb9f --- /dev/null +++ b/forestry_common/core/forestry/api/arboriculture/ITree.java @@ -0,0 +1,101 @@ +/******************************************************************************* + * Copyright 2011-2014 by SirSengir + * + * This work is licensed under a Creative Commons Attribution-NonCommercial-NoDerivs 3.0 Unported License. + * + * To view a copy of this license, visit http://creativecommons.org/licenses/by-nc-nd/3.0/. + ******************************************************************************/ +package forestry.api.arboriculture; + +import java.util.EnumSet; + +import net.minecraft.item.ItemStack; +import net.minecraft.world.World; +import net.minecraft.world.gen.feature.WorldGenerator; + +import net.minecraftforge.common.EnumPlantType; + +import forestry.api.genetics.IEffectData; +import forestry.api.genetics.IIndividual; + +public interface ITree extends IIndividual { + + void mate(ITree other); + + IEffectData[] doEffect(IEffectData[] storedData, World world, int biomeid, int x, int y, int z); + + IEffectData[] doFX(IEffectData[] storedData, World world, int biomeid, int x, int y, int z); + + ITreeGenome getGenome(); + + ITreeGenome getMate(); + + EnumSet getPlantTypes(); + + ITree[] getSaplings(World world, int x, int y, int z, float modifier); + + ItemStack[] getProduceList(); + + ItemStack[] getSpecialtyList(); + + ItemStack[] produceStacks(World world, int x, int y, int z, int ripeningTime); + + /** + * + * @param world + * @param x + * @param y + * @param z + * @return Boolean indicating whether a sapling can stay planted at the given position. + */ + boolean canStay(World world, int x, int y, int z); + + /** + * + * @param world + * @param x + * @param y + * @param z + * @return Boolean indicating whether a sapling at the given position can grow into a tree. + */ + boolean canGrow(World world, int x, int y, int z, int expectedGirth, int expectedHeight); + + /** + * @return Integer denoting the maturity (block ticks) required for a sapling to attempt to grow into a tree. + */ + int getRequiredMaturity(); + + /** + * @return Integer denoting how resilient leaf blocks are against adverse influences (i.e. caterpillars). + */ + int getResilience(); + + /** + * @param world + * @param x + * @param y + * @param z + * @return Integer denoting the size of the tree trunk. + */ + int getGirth(World world, int x, int y, int z); + + + + /** + * + * @param world + * @param x + * @param y + * @param z + * @return Growth conditions at the given position. + */ + EnumGrowthConditions getGrowthCondition(World world, int x, int y, int z); + + WorldGenerator getTreeGenerator(World world, int x, int y, int z, boolean wasBonemealed); + + ITree copy(); + + boolean isPureBred(EnumTreeChromosome chromosome); + + boolean canBearFruit(); +} diff --git a/forestry_common/core/forestry/api/arboriculture/ITreeGenome.java b/forestry_common/core/forestry/api/arboriculture/ITreeGenome.java new file mode 100755 index 000000000..971307506 --- /dev/null +++ b/forestry_common/core/forestry/api/arboriculture/ITreeGenome.java @@ -0,0 +1,48 @@ +/******************************************************************************* + * Copyright 2011-2014 by SirSengir + * + * This work is licensed under a Creative Commons Attribution-NonCommercial-NoDerivs 3.0 Unported License. + * + * To view a copy of this license, visit http://creativecommons.org/licenses/by-nc-nd/3.0/. + ******************************************************************************/ +package forestry.api.arboriculture; + +import java.util.EnumSet; + +import net.minecraftforge.common.EnumPlantType; + +import forestry.api.genetics.IGenome; + +public interface ITreeGenome extends IGenome { + + IAlleleTreeSpecies getPrimary(); + + IAlleleTreeSpecies getSecondary(); + + IFruitProvider getFruitProvider(); + + IGrowthProvider getGrowthProvider(); + + float getHeight(); + + float getFertility(); + + /** + * @return Determines either a) how many fruit leaves there are or b) the chance for any fruit leave to drop a sapling. Exact usage determined by the + * IFruitProvider + */ + float getYield(); + + float getSappiness(); + + EnumSet getPlantTypes(); + + /** + * @return Amount of random block ticks required for a sapling to mature into a fully grown tree. + */ + int getMaturationTime(); + + int getGirth(); + + IAlleleLeafEffect getEffect(); +} diff --git a/forestry_common/core/forestry/api/arboriculture/ITreeModifier.java b/forestry_common/core/forestry/api/arboriculture/ITreeModifier.java new file mode 100755 index 000000000..9eb559070 --- /dev/null +++ b/forestry_common/core/forestry/api/arboriculture/ITreeModifier.java @@ -0,0 +1,47 @@ +/******************************************************************************* + * Copyright 2011-2014 by SirSengir + * + * This work is licensed under a Creative Commons Attribution-NonCommercial-NoDerivs 3.0 Unported License. + * + * To view a copy of this license, visit http://creativecommons.org/licenses/by-nc-nd/3.0/. + ******************************************************************************/ +package forestry.api.arboriculture; + +public interface ITreeModifier { + + /** + * + * @param genome + * @return Float used to modify the height. + */ + float getHeightModifier(ITreeGenome genome, float currentModifier); + + /** + * + * @param genome + * @return Float used to modify the yield. + */ + float getYieldModifier(ITreeGenome genome, float currentModifier); + + /** + * + * @param genome + * @return Float used to modify the sappiness. + */ + float getSappinessModifier(ITreeGenome genome, float currentModifier); + + /** + * + * @param genome + * @return Float used to modify the maturation. + */ + float getMaturationModifier(ITreeGenome genome, float currentModifier); + + /** + * @param genome0 + * @param genome1 + * @return Float used to modify the base mutation chance. + */ + float getMutationModifier(ITreeGenome genome0, ITreeGenome genome1, float currentModifier); + +} diff --git a/forestry_common/core/forestry/api/arboriculture/ITreeMutation.java b/forestry_common/core/forestry/api/arboriculture/ITreeMutation.java new file mode 100755 index 000000000..1c0e3b7d4 --- /dev/null +++ b/forestry_common/core/forestry/api/arboriculture/ITreeMutation.java @@ -0,0 +1,36 @@ +/******************************************************************************* + * Copyright 2011-2014 by SirSengir + * + * This work is licensed under a Creative Commons Attribution-NonCommercial-NoDerivs 3.0 Unported License. + * + * To view a copy of this license, visit http://creativecommons.org/licenses/by-nc-nd/3.0/. + ******************************************************************************/ +package forestry.api.arboriculture; + +import net.minecraft.world.World; + +import forestry.api.genetics.IAllele; +import forestry.api.genetics.IGenome; +import forestry.api.genetics.IMutation; +import forestry.api.genetics.ISpeciesRoot; + +public interface ITreeMutation extends IMutation { + + /** + * @return {@link ISpeciesRoot} this mutation is associated with. + */ + ITreeRoot getRoot(); + + /** + * @param world + * @param x + * @param y + * @param z + * @param allele0 + * @param allele1 + * @param genome0 + * @param genome1 + * @return float representing the chance for mutation to occur. note that this is 0 - 100 based, since it was an integer previously! + */ + float getChance(World world, int x, int y, int z, IAllele allele0, IAllele allele1, IGenome genome0, IGenome genome1); +} diff --git a/forestry_common/core/forestry/api/arboriculture/ITreeRoot.java b/forestry_common/core/forestry/api/arboriculture/ITreeRoot.java new file mode 100755 index 000000000..02ede2c61 --- /dev/null +++ b/forestry_common/core/forestry/api/arboriculture/ITreeRoot.java @@ -0,0 +1,85 @@ +/******************************************************************************* + * Copyright 2011-2014 by SirSengir + * + * This work is licensed under a Creative Commons Attribution-NonCommercial-NoDerivs 3.0 Unported License. + * + * To view a copy of this license, visit http://creativecommons.org/licenses/by-nc-nd/3.0/. + ******************************************************************************/ +package forestry.api.arboriculture; + +import java.util.ArrayList; +import java.util.Collection; + +import net.minecraft.item.ItemStack; +import net.minecraft.nbt.NBTTagCompound; +import net.minecraft.world.World; + +import forestry.api.genetics.IAllele; +import forestry.api.genetics.IChromosome; +import forestry.api.genetics.IIndividual; +import forestry.api.genetics.ISpeciesRoot; + +public interface ITreeRoot extends ISpeciesRoot { + + boolean isMember(ItemStack itemstack); + + ITree getMember(ItemStack itemstack); + + ITree getMember(NBTTagCompound compound); + + ITreeGenome templateAsGenome(IAllele[] template); + + ITreeGenome templateAsGenome(IAllele[] templateActive, IAllele[] templateInactive); + + /** + * @param world + * @return {@link IArboristTracker} associated with the passed world. + */ + IArboristTracker getBreedingTracker(World world, String player); + + /* TREE SPECIFIC */ + /** + * Register a leaf tick handler. + * @param handler the {@link ILeafTickHandler} to register. + */ + void registerLeafTickHandler(ILeafTickHandler handler); + + Collection getLeafTickHandlers(); + + /** + * @return type of tree encoded on the itemstack. EnumBeeType.NONE if it isn't a tree. + */ + EnumGermlingType getType(ItemStack stack); + + ITree getTree(World world, int x, int y, int z); + + ITree getTree(World world, ITreeGenome genome); + + boolean plantSapling(World world, ITree tree, String owner, int x, int y, int z); + + boolean setLeaves(World world, IIndividual tree, String owner, int x, int y, int z); + + IChromosome[] templateAsChromosomes(IAllele[] template); + + IChromosome[] templateAsChromosomes(IAllele[] templateActive, IAllele[] templateInactive); + + boolean setFruitBlock(World world, IAlleleFruit allele, float sappiness, short[] indices, int x, int y, int z); + + /* GAME MODE */ + ArrayList getTreekeepingModes(); + + ITreekeepingMode getTreekeepingMode(World world); + + ITreekeepingMode getTreekeepingMode(String name); + + void registerTreekeepingMode(ITreekeepingMode mode); + + void setTreekeepingMode(World world, String name); + + /* TEMPLATES */ + ArrayList getIndividualTemplates(); + + /* MUTATIONS */ + Collection getMutations(boolean shuffle); + +} diff --git a/forestry_common/core/forestry/api/arboriculture/ITreekeepingMode.java b/forestry_common/core/forestry/api/arboriculture/ITreekeepingMode.java new file mode 100755 index 000000000..99980ccc0 --- /dev/null +++ b/forestry_common/core/forestry/api/arboriculture/ITreekeepingMode.java @@ -0,0 +1,24 @@ +/******************************************************************************* + * Copyright 2011-2014 by SirSengir + * + * This work is licensed under a Creative Commons Attribution-NonCommercial-NoDerivs 3.0 Unported License. + * + * To view a copy of this license, visit http://creativecommons.org/licenses/by-nc-nd/3.0/. + ******************************************************************************/ +package forestry.api.arboriculture; + +import java.util.ArrayList; + +public interface ITreekeepingMode extends ITreeModifier { + + /** + * @return Localized name of this treekeeping mode. + */ + String getName(); + + /** + * @return Localized list of strings outlining the behaviour of this treekeeping mode. + */ + ArrayList getDescription(); + +} diff --git a/forestry_common/core/forestry/api/arboriculture/TreeManager.java b/forestry_common/core/forestry/api/arboriculture/TreeManager.java new file mode 100755 index 000000000..e10c02702 --- /dev/null +++ b/forestry_common/core/forestry/api/arboriculture/TreeManager.java @@ -0,0 +1,18 @@ +/******************************************************************************* + * Copyright 2011-2014 by SirSengir + * + * This work is licensed under a Creative Commons Attribution-NonCommercial-NoDerivs 3.0 Unported License. + * + * To view a copy of this license, visit http://creativecommons.org/licenses/by-nc-nd/3.0/. + ******************************************************************************/ +package forestry.api.arboriculture; + +public class TreeManager { + public static int treeSpeciesCount = 0; + + /** + * Get your own reference to this via AlleleManager.alleleRegistry.getSpeciesRoot("rootTrees") and save it somewhere. + */ + @Deprecated + public static ITreeRoot treeInterface; +} diff --git a/forestry_common/core/forestry/api/arboriculture/package-info.java b/forestry_common/core/forestry/api/arboriculture/package-info.java new file mode 100755 index 000000000..b20483dc4 --- /dev/null +++ b/forestry_common/core/forestry/api/arboriculture/package-info.java @@ -0,0 +1,10 @@ +/******************************************************************************* + * Copyright 2011-2014 by SirSengir + * + * This work is licensed under a Creative Commons Attribution-NonCommercial-NoDerivs 3.0 Unported License. + * + * To view a copy of this license, visit http://creativecommons.org/licenses/by-nc-nd/3.0/. + ******************************************************************************/ +@API(apiVersion="1.0", owner="ForestryAPI|core", provides="ForestryAPI|arboriculture") +package forestry.api.arboriculture; +import cpw.mods.fml.common.API; diff --git a/forestry_common/core/forestry/api/circuits/ChipsetManager.java b/forestry_common/core/forestry/api/circuits/ChipsetManager.java new file mode 100755 index 000000000..616a40bdd --- /dev/null +++ b/forestry_common/core/forestry/api/circuits/ChipsetManager.java @@ -0,0 +1,15 @@ +/******************************************************************************* + * Copyright 2011-2014 by SirSengir + * + * This work is licensed under a Creative Commons Attribution-NonCommercial-NoDerivs 3.0 Unported License. + * + * To view a copy of this license, visit http://creativecommons.org/licenses/by-nc-nd/3.0/. + ******************************************************************************/ +package forestry.api.circuits; + +public class ChipsetManager { + + public static ISolderManager solderManager; + public static ICircuitRegistry circuitRegistry; + +} diff --git a/forestry_common/core/forestry/api/circuits/ICircuit.java b/forestry_common/core/forestry/api/circuits/ICircuit.java new file mode 100755 index 000000000..84c16539e --- /dev/null +++ b/forestry_common/core/forestry/api/circuits/ICircuit.java @@ -0,0 +1,34 @@ +/******************************************************************************* + * Copyright 2011-2014 by SirSengir + * + * This work is licensed under a Creative Commons Attribution-NonCommercial-NoDerivs 3.0 Unported License. + * + * To view a copy of this license, visit http://creativecommons.org/licenses/by-nc-nd/3.0/. + ******************************************************************************/ +package forestry.api.circuits; + +import java.util.List; + +import net.minecraft.tileentity.TileEntity; + +public interface ICircuit { + String getUID(); + + boolean requiresDiscovery(); + + int getLimit(); + + String getName(); + + boolean isCircuitable(TileEntity tile); + + void onInsertion(int slot, TileEntity tile); + + void onLoad(int slot, TileEntity tile); + + void onRemoval(int slot, TileEntity tile); + + void onTick(int slot, TileEntity tile); + + void addTooltip(List list); +} diff --git a/forestry_common/core/forestry/api/circuits/ICircuitBoard.java b/forestry_common/core/forestry/api/circuits/ICircuitBoard.java new file mode 100755 index 000000000..fd2927202 --- /dev/null +++ b/forestry_common/core/forestry/api/circuits/ICircuitBoard.java @@ -0,0 +1,34 @@ +/******************************************************************************* + * Copyright 2011-2014 by SirSengir + * + * This work is licensed under a Creative Commons Attribution-NonCommercial-NoDerivs 3.0 Unported License. + * + * To view a copy of this license, visit http://creativecommons.org/licenses/by-nc-nd/3.0/. + ******************************************************************************/ +package forestry.api.circuits; + +import java.util.List; + +import net.minecraft.tileentity.TileEntity; + +import forestry.api.core.INBTTagable; + +public interface ICircuitBoard extends INBTTagable { + + int getPrimaryColor(); + + int getSecondaryColor(); + + void addTooltip(List list); + + void onInsertion(TileEntity tile); + + void onLoad(TileEntity tile); + + void onRemoval(TileEntity tile); + + void onTick(TileEntity tile); + + ICircuit[] getCircuits(); + +} diff --git a/forestry_common/core/forestry/api/circuits/ICircuitLayout.java b/forestry_common/core/forestry/api/circuits/ICircuitLayout.java new file mode 100755 index 000000000..02d9ac818 --- /dev/null +++ b/forestry_common/core/forestry/api/circuits/ICircuitLayout.java @@ -0,0 +1,18 @@ +/******************************************************************************* + * Copyright 2011-2014 by SirSengir + * + * This work is licensed under a Creative Commons Attribution-NonCommercial-NoDerivs 3.0 Unported License. + * + * To view a copy of this license, visit http://creativecommons.org/licenses/by-nc-nd/3.0/. + ******************************************************************************/ +package forestry.api.circuits; + +public interface ICircuitLayout { + + String getUID(); + + String getName(); + + String getUsage(); + +} diff --git a/forestry_common/core/forestry/api/circuits/ICircuitLibrary.java b/forestry_common/core/forestry/api/circuits/ICircuitLibrary.java new file mode 100755 index 000000000..73285e708 --- /dev/null +++ b/forestry_common/core/forestry/api/circuits/ICircuitLibrary.java @@ -0,0 +1,12 @@ +/******************************************************************************* + * Copyright 2011-2014 by SirSengir + * + * This work is licensed under a Creative Commons Attribution-NonCommercial-NoDerivs 3.0 Unported License. + * + * To view a copy of this license, visit http://creativecommons.org/licenses/by-nc-nd/3.0/. + ******************************************************************************/ +package forestry.api.circuits; + +public interface ICircuitLibrary { + +} diff --git a/forestry_common/core/forestry/api/circuits/ICircuitRegistry.java b/forestry_common/core/forestry/api/circuits/ICircuitRegistry.java new file mode 100755 index 000000000..178acec1f --- /dev/null +++ b/forestry_common/core/forestry/api/circuits/ICircuitRegistry.java @@ -0,0 +1,44 @@ +/******************************************************************************* + * Copyright 2011-2014 by SirSengir + * + * This work is licensed under a Creative Commons Attribution-NonCommercial-NoDerivs 3.0 Unported License. + * + * To view a copy of this license, visit http://creativecommons.org/licenses/by-nc-nd/3.0/. + ******************************************************************************/ +package forestry.api.circuits; + +import java.util.HashMap; + +import net.minecraft.item.ItemStack; +import net.minecraft.world.World; + +public interface ICircuitRegistry { + + /* CIRCUITS */ + HashMap getRegisteredCircuits(); + + void registerCircuit(ICircuit circuit); + + ICircuit getCircuit(String uid); + + ICircuitLibrary getCircuitLibrary(World world, String playername); + + void registerLegacyMapping(int id, String uid); + + ICircuit getFromLegacyMap(int id); + + /* LAYOUTS */ + HashMap getRegisteredLayouts(); + + void registerLayout(ICircuitLayout layout); + + ICircuitLayout getLayout(String uid); + + ICircuitLayout getDefaultLayout(); + + + ICircuitBoard getCircuitboard(ItemStack itemstack); + + boolean isChipset(ItemStack itemstack); + +} diff --git a/forestry_common/core/forestry/api/circuits/ISolderManager.java b/forestry_common/core/forestry/api/circuits/ISolderManager.java new file mode 100755 index 000000000..5cff49a1c --- /dev/null +++ b/forestry_common/core/forestry/api/circuits/ISolderManager.java @@ -0,0 +1,16 @@ +/******************************************************************************* + * Copyright 2011-2014 by SirSengir + * + * This work is licensed under a Creative Commons Attribution-NonCommercial-NoDerivs 3.0 Unported License. + * + * To view a copy of this license, visit http://creativecommons.org/licenses/by-nc-nd/3.0/. + ******************************************************************************/ +package forestry.api.circuits; + +import net.minecraft.item.ItemStack; + +public interface ISolderManager { + + void addRecipe(ICircuitLayout layout, ItemStack resource, ICircuit circuit); + +} diff --git a/forestry_common/core/forestry/api/circuits/package-info.java b/forestry_common/core/forestry/api/circuits/package-info.java new file mode 100755 index 000000000..4525597fe --- /dev/null +++ b/forestry_common/core/forestry/api/circuits/package-info.java @@ -0,0 +1,10 @@ +/******************************************************************************* + * Copyright 2011-2014 by SirSengir + * + * This work is licensed under a Creative Commons Attribution-NonCommercial-NoDerivs 3.0 Unported License. + * + * To view a copy of this license, visit http://creativecommons.org/licenses/by-nc-nd/3.0/. + ******************************************************************************/ +@API(apiVersion="1.0", owner="ForestryAPI|core", provides="ForestryAPI|circuits") +package forestry.api.circuits; +import cpw.mods.fml.common.API; diff --git a/forestry_common/core/forestry/api/core/BlockInterface.java b/forestry_common/core/forestry/api/core/BlockInterface.java new file mode 100755 index 000000000..7e60d9c51 --- /dev/null +++ b/forestry_common/core/forestry/api/core/BlockInterface.java @@ -0,0 +1,42 @@ +/******************************************************************************* + * Copyright 2011-2014 by SirSengir + * + * This work is licensed under a Creative Commons Attribution-NonCommercial-NoDerivs 3.0 Unported License. + * + * To view a copy of this license, visit http://creativecommons.org/licenses/by-nc-nd/3.0/. + ******************************************************************************/ +package forestry.api.core; + +import net.minecraft.block.Block; +import net.minecraft.item.ItemStack; + +import cpw.mods.fml.common.FMLLog; + +public class BlockInterface { + /** + * Rather limited function to retrieve block ids. + * + * @param ident + * @return ItemStack representing the block. + */ + @Deprecated + public static ItemStack getBlock(String ident) { + ItemStack item = null; + + try { + String pack = ItemInterface.class.getPackage().getName(); + pack = pack.substring(0, pack.lastIndexOf('.')); + String itemClass = pack.substring(0, pack.lastIndexOf('.')) + ".core.config.ForestryBlock"; + Object obj = Class.forName(itemClass).getField(ident).get(null); + if (obj instanceof Block) + item = new ItemStack((Block) obj); + else if (obj instanceof ItemStack) + item = (ItemStack) obj; + } catch (Exception ex) { + FMLLog.warning("Could not retrieve Forestry block identified by: " + ident); + } + + return item; + } + +} diff --git a/forestry_common/core/forestry/api/core/EnumHumidity.java b/forestry_common/core/forestry/api/core/EnumHumidity.java new file mode 100755 index 000000000..6fcea2ff3 --- /dev/null +++ b/forestry_common/core/forestry/api/core/EnumHumidity.java @@ -0,0 +1,79 @@ +/******************************************************************************* + * Copyright 2011-2014 by SirSengir + * + * This work is licensed under a Creative Commons Attribution-NonCommercial-NoDerivs 3.0 Unported License. + * + * To view a copy of this license, visit http://creativecommons.org/licenses/by-nc-nd/3.0/. + ******************************************************************************/ +package forestry.api.core; + +import java.util.ArrayList; + +/** + * Many things Forestry use temperature and humidity of a biome to determine whether they can or how they can work or spawn at a given location. + * + * This enum concerns humidity. + */ +public enum EnumHumidity { + ARID("Arid"), NORMAL("Normal"), DAMP("Damp"); + + /** + * Populated by Forestry with vanilla biomes. Add additional arid biomes here. (ex. desert) + * @deprecated Biomes will be checked live rather than relying on cached values, so you don't have to register them. + */ + @Deprecated + public static ArrayList aridBiomeIds = new ArrayList(); + /** + * Populated by Forestry with vanilla biomes. Add additional damp biomes here. (ex. jungle) + * @deprecated Biomes will be checked live rather than relying on cached values, so you don't have to register them. + */ + @Deprecated + public static ArrayList dampBiomeIds = new ArrayList(); + /** + * Populated by Forestry with vanilla biomes. Add additional normal biomes here. + * @deprecated Biomes will be checked live rather than relying on cached values, so you don't have to register them. + */ + @Deprecated + public static ArrayList normalBiomeIds = new ArrayList(); + + public final String name; + + private EnumHumidity(String name) { + this.name = name; + } + + public String getName() { + return this.name; + } + + @Deprecated + public static ArrayList getBiomeIds(EnumHumidity humidity) { + switch (humidity) { + case ARID: + return aridBiomeIds; + case DAMP: + return dampBiomeIds; + case NORMAL: + default: + return normalBiomeIds; + } + } + + /** + * Determines the EnumHumidity given a floating point representation of Minecraft Rainfall + * @param rawHumidity raw rainfall value + * @return EnumHumidity corresponding to rainfall value + */ + public static EnumHumidity getFromValue(float rawHumidity) { + EnumHumidity value = EnumHumidity.ARID; + + if (rawHumidity >= 0.9f) { + value = EnumHumidity.DAMP; + } + else if (rawHumidity >= 0.3f) { + value = EnumHumidity.NORMAL; + } + + return value; + } +} diff --git a/forestry_common/core/forestry/api/core/EnumTemperature.java b/forestry_common/core/forestry/api/core/EnumTemperature.java new file mode 100755 index 000000000..23b8ebfc7 --- /dev/null +++ b/forestry_common/core/forestry/api/core/EnumTemperature.java @@ -0,0 +1,152 @@ +/******************************************************************************* + * Copyright 2011-2014 by SirSengir + * + * This work is licensed under a Creative Commons Attribution-NonCommercial-NoDerivs 3.0 Unported License. + * + * To view a copy of this license, visit http://creativecommons.org/licenses/by-nc-nd/3.0/. + ******************************************************************************/ +package forestry.api.core; + +import java.util.ArrayList; + +import net.minecraft.util.IIcon; +import net.minecraft.world.biome.BiomeGenBase; + +import cpw.mods.fml.relauncher.Side; +import cpw.mods.fml.relauncher.SideOnly; + +import net.minecraftforge.common.BiomeDictionary; + +/** + * Many things Forestry use temperature and humidity of a biome to determine whether they can or how they can work or spawn at a given location. + * + * This enum concerns temperature. + */ +public enum EnumTemperature { + NONE("None", "habitats/ocean"), ICY("Icy", "habitats/snow"), COLD("Cold", "habitats/taiga"), + NORMAL("Normal", "habitats/plains"), WARM("Warm", "habitats/jungle"), HOT("Hot", "habitats/desert"), HELLISH("Hellish", "habitats/nether"); + + /** + * Populated by Forestry with vanilla biomes. Add additional icy/snow biomes here. (ex. snow plains) + * @deprecated Biomes will be checked live rather than relying on cached values, so you don't have to register them. + */ + @Deprecated + public static ArrayList icyBiomeIds = new ArrayList(); + /** + * Populated by Forestry with vanilla biomes. Add additional cold biomes here. (ex. taiga) + * @deprecated Biomes will be checked live rather than relying on cached values, so you don't have to register them. + */ + @Deprecated + public static ArrayList coldBiomeIds = new ArrayList(); + /** + * Populated by Forestry with vanilla biomes. Add additional normal biomes here. (ex. forest, plains) + * @deprecated Biomes will be checked live rather than relying on cached values, so you don't have to register them. + */ + @Deprecated + public static ArrayList normalBiomeIds = new ArrayList(); + /** + * Populated by Forestry with vanilla biomes. Add additional warm biomes here. (ex. jungle) + * @deprecated Biomes will be checked live rather than relying on cached values, so you don't have to register them. + */ + @Deprecated + public static ArrayList warmBiomeIds = new ArrayList(); + /** + * Populated by Forestry with vanilla biomes. Add additional hot biomes here. (ex. desert) + * @deprecated Biomes will be checked live rather than relying on cached values, so you don't have to register them. + */ + @Deprecated + public static ArrayList hotBiomeIds = new ArrayList(); + /** + * Populated by Forestry with vanilla biomes. Add additional hellish biomes here. (ex. nether) + * @deprecated Biomes will be checked live rather than relying on cached values, so you don't have to register them. + */ + @Deprecated + public static ArrayList hellishBiomeIds = new ArrayList(); + + public final String name; + public final String iconIndex; + + private EnumTemperature(String name, String iconIndex) { + this.name = name; + this.iconIndex = iconIndex; + } + + public String getName() { + return this.name; + } + + @SideOnly(Side.CLIENT) + public IIcon getIcon() { + return ForestryAPI.textureManager.getDefault(iconIndex); + } + /** + * @deprecated Switching most internals to use getFromValue to not rely on cached values. + */ + @Deprecated + public static ArrayList getBiomeIds(EnumTemperature temperature) { + + switch (temperature) { + case ICY: + return icyBiomeIds; + case COLD: + return coldBiomeIds; + case WARM: + return warmBiomeIds; + case HOT: + return hotBiomeIds; + case HELLISH: + return hellishBiomeIds; + case NORMAL: + default: + return normalBiomeIds; + } + + } + + /** + * Determines if a given BiomeGenBase is of HELLISH temperature, since it is treated seperatly from actual temperature values. + * Uses the BiomeDictionary. + * @param biomeGen BiomeGenBase of the biome in question + * @return true, if the BiomeGenBase is a Nether-type biome; false otherwise. + */ + public static boolean isBiomeHellish(BiomeGenBase biomeGen) { + return BiomeDictionary.isBiomeOfType(biomeGen, BiomeDictionary.Type.NETHER); + } + + /** + * Determines if a given biomeID is of HELLISH temperature, since it is treated seperatly from actual temperature values. + * Uses the BiomeDictionary. + * @param biomeID ID of the BiomeGenBase in question + * @return true, if the biomeID is a Nether-type biome; false otherwise. + */ + public static boolean isBiomeHellish(int biomeID) { + return BiomeDictionary.isBiomeRegistered(biomeID) && BiomeDictionary.isBiomeOfType(BiomeGenBase.getBiome(biomeID), BiomeDictionary.Type.NETHER); + } + + /** + * Determines the EnumTemperature given a floating point representation of + * Minecraft temperature. Hellish biomes are handled based on their biome + * type - check isBiomeHellish. + * @param rawTemp raw temperature value + * @return EnumTemperature corresponding to value of rawTemp + */ + public static EnumTemperature getFromValue(float rawTemp) { + EnumTemperature value = EnumTemperature.ICY; + + if (rawTemp >= 2.0f) { + value = EnumTemperature.HOT; + } + else if (rawTemp >= 1.2f) { + value = EnumTemperature.WARM; + } + else if (rawTemp >= 0.2f) { + value = EnumTemperature.NORMAL; + } + else if (rawTemp >= 0.05f) { + value = EnumTemperature.COLD; + } + + return value; + } + +} diff --git a/forestry_common/core/forestry/api/core/ForestryAPI.java b/forestry_common/core/forestry/api/core/ForestryAPI.java new file mode 100755 index 000000000..7374016c5 --- /dev/null +++ b/forestry_common/core/forestry/api/core/ForestryAPI.java @@ -0,0 +1,54 @@ +/******************************************************************************* + * Copyright 2011-2014 by SirSengir + * + * This work is licensed under a Creative Commons Attribution-NonCommercial-NoDerivs 3.0 Unported License. + * + * To view a copy of this license, visit http://creativecommons.org/licenses/by-nc-nd/3.0/. + ******************************************************************************/ +package forestry.api.core; + +import cpw.mods.fml.relauncher.Side; +import cpw.mods.fml.relauncher.SideOnly; + +/** + * Forestry's API is divided into several subcategories to make it easier to understand. + * + * If you need to distribute API files, try to only include the parts you are actually + * using to minimize conflicts due to API changes. + * + * .core - Miscallenous base classes and interfaces as well as some basics for tools, armor, game modes and stuff needed by biome mods. + * .fuels - Managers and classes to facilitate adding fuels to various engines and machines. + * .recipes - Managers and helpers to facilitate adding new recipes to various machines. + * .storage - Managers, events and interfaces for defining new backpacks and handling backpack behaviour. + * .mail - Anything related to handling letters and adding new mail carrier systems. + * .genetics - Shared code for all genetic subclasses. + * \ .apiculture - Bees. + * \ .arboriculture - Trees. + * \ .lepidopterology - Butterflies. + * + * Note that if Forestry is not present, all these references will be null. + */ +public class ForestryAPI { + + /** + * The main mod instance for Forestry. + */ + public static Object instance; + + /** + * A {@link ITextureManager} needed for some things in the API. + */ + @SideOnly(Side.CLIENT) + public static ITextureManager textureManager; + + /** + * The currently active {@link IGameMode}. + */ + public static IGameMode activeMode; + + /** + * Provides information on certain Forestry constants (Villager IDs, Chest gen keys, etc) + */ + public static IForestryConstants forestryConstants; + +} diff --git a/forestry_common/core/forestry/api/core/ForestryEvent.java b/forestry_common/core/forestry/api/core/ForestryEvent.java new file mode 100755 index 000000000..db7a401fb --- /dev/null +++ b/forestry_common/core/forestry/api/core/ForestryEvent.java @@ -0,0 +1,60 @@ +/******************************************************************************* + * Copyright 2011-2014 by SirSengir + * + * This work is licensed under a Creative Commons Attribution-NonCommercial-NoDerivs 3.0 Unported License. + * + * To view a copy of this license, visit http://creativecommons.org/licenses/by-nc-nd/3.0/. + ******************************************************************************/ +package forestry.api.core; + +import net.minecraft.entity.player.EntityPlayer; + +import cpw.mods.fml.common.eventhandler.Event; + +import forestry.api.genetics.IAlleleSpecies; +import forestry.api.genetics.IBreedingTracker; +import forestry.api.genetics.IMutation; +import forestry.api.genetics.ISpeciesRoot; + +public abstract class ForestryEvent extends Event { + + private static abstract class BreedingEvent extends ForestryEvent { + public final ISpeciesRoot root; + public final IBreedingTracker tracker; + public final String username; + + private BreedingEvent(ISpeciesRoot root, String username, IBreedingTracker tracker) { + super(); + this.root = root; + this.username = username; + this.tracker = tracker; + } + } + + public static class SpeciesDiscovered extends BreedingEvent { + public final IAlleleSpecies species; + public SpeciesDiscovered(ISpeciesRoot root, String username, IAlleleSpecies species, IBreedingTracker tracker) { + super(root, username, tracker); + this.species = species; + } + } + + public static class MutationDiscovered extends BreedingEvent { + public final IMutation allele; + public MutationDiscovered(ISpeciesRoot root, String username, IMutation allele, IBreedingTracker tracker) { + super(root, username, tracker); + this.allele = allele; + } + } + + public static class SyncedBreedingTracker extends ForestryEvent { + public final IBreedingTracker tracker; + public final EntityPlayer player; + public SyncedBreedingTracker(IBreedingTracker tracker, EntityPlayer player) { + super(); + this.tracker = tracker; + this.player = player; + } + + } +} diff --git a/forestry_common/core/forestry/api/core/IArmorNaturalist.java b/forestry_common/core/forestry/api/core/IArmorNaturalist.java new file mode 100755 index 000000000..ebf73ab36 --- /dev/null +++ b/forestry_common/core/forestry/api/core/IArmorNaturalist.java @@ -0,0 +1,27 @@ +/******************************************************************************* + * Copyright 2011-2014 by SirSengir + * + * This work is licensed under a Creative Commons Attribution-NonCommercial-NoDerivs 3.0 Unported License. + * + * To view a copy of this license, visit http://creativecommons.org/licenses/by-nc-nd/3.0/. + ******************************************************************************/ +package forestry.api.core; + +import net.minecraft.entity.player.EntityPlayer; +import net.minecraft.item.ItemStack; + +public interface IArmorNaturalist { + + /** + * Called when the naturalist's armor acts as spectacles for seeing pollinated tree leaves/flowers. + * + * @param player + * Player doing the viewing + * @param armor + * Armor item + * @param doSee + * Whether or not to actually do the side effects of viewing + * @return true if the armor actually allows the player to see pollination. + */ + public boolean canSeePollination(EntityPlayer player, ItemStack armor, boolean doSee); +} diff --git a/forestry_common/core/forestry/api/core/IForestryConstants.java b/forestry_common/core/forestry/api/core/IForestryConstants.java new file mode 100755 index 000000000..054aefc3c --- /dev/null +++ b/forestry_common/core/forestry/api/core/IForestryConstants.java @@ -0,0 +1,26 @@ +/******************************************************************************* + * Copyright 2011-2014 by SirSengir + * + * This work is licensed under a Creative Commons Attribution-NonCommercial-NoDerivs 3.0 Unported License. + * + * To view a copy of this license, visit http://creativecommons.org/licenses/by-nc-nd/3.0/. + ******************************************************************************/ +package forestry.api.core; + +public interface IForestryConstants { + + /** + * @return The villager ID for the Apiarist Villager. + */ + public int getApicultureVillagerID(); + + /** + * @return The villager ID for the Arborist Villager. + */ + public int getArboricultureVillagerID(); + + /** + * @return The ChestGenHooks key for adding items to the Forestry Villager chest. + */ + public String getVillagerChestGenKey(); +} diff --git a/forestry_common/core/forestry/api/core/IGameMode.java b/forestry_common/core/forestry/api/core/IGameMode.java new file mode 100755 index 000000000..46a6461e4 --- /dev/null +++ b/forestry_common/core/forestry/api/core/IGameMode.java @@ -0,0 +1,43 @@ +/******************************************************************************* + * Copyright 2011-2014 by SirSengir + * + * This work is licensed under a Creative Commons Attribution-NonCommercial-NoDerivs 3.0 Unported License. + * + * To view a copy of this license, visit http://creativecommons.org/licenses/by-nc-nd/3.0/. + ******************************************************************************/ +package forestry.api.core; + +import net.minecraft.item.ItemStack; + +public interface IGameMode { + + /** + * @return Human-readable identifier for the game mode. (i.e. 'EASY', 'NORMAL', 'HARD') + */ + String getIdentifier(); + + /** + * @param ident Identifier for the setting. (See the gamemode config.) + * @return Value of the requested setting, false if unknown setting. + */ + boolean getBooleanSetting(String ident); + + /** + * @param ident Identifier for the setting. (See the gamemode config.) + * @return Value of the requested setting, 0 if unknown setting. + */ + int getIntegerSetting(String ident); + + /** + * @param ident Identifier for the setting. (See the gamemode config.) + * @return Value of the requested setting, 0 if unknown setting. + */ + float getFloatSetting(String ident); + + /** + * @param ident Identifier for the setting. (See the gamemode config.) + * @return Value of the requested setting, an itemstack containing an apple if unknown setting. + */ + ItemStack getStackSetting(String ident); + +} diff --git a/forestry_common/core/forestry/api/core/IIconProvider.java b/forestry_common/core/forestry/api/core/IIconProvider.java new file mode 100755 index 000000000..348abd184 --- /dev/null +++ b/forestry_common/core/forestry/api/core/IIconProvider.java @@ -0,0 +1,27 @@ +/******************************************************************************* + * Copyright 2011-2014 by SirSengir + * + * This work is licensed under a Creative Commons Attribution-NonCommercial-NoDerivs 3.0 Unported License. + * + * To view a copy of this license, visit http://creativecommons.org/licenses/by-nc-nd/3.0/. + ******************************************************************************/ +package forestry.api.core; + +import net.minecraft.client.renderer.texture.IIconRegister; +import net.minecraft.util.IIcon; + +import cpw.mods.fml.relauncher.Side; +import cpw.mods.fml.relauncher.SideOnly; + +/** + * Provides icons, needed in some interfaces, most notably for bees and trees. + */ +public interface IIconProvider { + + @SideOnly(Side.CLIENT) + IIcon getIcon(short texUID); + + @SideOnly(Side.CLIENT) + void registerIcons(IIconRegister register); + +} diff --git a/forestry_common/core/forestry/api/core/INBTTagable.java b/forestry_common/core/forestry/api/core/INBTTagable.java new file mode 100755 index 000000000..2b68734cf --- /dev/null +++ b/forestry_common/core/forestry/api/core/INBTTagable.java @@ -0,0 +1,16 @@ +/******************************************************************************* + * Copyright 2011-2014 by SirSengir + * + * This work is licensed under a Creative Commons Attribution-NonCommercial-NoDerivs 3.0 Unported License. + * + * To view a copy of this license, visit http://creativecommons.org/licenses/by-nc-nd/3.0/. + ******************************************************************************/ +package forestry.api.core; + +import net.minecraft.nbt.NBTTagCompound; + +public interface INBTTagable { + void readFromNBT(NBTTagCompound nbttagcompound); + + void writeToNBT(NBTTagCompound nbttagcompound); +} diff --git a/forestry_common/core/forestry/api/core/IPlugin.java b/forestry_common/core/forestry/api/core/IPlugin.java new file mode 100755 index 000000000..4412ef3b3 --- /dev/null +++ b/forestry_common/core/forestry/api/core/IPlugin.java @@ -0,0 +1,39 @@ +/******************************************************************************* + * Copyright 2011-2014 by SirSengir + * + * This work is licensed under a Creative Commons Attribution-NonCommercial-NoDerivs 3.0 Unported License. + * + * To view a copy of this license, visit http://creativecommons.org/licenses/by-nc-nd/3.0/. + ******************************************************************************/ +package forestry.api.core; + +/** + * Optional way to hook into Forestry. + * + * Plugin classes can reside in any package, their class name however has to start with 'Plugin', i.e. 'PluginMyStuff'. + * + * @author SirSengir + */ +public interface IPlugin { + + /** + * @return true if the plugin is to be loaded. + */ + public boolean isAvailable(); + + /** + * Called during Forestry's @PreInit. + */ + public void preInit(); + + /** + * Called at the start of Forestry's @PostInit. + */ + public void doInit(); + + /** + * Called at the end of Forestry's @PostInit. + */ + public void postInit(); + +} diff --git a/forestry_common/core/forestry/api/core/IStructureLogic.java b/forestry_common/core/forestry/api/core/IStructureLogic.java new file mode 100755 index 000000000..cd55c5301 --- /dev/null +++ b/forestry_common/core/forestry/api/core/IStructureLogic.java @@ -0,0 +1,22 @@ +/******************************************************************************* + * Copyright 2011-2014 by SirSengir + * + * This work is licensed under a Creative Commons Attribution-NonCommercial-NoDerivs 3.0 Unported License. + * + * To view a copy of this license, visit http://creativecommons.org/licenses/by-nc-nd/3.0/. + ******************************************************************************/ +package forestry.api.core; + +public interface IStructureLogic extends INBTTagable { + + /** + * @return String unique to the type of structure controlled by this structure logic. + */ + String getTypeUID(); + + /** + * Called by {@link ITileStructure}'s validateStructure(). + */ + void validateStructure(); + +} diff --git a/forestry_common/core/forestry/api/core/ITextureManager.java b/forestry_common/core/forestry/api/core/ITextureManager.java new file mode 100755 index 000000000..a956d2439 --- /dev/null +++ b/forestry_common/core/forestry/api/core/ITextureManager.java @@ -0,0 +1,23 @@ +/******************************************************************************* + * Copyright 2011-2014 by SirSengir + * + * This work is licensed under a Creative Commons Attribution-NonCommercial-NoDerivs 3.0 Unported License. + * + * To view a copy of this license, visit http://creativecommons.org/licenses/by-nc-nd/3.0/. + ******************************************************************************/ +package forestry.api.core; + +import net.minecraft.util.IIcon; + +import cpw.mods.fml.relauncher.Side; +import cpw.mods.fml.relauncher.SideOnly; + +@SideOnly(Side.CLIENT) +public interface ITextureManager { + + void registerIconProvider(IIconProvider provider); + + IIcon getIcon(short texUID); + + IIcon getDefault(String ident); +} diff --git a/forestry_common/core/forestry/api/core/ITileStructure.java b/forestry_common/core/forestry/api/core/ITileStructure.java new file mode 100755 index 000000000..f4909dde8 --- /dev/null +++ b/forestry_common/core/forestry/api/core/ITileStructure.java @@ -0,0 +1,65 @@ +/******************************************************************************* + * Copyright 2011-2014 by SirSengir + * + * This work is licensed under a Creative Commons Attribution-NonCommercial-NoDerivs 3.0 Unported License. + * + * To view a copy of this license, visit http://creativecommons.org/licenses/by-nc-nd/3.0/. + ******************************************************************************/ +package forestry.api.core; + +import net.minecraft.inventory.IInventory; +import net.minecraft.tileentity.TileEntity; + +/** + * The basis for multiblock components. + */ +public interface ITileStructure { + + /** + * @return String unique to the type of structure controlled by this structure logic. Should map to {@link IStructureLogic} + */ + String getTypeUID(); + + /** + * Should map to {@link IStructureLogic} + */ + void validateStructure(); + + /** + * Called when the structure resets. + */ + void onStructureReset(); + + /** + * @return TileEntity that is the master in this structure, null if no structure exists. + */ + ITileStructure getCentralTE(); + + /** + * Called to set the master TileEntity. Implementing TileEntity should keep track of the master's coordinates, not refer to the TE object itself. + * + * @param tile + */ + void setCentralTE(TileEntity tile); + + /** + * @return IInventory representing the TE's inventory. + */ + IInventory getInventory(); + + /** + * Only called on Forestry's own blocks. + */ + void makeMaster(); + + /** + * @return true if this TE is the master in a structure, false otherwise. + */ + boolean isMaster(); + + /** + * @return true if the TE is master or has a master. + */ + boolean isIntegratedIntoStructure(); + +} diff --git a/forestry_common/core/forestry/api/core/IToolScoop.java b/forestry_common/core/forestry/api/core/IToolScoop.java new file mode 100755 index 000000000..516a36025 --- /dev/null +++ b/forestry_common/core/forestry/api/core/IToolScoop.java @@ -0,0 +1,15 @@ +/******************************************************************************* + * Copyright 2011-2014 by SirSengir + * + * This work is licensed under a Creative Commons Attribution-NonCommercial-NoDerivs 3.0 Unported License. + * + * To view a copy of this license, visit http://creativecommons.org/licenses/by-nc-nd/3.0/. + ******************************************************************************/ +package forestry.api.core; + +/** + * Marks a tool as a scoop. + */ +public interface IToolScoop { + +} diff --git a/forestry_common/core/forestry/api/core/ItemInterface.java b/forestry_common/core/forestry/api/core/ItemInterface.java new file mode 100755 index 000000000..3d6423528 --- /dev/null +++ b/forestry_common/core/forestry/api/core/ItemInterface.java @@ -0,0 +1,51 @@ +/******************************************************************************* + * Copyright 2011-2014 by SirSengir + * + * This work is licensed under a Creative Commons Attribution-NonCommercial-NoDerivs 3.0 Unported License. + * + * To view a copy of this license, visit http://creativecommons.org/licenses/by-nc-nd/3.0/. + ******************************************************************************/ +package forestry.api.core; + +import java.lang.reflect.Method; + +import net.minecraft.item.ItemStack; + +import cpw.mods.fml.common.FMLLog; + +/** + * This is going away someday, use FML's GameRegistry instead. + * @deprecated + */ +@Deprecated +public class ItemInterface { + + /** + * Get items here! + * + * Blocks currently not supported. + * + * @param ident + * @return ItemStack representing the item, null if not found. + */ + public static ItemStack getItem(String ident) { + ItemStack item = null; + + try { + String pack = ItemInterface.class.getPackage().getName(); + pack = pack.substring(0, pack.lastIndexOf('.')); + String itemClass = pack.substring(0, pack.lastIndexOf('.')) + ".core.config.ForestryItem"; + Object[] enums = Class.forName(itemClass).getEnumConstants(); + for (Object e : enums) { + if (e.toString().equals(ident)) { + Method m = e.getClass().getMethod("getItemStack"); + return (ItemStack) m.invoke(e); + } + } + } catch (Exception ex) { + FMLLog.warning("Could not retrieve Forestry item identified by: " + ident); + } + + return item; + } +} diff --git a/forestry_common/core/forestry/api/core/PluginInfo.java b/forestry_common/core/forestry/api/core/PluginInfo.java new file mode 100755 index 000000000..ac6f3028e --- /dev/null +++ b/forestry_common/core/forestry/api/core/PluginInfo.java @@ -0,0 +1,56 @@ +/******************************************************************************* + * Copyright 2011-2014 by SirSengir + * + * This work is licensed under a Creative Commons Attribution-NonCommercial-NoDerivs 3.0 Unported License. + * + * To view a copy of this license, visit http://creativecommons.org/licenses/by-nc-nd/3.0/. + ******************************************************************************/ +package forestry.api.core; + +import java.lang.annotation.Retention; +import java.lang.annotation.RetentionPolicy; + +/** + * Optional annotation to provide additional information on IPlugins. This information will be available via the "/forestry plugin info $pluginID" command ingame. + * + * @author SirSengir + */ +@Retention(RetentionPolicy.RUNTIME) +public @interface PluginInfo { + + /** + * @return Unique identifier for the plugin, no spaces! + */ + String pluginID(); + + /** + * @return Nice and readable plugin name. + */ + String name(); + + /** + * @return Plugin author's name. + */ + String author() default ""; + + /** + * @return URL of plugin homepage. + */ + String url() default ""; + + /** + * @return Version of the plugin, if any. + */ + String version() default ""; + + /** + * @return Short description what the plugin does. + */ + String description() default ""; + + /** + * @return Not used (yet?). + */ + String help() default ""; + +} diff --git a/forestry_common/core/forestry/api/core/Tabs.java b/forestry_common/core/forestry/api/core/Tabs.java new file mode 100755 index 000000000..c8b178d62 --- /dev/null +++ b/forestry_common/core/forestry/api/core/Tabs.java @@ -0,0 +1,21 @@ +/******************************************************************************* + * Copyright 2011-2014 by SirSengir + * + * This work is licensed under a Creative Commons Attribution-NonCommercial-NoDerivs 3.0 Unported License. + * + * To view a copy of this license, visit http://creativecommons.org/licenses/by-nc-nd/3.0/. + ******************************************************************************/ +package forestry.api.core; + +import net.minecraft.creativetab.CreativeTabs; + +/** + * References to the specialised tabs added by Forestry to creative inventory. + */ +public class Tabs { + + public static CreativeTabs tabApiculture; + public static CreativeTabs tabArboriculture; + public static CreativeTabs tabLepidopterology; + +} diff --git a/forestry_common/core/forestry/api/core/package-info.java b/forestry_common/core/forestry/api/core/package-info.java new file mode 100755 index 000000000..428939f4f --- /dev/null +++ b/forestry_common/core/forestry/api/core/package-info.java @@ -0,0 +1,10 @@ +/******************************************************************************* + * Copyright 2011-2014 by SirSengir + * + * This work is licensed under a Creative Commons Attribution-NonCommercial-NoDerivs 3.0 Unported License. + * + * To view a copy of this license, visit http://creativecommons.org/licenses/by-nc-nd/3.0/. + ******************************************************************************/ +@API(apiVersion="1.0", owner="Forestry", provides="ForestryAPI|core") +package forestry.api.core; +import cpw.mods.fml.common.API; diff --git a/forestry_common/core/forestry/api/farming/Farmables.java b/forestry_common/core/forestry/api/farming/Farmables.java new file mode 100755 index 000000000..26b7eec2c --- /dev/null +++ b/forestry_common/core/forestry/api/farming/Farmables.java @@ -0,0 +1,22 @@ +/******************************************************************************* + * Copyright 2011-2014 by SirSengir + * + * This work is licensed under a Creative Commons Attribution-NonCommercial-NoDerivs 3.0 Unported License. + * + * To view a copy of this license, visit http://creativecommons.org/licenses/by-nc-nd/3.0/. + ******************************************************************************/ +package forestry.api.farming; + +import java.util.Collection; +import java.util.HashMap; + +public class Farmables { + /** + * Can be used to add IFarmables to some of the vanilla farm logics. + * + * Identifiers: farmArboreal farmWheat farmGourd farmInfernal farmPoales farmSucculentes farmVegetables farmShroom + */ + public static HashMap> farmables = new HashMap>(); + + public static IFarmInterface farmInterface; +} diff --git a/forestry_common/core/forestry/api/farming/ICrop.java b/forestry_common/core/forestry/api/farming/ICrop.java new file mode 100755 index 000000000..61f6ffceb --- /dev/null +++ b/forestry_common/core/forestry/api/farming/ICrop.java @@ -0,0 +1,23 @@ +/******************************************************************************* + * Copyright 2011-2014 by SirSengir + * + * This work is licensed under a Creative Commons Attribution-NonCommercial-NoDerivs 3.0 Unported License. + * + * To view a copy of this license, visit http://creativecommons.org/licenses/by-nc-nd/3.0/. + ******************************************************************************/ +package forestry.api.farming; + +import java.util.Collection; + +import net.minecraft.item.ItemStack; + +public interface ICrop { + + /** + * Harvests this crop. Performs the necessary manipulations to set the crop into a "harvested" state. + * + * @return Products harvested. + */ + Collection harvest(); + +} diff --git a/forestry_common/core/forestry/api/farming/IFarmComponent.java b/forestry_common/core/forestry/api/farming/IFarmComponent.java new file mode 100755 index 000000000..4704fab8e --- /dev/null +++ b/forestry_common/core/forestry/api/farming/IFarmComponent.java @@ -0,0 +1,19 @@ +/******************************************************************************* + * Copyright 2011-2014 by SirSengir + * + * This work is licensed under a Creative Commons Attribution-NonCommercial-NoDerivs 3.0 Unported License. + * + * To view a copy of this license, visit http://creativecommons.org/licenses/by-nc-nd/3.0/. + ******************************************************************************/ +package forestry.api.farming; + +import forestry.api.core.ITileStructure; + +public interface IFarmComponent extends ITileStructure { + + boolean hasFunction(); + + void registerListener(IFarmListener listener); + + void removeListener(IFarmListener listener); +} diff --git a/forestry_common/core/forestry/api/farming/IFarmHousing.java b/forestry_common/core/forestry/api/farming/IFarmHousing.java new file mode 100755 index 000000000..6f1e00349 --- /dev/null +++ b/forestry_common/core/forestry/api/farming/IFarmHousing.java @@ -0,0 +1,76 @@ +/******************************************************************************* + * Copyright 2011-2014 by SirSengir + * + * This work is licensed under a Creative Commons Attribution-NonCommercial-NoDerivs 3.0 Unported License. + * + * To view a copy of this license, visit http://creativecommons.org/licenses/by-nc-nd/3.0/. + ******************************************************************************/ +package forestry.api.farming; + +import net.minecraft.item.ItemStack; +import net.minecraft.world.World; + +import net.minecraftforge.common.util.ForgeDirection; +import net.minecraftforge.fluids.FluidStack; + +public interface IFarmHousing { + + int[] getCoords(); + + int[] getArea(); + + int[] getOffset(); + + World getWorld(); + + /** + * Will run the work cycle on a master TE. Will do nothing on any other farm component. + * + * @return true if any work was done, false otherwise. + */ + boolean doWork(); + + boolean hasLiquid(FluidStack liquid); + + void removeLiquid(FluidStack liquid); + + boolean hasResources(ItemStack[] resources); + + void removeResources(ItemStack[] resources); + + /** + * Callback for {@link IFarmLogic}s to plant a sapling, seed, germling, stem. Will remove the appropriate germling from the farm's inventory. It's up to the + * logic to only call this on a valid location. + * + * @param farmable + * @param world + * @param x + * @param y + * @param z + * @return true if planting was successful, false otherwise. + */ + boolean plantGermling(IFarmable farmable, World world, int x, int y, int z); + + /* INTERACTION WITH HATCHES */ + boolean acceptsAsGermling(ItemStack itemstack); + + boolean acceptsAsResource(ItemStack itemstack); + + boolean acceptsAsFertilizer(ItemStack itemstack); + + /* LOGIC */ + /** + * Set a farm logic for the given direction. UP/DOWN/UNKNOWN are invalid! + * + * @param direction + * @param logic + */ + void setFarmLogic(ForgeDirection direction, IFarmLogic logic); + + /** + * Reset the farm logic for the given direction to default. UP/DOWN/UNKNOWN are invalid! + * + * @param direction + */ + void resetFarmLogic(ForgeDirection direction); +} diff --git a/forestry_common/core/forestry/api/farming/IFarmInterface.java b/forestry_common/core/forestry/api/farming/IFarmInterface.java new file mode 100755 index 000000000..ae851df0e --- /dev/null +++ b/forestry_common/core/forestry/api/farming/IFarmInterface.java @@ -0,0 +1,22 @@ +/******************************************************************************* + * Copyright 2011-2014 by SirSengir + * + * This work is licensed under a Creative Commons Attribution-NonCommercial-NoDerivs 3.0 Unported License. + * + * To view a copy of this license, visit http://creativecommons.org/licenses/by-nc-nd/3.0/. + ******************************************************************************/ +package forestry.api.farming; + +import forestry.api.core.IStructureLogic; + +public interface IFarmInterface { + + /** + * Creates {@link IStructureLogic} for use in farm components. + * + * @param structure + * {@link IFarmComponent} to create the logic for. + * @return {@link IStructureLogic} for use in farm components + */ + IStructureLogic createFarmStructureLogic(IFarmComponent structure); +} diff --git a/forestry_common/core/forestry/api/farming/IFarmListener.java b/forestry_common/core/forestry/api/farming/IFarmListener.java new file mode 100755 index 000000000..e9f8e0718 --- /dev/null +++ b/forestry_common/core/forestry/api/farming/IFarmListener.java @@ -0,0 +1,79 @@ +/******************************************************************************* + * Copyright 2011-2014 by SirSengir + * + * This work is licensed under a Creative Commons Attribution-NonCommercial-NoDerivs 3.0 Unported License. + * + * To view a copy of this license, visit http://creativecommons.org/licenses/by-nc-nd/3.0/. + ******************************************************************************/ +package forestry.api.farming; + +import java.util.Collection; + +import net.minecraft.item.ItemStack; + +import net.minecraftforge.common.util.ForgeDirection; + +public interface IFarmListener { + + /** + * Called before a crop is harvested. + * + * @param crop + * ICrop about to be harvested. + * @return true to cancel further processing of this crop. + */ + boolean beforeCropHarvest(ICrop crop); + + /** + * Called after a crop has been harvested, but before harvested items are stowed in the farms inventory. + * + * @param harvested + * Collection of harvested stacks. May be manipulated. Ensure removal of stacks with 0 or less items! + * @param crop + * Harvested {@link ICrop} + */ + void afterCropHarvest(Collection harvested, ICrop crop); + + /** + * Called after the stack of collected items has been returned by the farm logic, but before it is added to the farm's pending queue. + * + * @param collected + * Collection of collected stacks. May be manipulated. Ensure removal of stacks with 0 or less items! + * @param logic + */ + void hasCollected(Collection collected, IFarmLogic logic); + + /** + * Called after farmland has successfully been cultivated by a farm logic. + * + * @param logic + * @param x + * @param y + * @param z + * @param direction + * @param extent + */ + void hasCultivated(IFarmLogic logic, int x, int y, int z, ForgeDirection direction, int extent); + + /** + * Called after the stack of harvested crops has been returned by the farm logic, but before it is added to the farm's pending queue. + * + * @param harvested + * @param logic + * @param x + * @param y + * @param z + * @param direction + * @param extent + */ + void hasScheduledHarvest(Collection harvested, IFarmLogic logic, int x, int y, int z, ForgeDirection direction, int extent); + + /** + * Can be used to cancel farm task on a per side/{@link IFarmLogic} basis. + * + * @param logic + * @param direction + * @return true to skip any work action on the given logic and direction for this work cycle. + */ + boolean cancelTask(IFarmLogic logic, ForgeDirection direction); +} diff --git a/forestry_common/core/forestry/api/farming/IFarmLogic.java b/forestry_common/core/forestry/api/farming/IFarmLogic.java new file mode 100755 index 000000000..5d4d93b6b --- /dev/null +++ b/forestry_common/core/forestry/api/farming/IFarmLogic.java @@ -0,0 +1,43 @@ +/******************************************************************************* + * Copyright 2011-2014 by SirSengir + * + * This work is licensed under a Creative Commons Attribution-NonCommercial-NoDerivs 3.0 Unported License. + * + * To view a copy of this license, visit http://creativecommons.org/licenses/by-nc-nd/3.0/. + ******************************************************************************/ +package forestry.api.farming; + +import java.util.Collection; + +import net.minecraft.item.ItemStack; +import net.minecraft.util.IIcon; +import net.minecraft.util.ResourceLocation; + +import cpw.mods.fml.relauncher.Side; +import cpw.mods.fml.relauncher.SideOnly; + +import net.minecraftforge.common.util.ForgeDirection; + +public interface IFarmLogic { + + int getFertilizerConsumption(); + + int getWaterConsumption(float hydrationModifier); + + boolean isAcceptedResource(ItemStack itemstack); + + boolean isAcceptedGermling(ItemStack itemstack); + + Collection collect(); + + boolean cultivate(int x, int y, int z, ForgeDirection direction, int extent); + + Collection harvest(int x, int y, int z, ForgeDirection direction, int extent); + + @SideOnly(Side.CLIENT) + IIcon getIcon(); + + ResourceLocation getSpriteSheet(); + + String getName(); +} diff --git a/forestry_common/core/forestry/api/farming/IFarmable.java b/forestry_common/core/forestry/api/farming/IFarmable.java new file mode 100755 index 000000000..4b5cb8e26 --- /dev/null +++ b/forestry_common/core/forestry/api/farming/IFarmable.java @@ -0,0 +1,61 @@ +/******************************************************************************* + * Copyright 2011-2014 by SirSengir + * + * This work is licensed under a Creative Commons Attribution-NonCommercial-NoDerivs 3.0 Unported License. + * + * To view a copy of this license, visit http://creativecommons.org/licenses/by-nc-nd/3.0/. + ******************************************************************************/ +package forestry.api.farming; + +import net.minecraft.item.ItemStack; +import net.minecraft.world.World; + +/** + * IGermling describes a crop or other harvestable object and can be used to inspect item stacks and blocks for matches. + */ +public interface IFarmable { + + /** + * @param world + * @param x + * @param y + * @param z + * @return true if the block at the given location is a "sapling" for this type, i.e. a non-harvestable immature version of the crop. + */ + boolean isSaplingAt(World world, int x, int y, int z); + + /** + * @param world + * @param x + * @param y + * @param z + * @return {@link ICrop} if the block at the given location is a harvestable and mature crop, null otherwise. + */ + ICrop getCropAt(World world, int x, int y, int z); + + /** + * @param itemstack + * @return true if the item is a valid germling (plantable sapling, seed, etc.) for this type. + */ + boolean isGermling(ItemStack itemstack); + + /** + * @param itemstack + * @return true if the item is something that can drop from this type without actually being harvested as a crop. (Apples or sapling from decaying leaves.) + */ + boolean isWindfall(ItemStack itemstack); + + /** + * Plants a sapling by manipulating the world. The {@link IFarmLogic} should have verified the given location as valid. Called by the {@link IFarmHousing} + * which handles resources. + * + * @param germling + * @param world + * @param x + * @param y + * @param z + * @return true on success, false otherwise. + */ + boolean plantSaplingAt(ItemStack germling, World world, int x, int y, int z); + +} diff --git a/forestry_common/core/forestry/api/farming/package-info.java b/forestry_common/core/forestry/api/farming/package-info.java new file mode 100755 index 000000000..fc275cf88 --- /dev/null +++ b/forestry_common/core/forestry/api/farming/package-info.java @@ -0,0 +1,10 @@ +/******************************************************************************* + * Copyright 2011-2014 by SirSengir + * + * This work is licensed under a Creative Commons Attribution-NonCommercial-NoDerivs 3.0 Unported License. + * + * To view a copy of this license, visit http://creativecommons.org/licenses/by-nc-nd/3.0/. + ******************************************************************************/ +@API(apiVersion="1.0", owner="ForestryAPI|core", provides="ForestryAPI|farming") +package forestry.api.farming; +import cpw.mods.fml.common.API; diff --git a/forestry_common/core/forestry/api/food/BeverageManager.java b/forestry_common/core/forestry/api/food/BeverageManager.java new file mode 100755 index 000000000..0dca04903 --- /dev/null +++ b/forestry_common/core/forestry/api/food/BeverageManager.java @@ -0,0 +1,15 @@ +/******************************************************************************* + * Copyright 2011-2014 by SirSengir + * + * This work is licensed under a Creative Commons Attribution-NonCommercial-NoDerivs 3.0 Unported License. + * + * To view a copy of this license, visit http://creativecommons.org/licenses/by-nc-nd/3.0/. + ******************************************************************************/ +package forestry.api.food; + +public class BeverageManager { + public static IBeverageEffect[] effectList = new IBeverageEffect[128]; + + public static IInfuserManager infuserManager; + public static IIngredientManager ingredientManager; +} diff --git a/forestry_common/core/forestry/api/food/IBeverageEffect.java b/forestry_common/core/forestry/api/food/IBeverageEffect.java new file mode 100755 index 000000000..f93f8ee27 --- /dev/null +++ b/forestry_common/core/forestry/api/food/IBeverageEffect.java @@ -0,0 +1,19 @@ +/******************************************************************************* + * Copyright 2011-2014 by SirSengir + * + * This work is licensed under a Creative Commons Attribution-NonCommercial-NoDerivs 3.0 Unported License. + * + * To view a copy of this license, visit http://creativecommons.org/licenses/by-nc-nd/3.0/. + ******************************************************************************/ +package forestry.api.food; + +import net.minecraft.entity.player.EntityPlayer; +import net.minecraft.world.World; + +public interface IBeverageEffect { + int getId(); + + void doEffect(World world, EntityPlayer player); + + String getDescription(); +} diff --git a/forestry_common/core/forestry/api/food/IInfuserManager.java b/forestry_common/core/forestry/api/food/IInfuserManager.java new file mode 100755 index 000000000..18756ef09 --- /dev/null +++ b/forestry_common/core/forestry/api/food/IInfuserManager.java @@ -0,0 +1,24 @@ +/******************************************************************************* + * Copyright 2011-2014 by SirSengir + * + * This work is licensed under a Creative Commons Attribution-NonCommercial-NoDerivs 3.0 Unported License. + * + * To view a copy of this license, visit http://creativecommons.org/licenses/by-nc-nd/3.0/. + ******************************************************************************/ +package forestry.api.food; + +import net.minecraft.item.ItemStack; + +public interface IInfuserManager { + + void addMixture(int meta, ItemStack ingredient, IBeverageEffect effect); + + void addMixture(int meta, ItemStack[] ingredients, IBeverageEffect effect); + + ItemStack getSeasoned(ItemStack base, ItemStack[] ingredients); + + boolean hasMixtures(ItemStack[] ingredients); + + ItemStack[] getRequired(ItemStack[] ingredients); + +} diff --git a/forestry_common/core/forestry/api/food/IIngredientManager.java b/forestry_common/core/forestry/api/food/IIngredientManager.java new file mode 100755 index 000000000..20ff837a8 --- /dev/null +++ b/forestry_common/core/forestry/api/food/IIngredientManager.java @@ -0,0 +1,18 @@ +/******************************************************************************* + * Copyright 2011-2014 by SirSengir + * + * This work is licensed under a Creative Commons Attribution-NonCommercial-NoDerivs 3.0 Unported License. + * + * To view a copy of this license, visit http://creativecommons.org/licenses/by-nc-nd/3.0/. + ******************************************************************************/ +package forestry.api.food; + +import net.minecraft.item.ItemStack; + +public interface IIngredientManager { + + String getDescription(ItemStack itemstack); + + void addIngredient(ItemStack ingredient, String description); + +} diff --git a/forestry_common/core/forestry/api/food/package-info.java b/forestry_common/core/forestry/api/food/package-info.java new file mode 100755 index 000000000..6a02d6d15 --- /dev/null +++ b/forestry_common/core/forestry/api/food/package-info.java @@ -0,0 +1,10 @@ +/******************************************************************************* + * Copyright 2011-2014 by SirSengir + * + * This work is licensed under a Creative Commons Attribution-NonCommercial-NoDerivs 3.0 Unported License. + * + * To view a copy of this license, visit http://creativecommons.org/licenses/by-nc-nd/3.0/. + ******************************************************************************/ +@API(apiVersion="1.0", owner="ForestryAPI|core", provides="ForestryAPI|food") +package forestry.api.food; +import cpw.mods.fml.common.API; diff --git a/forestry_common/core/forestry/api/fuels/EngineBronzeFuel.java b/forestry_common/core/forestry/api/fuels/EngineBronzeFuel.java new file mode 100755 index 000000000..f7e615bee --- /dev/null +++ b/forestry_common/core/forestry/api/fuels/EngineBronzeFuel.java @@ -0,0 +1,36 @@ +/******************************************************************************* + * Copyright 2011-2014 by SirSengir + * + * This work is licensed under a Creative Commons Attribution-NonCommercial-NoDerivs 3.0 Unported License. + * + * To view a copy of this license, visit http://creativecommons.org/licenses/by-nc-nd/3.0/. + ******************************************************************************/ +package forestry.api.fuels; + +import net.minecraftforge.fluids.Fluid; + +public class EngineBronzeFuel { + /** + * Item that is valid fuel for a biogas engine. + */ + public final Fluid liquid; + /** + * Power produced by this fuel per work cycle of the engine. + */ + public final int powerPerCycle; + /** + * How many work cycles a single "stack" of this type lasts. + */ + public final int burnDuration; + /** + * By how much the normal heat dissipation rate of 1 is multiplied when using this fuel type. + */ + public final int dissipationMultiplier; + + public EngineBronzeFuel(Fluid liquid, int powerPerCycle, int burnDuration, int dissipationMultiplier) { + this.liquid = liquid; + this.powerPerCycle = powerPerCycle; + this.burnDuration = burnDuration; + this.dissipationMultiplier = dissipationMultiplier; + } +} diff --git a/forestry_common/core/forestry/api/fuels/EngineCopperFuel.java b/forestry_common/core/forestry/api/fuels/EngineCopperFuel.java new file mode 100755 index 000000000..e5dc9a266 --- /dev/null +++ b/forestry_common/core/forestry/api/fuels/EngineCopperFuel.java @@ -0,0 +1,33 @@ +/******************************************************************************* + * Copyright 2011-2014 by SirSengir + * + * This work is licensed under a Creative Commons Attribution-NonCommercial-NoDerivs 3.0 Unported License. + * + * To view a copy of this license, visit http://creativecommons.org/licenses/by-nc-nd/3.0/. + ******************************************************************************/ +package forestry.api.fuels; + +import net.minecraft.item.ItemStack; + +public class EngineCopperFuel { + + /** + * Item that is valid fuel for a peat-fired engine. + */ + public final ItemStack fuel; + /** + * Power produced by this fuel per work cycle. + */ + public final int powerPerCycle; + /** + * Amount of work cycles this item lasts before being consumed. + */ + public final int burnDuration; + + public EngineCopperFuel(ItemStack fuel, int powerPerCycle, int burnDuration) { + this.fuel = fuel; + this.powerPerCycle = powerPerCycle; + this.burnDuration = burnDuration; + } + +} diff --git a/forestry_common/core/forestry/api/fuels/FermenterFuel.java b/forestry_common/core/forestry/api/fuels/FermenterFuel.java new file mode 100755 index 000000000..b3ac01285 --- /dev/null +++ b/forestry_common/core/forestry/api/fuels/FermenterFuel.java @@ -0,0 +1,31 @@ +/******************************************************************************* + * Copyright 2011-2014 by SirSengir + * + * This work is licensed under a Creative Commons Attribution-NonCommercial-NoDerivs 3.0 Unported License. + * + * To view a copy of this license, visit http://creativecommons.org/licenses/by-nc-nd/3.0/. + ******************************************************************************/ +package forestry.api.fuels; + +import net.minecraft.item.ItemStack; + +public class FermenterFuel { + /** + * Item that is a valid fuel for the fermenter (i.e. fertilizer). + */ + public final ItemStack item; + /** + * How much is fermeted per work cycle, i.e. how much biomass is produced per cycle. + */ + public final int fermentPerCycle; + /** + * Amount of work cycles a single item of this fuel lasts before expiring. + */ + public final int burnDuration; + + public FermenterFuel(ItemStack item, int fermentPerCycle, int burnDuration) { + this.item = item; + this.fermentPerCycle = fermentPerCycle; + this.burnDuration = burnDuration; + } +} diff --git a/forestry_common/core/forestry/api/fuels/FuelManager.java b/forestry_common/core/forestry/api/fuels/FuelManager.java new file mode 100755 index 000000000..bdb1e747f --- /dev/null +++ b/forestry_common/core/forestry/api/fuels/FuelManager.java @@ -0,0 +1,36 @@ +/******************************************************************************* + * Copyright 2011-2014 by SirSengir + * + * This work is licensed under a Creative Commons Attribution-NonCommercial-NoDerivs 3.0 Unported License. + * + * To view a copy of this license, visit http://creativecommons.org/licenses/by-nc-nd/3.0/. + ******************************************************************************/ +package forestry.api.fuels; + +import java.util.HashMap; + + +public class FuelManager { + /** + * Add new fuels for the fermenter here (i.e. fertilizer). Will accept Items, ItemStacks and Strings (Ore Dictionary) + */ + public static HashMap fermenterFuel; + /** + * Add new resources for the moistener here (i.e. wheat) + */ + public static HashMap moistenerResource; + /** + * Add new substrates for the rainmaker here + */ + public static HashMap rainSubstrate; + /** + * Add new fuels for EngineBronze (= biogas engine) here + */ + public static HashMap bronzeEngineFuel; + /** + * Add new fuels for EngineCopper (= peat-fired engine) here + */ + public static HashMap copperEngineFuel; + + // Generator fuel list in GeneratorFuel.class +} diff --git a/forestry_common/core/forestry/api/fuels/GeneratorFuel.java b/forestry_common/core/forestry/api/fuels/GeneratorFuel.java new file mode 100755 index 000000000..97546261a --- /dev/null +++ b/forestry_common/core/forestry/api/fuels/GeneratorFuel.java @@ -0,0 +1,37 @@ +/******************************************************************************* + * Copyright 2011-2014 by SirSengir + * + * This work is licensed under a Creative Commons Attribution-NonCommercial-NoDerivs 3.0 Unported License. + * + * To view a copy of this license, visit http://creativecommons.org/licenses/by-nc-nd/3.0/. + ******************************************************************************/ +package forestry.api.fuels; + +import java.util.HashMap; + +import net.minecraftforge.fluids.FluidStack; + +public class GeneratorFuel { + + public static HashMap fuels = new HashMap(); + + /** + * LiquidStack representing the fuel type and amount consumed per triggered cycle. + */ + public final FluidStack fuelConsumed; + /** + * EU emitted per tick while this fuel is being consumed in the generator (i.e. biofuel = 32, biomass = 8). + */ + public final int eu; + /** + * Rate at which the fuel is consumed. 1 - Every tick 2 - Every second tick 3 - Every third tick etc. + */ + public final int rate; + + public GeneratorFuel(FluidStack fuelConsumed, int eu, int rate) { + this.fuelConsumed = fuelConsumed; + this.eu = eu; + this.rate = rate; + } + +} diff --git a/forestry_common/core/forestry/api/fuels/MoistenerFuel.java b/forestry_common/core/forestry/api/fuels/MoistenerFuel.java new file mode 100755 index 000000000..e5f3c4ca4 --- /dev/null +++ b/forestry_common/core/forestry/api/fuels/MoistenerFuel.java @@ -0,0 +1,36 @@ +/******************************************************************************* + * Copyright 2011-2014 by SirSengir + * + * This work is licensed under a Creative Commons Attribution-NonCommercial-NoDerivs 3.0 Unported License. + * + * To view a copy of this license, visit http://creativecommons.org/licenses/by-nc-nd/3.0/. + ******************************************************************************/ +package forestry.api.fuels; + +import net.minecraft.item.ItemStack; + +public class MoistenerFuel { + /** + * The item to use + */ + public final ItemStack item; + /** + * The item that leaves the moistener's working slot (i.e. mouldy wheat, decayed wheat, mulch) + */ + public final ItemStack product; + /** + * How much this item contributes to the final product of the moistener (i.e. mycelium) + */ + public final int moistenerValue; + /** + * What stage this product represents. Resources with lower stage value will be consumed first. + */ + public final int stage; + + public MoistenerFuel(ItemStack item, ItemStack product, int stage, int moistenerValue) { + this.item = item; + this.product = product; + this.stage = stage; + this.moistenerValue = moistenerValue; + } +} diff --git a/forestry_common/core/forestry/api/fuels/RainSubstrate.java b/forestry_common/core/forestry/api/fuels/RainSubstrate.java new file mode 100755 index 000000000..f35a6bd66 --- /dev/null +++ b/forestry_common/core/forestry/api/fuels/RainSubstrate.java @@ -0,0 +1,42 @@ +/******************************************************************************* + * Copyright 2011-2014 by SirSengir + * + * This work is licensed under a Creative Commons Attribution-NonCommercial-NoDerivs 3.0 Unported License. + * + * To view a copy of this license, visit http://creativecommons.org/licenses/by-nc-nd/3.0/. + ******************************************************************************/ +package forestry.api.fuels; + +import net.minecraft.item.ItemStack; + +public class RainSubstrate { + /** + * Rain substrate capable of activating the rainmaker. + */ + public ItemStack item; + /** + * Duration of the rain shower triggered by this substrate in Minecraft ticks. + */ + public int duration; + /** + * Speed of activation sequence triggered. + */ + public float speed; + + public boolean reverse; + + public RainSubstrate(ItemStack item, int duration, float speed) { + this(item, duration, speed, false); + } + + public RainSubstrate(ItemStack item, float speed) { + this(item, 0, speed, true); + } + + public RainSubstrate(ItemStack item, int duration, float speed, boolean reverse) { + this.item = item; + this.duration = duration; + this.speed = speed; + this.reverse = reverse; + } +} diff --git a/forestry_common/core/forestry/api/fuels/package-info.java b/forestry_common/core/forestry/api/fuels/package-info.java new file mode 100755 index 000000000..73f086aa8 --- /dev/null +++ b/forestry_common/core/forestry/api/fuels/package-info.java @@ -0,0 +1,10 @@ +/******************************************************************************* + * Copyright 2011-2014 by SirSengir + * + * This work is licensed under a Creative Commons Attribution-NonCommercial-NoDerivs 3.0 Unported License. + * + * To view a copy of this license, visit http://creativecommons.org/licenses/by-nc-nd/3.0/. + ******************************************************************************/ +@API(apiVersion="1.0", owner="ForestryAPI|core", provides="ForestryAPI|fuels") +package forestry.api.fuels; +import cpw.mods.fml.common.API; diff --git a/forestry_common/core/forestry/api/genetics/AlleleManager.java b/forestry_common/core/forestry/api/genetics/AlleleManager.java new file mode 100755 index 000000000..15d4ed5d6 --- /dev/null +++ b/forestry_common/core/forestry/api/genetics/AlleleManager.java @@ -0,0 +1,31 @@ +/******************************************************************************* + * Copyright 2011-2014 by SirSengir + * + * This work is licensed under a Creative Commons Attribution-NonCommercial-NoDerivs 3.0 Unported License. + * + * To view a copy of this license, visit http://creativecommons.org/licenses/by-nc-nd/3.0/. + ******************************************************************************/ +package forestry.api.genetics; + +import java.util.HashMap; + +import net.minecraft.item.ItemStack; + +/** + * Holds a static reference to the {@link IAlleleRegistry}. + */ +public class AlleleManager { + /** + * Main access point for all things related to genetics. See {@link IAlleleRegistry} for details. + */ + public static IAlleleRegistry alleleRegistry; + /** + * Translates plain leaf blocks into genetic data. Used by bees and butterflies to convert and pollinate foreign leaf blocks. + */ + public static HashMap ersatzSpecimen = new HashMap(); + /** + * Translates plain saplings into genetic data. Used by the treealyzer and the farm to convert foreign saplings. + */ + public static HashMap ersatzSaplings = new HashMap(); + +} diff --git a/forestry_common/core/forestry/api/genetics/EnumTolerance.java b/forestry_common/core/forestry/api/genetics/EnumTolerance.java new file mode 100755 index 000000000..09d3da3df --- /dev/null +++ b/forestry_common/core/forestry/api/genetics/EnumTolerance.java @@ -0,0 +1,18 @@ +/******************************************************************************* + * Copyright 2011-2014 by SirSengir + * + * This work is licensed under a Creative Commons Attribution-NonCommercial-NoDerivs 3.0 Unported License. + * + * To view a copy of this license, visit http://creativecommons.org/licenses/by-nc-nd/3.0/. + ******************************************************************************/ +package forestry.api.genetics; + +public enum EnumTolerance { + NONE, + + BOTH_1, BOTH_2, BOTH_3, BOTH_4, BOTH_5, + + UP_1, UP_2, UP_3, UP_4, UP_5, + + DOWN_1, DOWN_2, DOWN_3, DOWN_4, DOWN_5 +} diff --git a/forestry_common/core/forestry/api/genetics/IAllele.java b/forestry_common/core/forestry/api/genetics/IAllele.java new file mode 100755 index 000000000..23902f493 --- /dev/null +++ b/forestry_common/core/forestry/api/genetics/IAllele.java @@ -0,0 +1,36 @@ +/******************************************************************************* + * Copyright 2011-2014 by SirSengir + * + * This work is licensed under a Creative Commons Attribution-NonCommercial-NoDerivs 3.0 Unported License. + * + * To view a copy of this license, visit http://creativecommons.org/licenses/by-nc-nd/3.0/. + ******************************************************************************/ +package forestry.api.genetics; + +/** + * An {@link IIndividual}'s {@link IGenome} is composed of {@link IChromosome}s consisting each of a primary and secondary {@link IAllele}. + * + * {@link IAllele}s hold all information regarding an {@link IIndividual}'s traits, from species to size, temperature tolerances, etc. + * + * Should be extended for different types of alleles. ISpeciesAllele, IBiomeAllele, etc. + * + * @author SirSengir + */ +public interface IAllele { + + /** + * @return A unique string identifier for this allele. + */ + String getUID(); + + /** + * @return true if the allele is dominant, false otherwise. + */ + boolean isDominant(); + + /** + * @return Localized short, human-readable identifier used in tooltips and beealyzer. + */ + String getName(); + +} diff --git a/forestry_common/core/forestry/api/genetics/IAlleleArea.java b/forestry_common/core/forestry/api/genetics/IAlleleArea.java new file mode 100755 index 000000000..fd4b0339c --- /dev/null +++ b/forestry_common/core/forestry/api/genetics/IAlleleArea.java @@ -0,0 +1,17 @@ +/******************************************************************************* + * Copyright 2011-2014 by SirSengir + * + * This work is licensed under a Creative Commons Attribution-NonCommercial-NoDerivs 3.0 Unported License. + * + * To view a copy of this license, visit http://creativecommons.org/licenses/by-nc-nd/3.0/. + ******************************************************************************/ +package forestry.api.genetics; + +/** + * Simple interface to allow adding additional alleles containing float values. + */ +public interface IAlleleArea extends IAllele { + + int[] getValue(); + +} diff --git a/forestry_common/core/forestry/api/genetics/IAlleleBoolean.java b/forestry_common/core/forestry/api/genetics/IAlleleBoolean.java new file mode 100755 index 000000000..29a6787e5 --- /dev/null +++ b/forestry_common/core/forestry/api/genetics/IAlleleBoolean.java @@ -0,0 +1,18 @@ +/******************************************************************************* + * Copyright 2011-2014 by SirSengir + * + * This work is licensed under a Creative Commons Attribution-NonCommercial-NoDerivs 3.0 Unported License. + * + * To view a copy of this license, visit http://creativecommons.org/licenses/by-nc-nd/3.0/. + ******************************************************************************/ +package forestry.api.genetics; + +/** + * Simple interface to allow adding additional alleles containing float values. + */ +public interface IAlleleBoolean extends IAllele { + + boolean getValue(); + + +} diff --git a/forestry_common/core/forestry/api/genetics/IAlleleEffect.java b/forestry_common/core/forestry/api/genetics/IAlleleEffect.java new file mode 100755 index 000000000..3c03a7c1c --- /dev/null +++ b/forestry_common/core/forestry/api/genetics/IAlleleEffect.java @@ -0,0 +1,28 @@ +/******************************************************************************* + * Copyright 2011-2014 by SirSengir + * + * This work is licensed under a Creative Commons Attribution-NonCommercial-NoDerivs 3.0 Unported License. + * + * To view a copy of this license, visit http://creativecommons.org/licenses/by-nc-nd/3.0/. + ******************************************************************************/ +package forestry.api.genetics; + +/** + * Basic effect allele. + */ +public interface IAlleleEffect extends IAllele { + /** + * @return true if this effect can combine with the effect on other allele (i.e. run before or after). combination can only occur if both effects are + * combinable. + */ + boolean isCombinable(); + + /** + * Returns the passed data storage if it is valid for this effect or a new one if the passed storage object was invalid for this effect. + * + * @param storedData + * @return {@link IEffectData} for the next cycle. + */ + IEffectData validateStorage(IEffectData storedData); + +} diff --git a/forestry_common/core/forestry/api/genetics/IAlleleFloat.java b/forestry_common/core/forestry/api/genetics/IAlleleFloat.java new file mode 100755 index 000000000..8124f0a76 --- /dev/null +++ b/forestry_common/core/forestry/api/genetics/IAlleleFloat.java @@ -0,0 +1,17 @@ +/******************************************************************************* + * Copyright 2011-2014 by SirSengir + * + * This work is licensed under a Creative Commons Attribution-NonCommercial-NoDerivs 3.0 Unported License. + * + * To view a copy of this license, visit http://creativecommons.org/licenses/by-nc-nd/3.0/. + ******************************************************************************/ +package forestry.api.genetics; + +/** + * Simple interface to allow adding additional alleles containing float values. + */ +public interface IAlleleFloat extends IAllele { + + float getValue(); + +} diff --git a/forestry_common/core/forestry/api/genetics/IAlleleFlowers.java b/forestry_common/core/forestry/api/genetics/IAlleleFlowers.java new file mode 100755 index 000000000..45ef918cb --- /dev/null +++ b/forestry_common/core/forestry/api/genetics/IAlleleFlowers.java @@ -0,0 +1,18 @@ +/******************************************************************************* + * Copyright 2011-2014 by SirSengir + * + * This work is licensed under a Creative Commons Attribution-NonCommercial-NoDerivs 3.0 Unported License. + * + * To view a copy of this license, visit http://creativecommons.org/licenses/by-nc-nd/3.0/. + ******************************************************************************/ +package forestry.api.genetics; + + +public interface IAlleleFlowers extends IAllele { + + /** + * @return FlowerProvider + */ + IFlowerProvider getProvider(); + +} diff --git a/forestry_common/core/forestry/api/genetics/IAlleleHandler.java b/forestry_common/core/forestry/api/genetics/IAlleleHandler.java new file mode 100755 index 000000000..19d829e17 --- /dev/null +++ b/forestry_common/core/forestry/api/genetics/IAlleleHandler.java @@ -0,0 +1,43 @@ +/******************************************************************************* + * Copyright 2011-2014 by SirSengir + * + * This work is licensed under a Creative Commons Attribution-NonCommercial-NoDerivs 3.0 Unported License. + * + * To view a copy of this license, visit http://creativecommons.org/licenses/by-nc-nd/3.0/. + ******************************************************************************/ +package forestry.api.genetics; + +/** + * @author Alex Binnie + * + * Handler for events that occur in IAlleleRegistry, such as registering alleles, branches etc. Useful for handling plugin specific behavior (i.e. + * creating a list of all bee species etc.) + * + */ +public interface IAlleleHandler { + + /** + * Called when an allele is registered with {@link IAlleleRegistry}. + * + * @param allele + * Allele which was registered. + */ + public void onRegisterAllele(IAllele allele); + + /** + * Called when a classification is registered with {@link IAlleleRegistry}. + * + * @param classification + * Classification which was registered. + */ + public void onRegisterClassification(IClassification classification); + + /** + * Called when a fruit family is registered with {@link IAlleleRegistry}. + * + * @param family + * Fruit family which was registered. + */ + public void onRegisterFruitFamily(IFruitFamily family); + +} diff --git a/forestry_common/core/forestry/api/genetics/IAlleleInteger.java b/forestry_common/core/forestry/api/genetics/IAlleleInteger.java new file mode 100755 index 000000000..e45e16b12 --- /dev/null +++ b/forestry_common/core/forestry/api/genetics/IAlleleInteger.java @@ -0,0 +1,17 @@ +/******************************************************************************* + * Copyright 2011-2014 by SirSengir + * + * This work is licensed under a Creative Commons Attribution-NonCommercial-NoDerivs 3.0 Unported License. + * + * To view a copy of this license, visit http://creativecommons.org/licenses/by-nc-nd/3.0/. + ******************************************************************************/ +package forestry.api.genetics; + +/** + * Simple interface to allow adding additional alleles containing integer values. + */ +public interface IAlleleInteger extends IAllele { + + int getValue(); + +} diff --git a/forestry_common/core/forestry/api/genetics/IAllelePlantType.java b/forestry_common/core/forestry/api/genetics/IAllelePlantType.java new file mode 100755 index 000000000..f292b3588 --- /dev/null +++ b/forestry_common/core/forestry/api/genetics/IAllelePlantType.java @@ -0,0 +1,18 @@ +/******************************************************************************* + * Copyright 2011-2014 by SirSengir + * + * This work is licensed under a Creative Commons Attribution-NonCommercial-NoDerivs 3.0 Unported License. + * + * To view a copy of this license, visit http://creativecommons.org/licenses/by-nc-nd/3.0/. + ******************************************************************************/ +package forestry.api.genetics; + +import java.util.EnumSet; + +import net.minecraftforge.common.EnumPlantType; + +public interface IAllelePlantType extends IAllele { + + public EnumSet getPlantTypes(); + +} diff --git a/forestry_common/core/forestry/api/genetics/IAlleleRegistry.java b/forestry_common/core/forestry/api/genetics/IAlleleRegistry.java new file mode 100755 index 000000000..1f0c21177 --- /dev/null +++ b/forestry_common/core/forestry/api/genetics/IAlleleRegistry.java @@ -0,0 +1,229 @@ +/******************************************************************************* + * Copyright 2011-2014 by SirSengir + * + * This work is licensed under a Creative Commons Attribution-NonCommercial-NoDerivs 3.0 Unported License. + * + * To view a copy of this license, visit http://creativecommons.org/licenses/by-nc-nd/3.0/. + ******************************************************************************/ +package forestry.api.genetics; + +import java.util.Collection; +import java.util.Map; + +import net.minecraft.item.ItemStack; +import net.minecraft.world.World; + +import forestry.api.genetics.IClassification.EnumClassLevel; + +/** + * Manages {@link ISpeciesRoot}, {@link IAllele}s, {@link IFruitFamily}s, {@link IClassification}, the blacklist and allows creation of research notes. + * + * @author SirSengir + */ +public interface IAlleleRegistry { + + /* SPECIES ROOT CLASSES */ + /** + * Register a {@link ISpeciesRoot}. + * @param root {@link ISpeciesRoot} to register. + */ + void registerSpeciesRoot(ISpeciesRoot root); + + /** + * @return Map of all registered {@link ISpeciesRoot}. + */ + Map getSpeciesRoot(); + + /** + * Retrieve the {@link ISpeciesRoot} with the given uid. + * @param uid Unique id for the species class, i.e. "rootBees", "rootTrees", "rootButterflies". + * @return {@link ISpeciesRoot} if it exists, null otherwise. + */ + ISpeciesRoot getSpeciesRoot(String uid); + + /** + * Retrieve a matching {@link ISpeciesRoot} for the given itemstack. + * @param stack An itemstack possibly containing NBT data which can be converted by a species root. + * @return {@link ISpeciesRoot} if found, null otherwise. + */ + ISpeciesRoot getSpeciesRoot(ItemStack stack); + + /** + * Retrieve a matching {@link ISpeciesRoot} for the given {@link IIndividual}-class. + * @param clz Class extending {@link IIndividual}. + * @return {@link ISpeciesRoot} if found, null otherwise. + */ + ISpeciesRoot getSpeciesRoot(Class clz); + + /* INDIVIDUAL */ + /** + * Tests the itemstack for genetic information. + * + * @param stack + * @return true if the itemstack is an individual. + */ + boolean isIndividual(ItemStack stack); + + /** + * Retrieve genetic information from an itemstack. + * + * @param stack + * Stack to retrieve genetic information for. + * @return IIndividual containing genetic information, null if none could be extracted. + */ + IIndividual getIndividual(ItemStack stack); + + /* ALLELES */ + + /** + * @return HashMap of all currently registered alleles. + */ + Map getRegisteredAlleles(); + + /** + * Registers an allele. + * + * @param allele + * IAllele to register. + */ + void registerAllele(IAllele allele); + + /** + * @return HashMap of all registered deprecated alleles and their corresponding replacements + */ + Map getDeprecatedAlleleReplacements(); + + /** + * Registers an old allele UID and the new IAllele to replace instances of it with. + * + * @param deprecatedAlleleUID + * the old allele's UID + * @param replacement + * the IAllele that the deprecated Allele will be replaced with. + */ + void registerDeprecatedAlleleReplacement(String deprecatedAlleleUID, IAllele replacement); + + /** + * Gets an allele + * + * @param uid + * String based unique identifier of the allele to retrieve. + * @return IAllele if found or a replacement is found in the Deprecated Allele map, null otherwise. + */ + IAllele getAllele(String uid); + + /* THIS SHOULD BE PHASED OUT */ + @Deprecated + void reloadMetaMap(World world); + + @Deprecated + IAllele getFromMetaMap(int meta); + + @Deprecated + int getFromUIDMap(String uid); + + /* CLASSIFICATIONS */ + /** + * @return HashMap of all currently registered classifications. + */ + Map getRegisteredClassifications(); + + /** + * Registers a classification. + * + * @param classification + * IClassification to register. + */ + void registerClassification(IClassification classification); + + /** + * Creates and returns a classification. + * + * @param level + * EnumClassLevel of the classification to create. + * @param uid + * String based unique identifier. Implementation will throw an exception if the key is already taken. + * @param scientific + * Binomial for the given classification. + * @return Created {@link IClassification} for easier chaining. + */ + IClassification createAndRegisterClassification(EnumClassLevel level, String uid, String scientific); + + /** + * Gets a classification. + * + * @param uid + * String based unique identifier of the classification to retrieve. + * @return {@link IClassification} if found, null otherwise. + */ + IClassification getClassification(String uid); + + /* FRUIT FAMILIES */ + /** + * Get all registered fruit families. + * + * @return A map of registered fruit families and their UIDs. + */ + Map getRegisteredFruitFamilies(); + + /** + * Registers a new fruit family. + * + * @param family + */ + void registerFruitFamily(IFruitFamily family); + + /** + * Retrieves a fruit family identified by uid. + * + * @param uid + * @return {IFruitFamily} if found, false otherwise. + */ + IFruitFamily getFruitFamily(String uid); + + /* ALLELE HANDLERS */ + /** + * Registers a new IAlleleHandler + * + * @param handler + * IAlleleHandler to register. + */ + void registerAlleleHandler(IAlleleHandler handler); + + /* BLACKLIST */ + /** + * Blacklist an allele identified by its UID from mutation. + * + * @param uid + * UID of the allele to blacklist. + */ + void blacklistAllele(String uid); + + /** + * @return Current blacklisted alleles. + */ + Collection getAlleleBlacklist(); + + /** + * @param uid + * UID of the species to vet. + * @return true if the allele is blacklisted. + */ + boolean isBlacklisted(String uid); + + /* RESEARCH */ + /** + * @param researcher Username of the player who researched this note. + * @param species {@link IAlleleSpecies} to encode on the research note. + * @return An itemstack containing a research note with the given species encoded onto it. + */ + ItemStack getSpeciesNoteStack(String researcher, IAlleleSpecies species); + + /** + * @param researcher Username of the player who researched this note. + * @param mutation {@link IMutation} to encode on the research note. + * @return An itemstack containing a research note with the given mutation encoded onto it. + */ + ItemStack getMutationNoteStack(String researcher, IMutation mutation); + +} diff --git a/forestry_common/core/forestry/api/genetics/IAlleleSpecies.java b/forestry_common/core/forestry/api/genetics/IAlleleSpecies.java new file mode 100755 index 000000000..d14082a45 --- /dev/null +++ b/forestry_common/core/forestry/api/genetics/IAlleleSpecies.java @@ -0,0 +1,115 @@ +/******************************************************************************* + * Copyright 2011-2014 by SirSengir + * + * This work is licensed under a Creative Commons Attribution-NonCommercial-NoDerivs 3.0 Unported License. + * + * To view a copy of this license, visit http://creativecommons.org/licenses/by-nc-nd/3.0/. + ******************************************************************************/ +package forestry.api.genetics; + +import net.minecraft.item.ItemStack; +import net.minecraft.world.World; + +import cpw.mods.fml.relauncher.Side; +import cpw.mods.fml.relauncher.SideOnly; + +import forestry.api.core.EnumHumidity; +import forestry.api.core.EnumTemperature; +import forestry.api.core.IIconProvider; + +/** + * Basic species allele. + */ +public interface IAlleleSpecies extends IAllele { + + /** + * @return the {@link ISpeciesRoot} associated with this species. + */ + ISpeciesRoot getRoot(); + + /** + * @return Localized short description of this species. (May be null.) + */ + String getDescription(); + + /** + * Binomial name of the species sans genus ("Apis"). Returning "humboldti" will have the bee species flavour name be "Apis humboldti". Feel free to use fun + * names or return null. + * + * @return flavour text (may be null) + */ + String getBinomial(); + + /** + * Authority for the binomial name, e.g. "Sengir" on species of base Forestry. + * + * @return flavour text (may be null) + */ + String getAuthority(); + + /** + * @return Branch this species is associated with. + */ + IClassification getBranch(); + + /* RESEARCH */ + /** + * Complexity determines the difficulty researching a species. The values of primary and secondary are + * added together (and rounded) to determine the amount of pairs needed for successful research. + * @return Values between 3 - 11 are useful. + */ + int getComplexity(); + + /** + * @param itemstack + * @return A float signifying the chance for the passed itemstack to yield a research success. + */ + float getResearchSuitability(ItemStack itemstack); + + /** + * @param world + * @param researcher + * @param individual + * @param bountyLevel + * @return Array of itemstacks representing the bounty for this research success. + */ + ItemStack[] getResearchBounty(World world, String researcher, IIndividual individual, int bountyLevel); + + /* CLIMATE */ + /** + * @return Preferred temperature + */ + EnumTemperature getTemperature(); + + /** + * @return Preferred humidity + */ + EnumHumidity getHumidity(); + + /* MISC */ + /** + * @return true if the species icon should have a glowing effect. + */ + boolean hasEffect(); + + /** + * @return true if the species should not be displayed in NEI or creative inventory. + */ + boolean isSecret(); + + /** + * @return true to have the species count against the species total. + */ + boolean isCounted(); + + /* APPEARANCE */ + /** + * @param renderPass Render pass to get the colour for. + * @return Colour to use for the render pass. + */ + int getIconColour(int renderPass); + + @SideOnly(Side.CLIENT) + IIconProvider getIconProvider(); + +} diff --git a/forestry_common/core/forestry/api/genetics/IAlleleTolerance.java b/forestry_common/core/forestry/api/genetics/IAlleleTolerance.java new file mode 100755 index 000000000..e00d9fd28 --- /dev/null +++ b/forestry_common/core/forestry/api/genetics/IAlleleTolerance.java @@ -0,0 +1,17 @@ +/******************************************************************************* + * Copyright 2011-2014 by SirSengir + * + * This work is licensed under a Creative Commons Attribution-NonCommercial-NoDerivs 3.0 Unported License. + * + * To view a copy of this license, visit http://creativecommons.org/licenses/by-nc-nd/3.0/. + ******************************************************************************/ +package forestry.api.genetics; + +/** + * Simple interface to allow adding additional alleles containing float values. + */ +public interface IAlleleTolerance extends IAllele { + + EnumTolerance getValue(); + +} diff --git a/forestry_common/core/forestry/api/genetics/IBreedingTracker.java b/forestry_common/core/forestry/api/genetics/IBreedingTracker.java new file mode 100755 index 000000000..b8b5a8d7d --- /dev/null +++ b/forestry_common/core/forestry/api/genetics/IBreedingTracker.java @@ -0,0 +1,101 @@ +/******************************************************************************* + * Copyright 2011-2014 by SirSengir + * + * This work is licensed under a Creative Commons Attribution-NonCommercial-NoDerivs 3.0 Unported License. + * + * To view a copy of this license, visit http://creativecommons.org/licenses/by-nc-nd/3.0/. + ******************************************************************************/ +package forestry.api.genetics; + +import net.minecraft.entity.player.EntityPlayer; +import net.minecraft.nbt.NBTTagCompound; + +import forestry.api.apiculture.IBeekeepingMode; + +/** + * Keeps track of who bred and/or discovered which species in a world. + * + * @author SirSengir + */ +public interface IBreedingTracker { + + /** + * @return Name of the current {@link IBeekeepingMode}. + */ + String getModeName(); + + /** + * Set the current {@link IBeekeepingMode}. + */ + void setModeName(String name); + + /** + * @return Amount of species discovered. + */ + int getSpeciesBred(); + + /** + * Register the birth of an individual. Will mark it as discovered. + * + * @param individual + */ + void registerBirth(IIndividual individual); + + /** + * Register the pickup of an individual. + * + * @param individual + */ + void registerPickup(IIndividual individual); + + /** + * Marks a species as discovered. Should only be called from registerIndividual normally. + * + * @param species + */ + void registerSpecies(IAlleleSpecies species); + + /** + * Register a successful mutation. Will mark it as discovered. + */ + @Deprecated + void registerMutation(IAllele allele0, IAllele allele1); + + /** + * Register a successful mutation. Will mark it as discovered. + * + * @param mutation + */ + void registerMutation(IMutation mutation); + + /** + * Queries the tracker for discovered species. + * + * @param mutation + * Mutation to query for. + * @return true if the mutation has been discovered. + */ + boolean isDiscovered(IMutation mutation); + + /** + * Queries the tracker for discovered species. + * + * @param species + * Species to check. + * @return true if the species has been bred. + */ + boolean isDiscovered(IAlleleSpecies species); + + /** + * Synchronizes the tracker to the client side. Should be called before opening any gui needing that information. + * + * @param player + */ + void synchToPlayer(EntityPlayer player); + + /* LOADING & SAVING */ + void decodeFromNBT(NBTTagCompound nbttagcompound); + + void encodeToNBT(NBTTagCompound nbttagcompound); + +} diff --git a/forestry_common/core/forestry/api/genetics/IChromosome.java b/forestry_common/core/forestry/api/genetics/IChromosome.java new file mode 100755 index 000000000..2e01f4008 --- /dev/null +++ b/forestry_common/core/forestry/api/genetics/IChromosome.java @@ -0,0 +1,27 @@ +/******************************************************************************* + * Copyright 2011-2014 by SirSengir + * + * This work is licensed under a Creative Commons Attribution-NonCommercial-NoDerivs 3.0 Unported License. + * + * To view a copy of this license, visit http://creativecommons.org/licenses/by-nc-nd/3.0/. + ******************************************************************************/ +package forestry.api.genetics; + +import forestry.api.core.INBTTagable; + +/** + * Implementations other than Forestry's default one are not supported! + * + * @author SirSengir + */ +public interface IChromosome extends INBTTagable { + + IAllele getPrimaryAllele(); + + IAllele getSecondaryAllele(); + + IAllele getInactiveAllele(); + + IAllele getActiveAllele(); + +} diff --git a/forestry_common/core/forestry/api/genetics/IChromosomeType.java b/forestry_common/core/forestry/api/genetics/IChromosomeType.java new file mode 100755 index 000000000..faaf7a188 --- /dev/null +++ b/forestry_common/core/forestry/api/genetics/IChromosomeType.java @@ -0,0 +1,26 @@ +/******************************************************************************* + * Copyright 2011-2014 by SirSengir + * + * This work is licensed under a Creative Commons Attribution-NonCommercial-NoDerivs 3.0 Unported License. + * + * To view a copy of this license, visit http://creativecommons.org/licenses/by-nc-nd/3.0/. + ******************************************************************************/ +package forestry.api.genetics; + +/* + * Interface to be implemented by the enums representing the various chromosomes + */ +public interface IChromosomeType { + + /* + * Get class which all alleles on this chromosome must interface + */ + Class getAlleleClass(); + + String getName(); + + ISpeciesRoot getSpeciesRoot(); + + int ordinal(); + +} diff --git a/forestry_common/core/forestry/api/genetics/IClassification.java b/forestry_common/core/forestry/api/genetics/IClassification.java new file mode 100755 index 000000000..69526bca8 --- /dev/null +++ b/forestry_common/core/forestry/api/genetics/IClassification.java @@ -0,0 +1,109 @@ +/******************************************************************************* + * Copyright 2011-2014 by SirSengir + * + * This work is licensed under a Creative Commons Attribution-NonCommercial-NoDerivs 3.0 Unported License. + * + * To view a copy of this license, visit http://creativecommons.org/licenses/by-nc-nd/3.0/. + ******************************************************************************/ +package forestry.api.genetics; + +/** + * Biological classifications from domain down to genus. + * + * Used by the *alyzers to display hierarchies. + */ +public interface IClassification { + + public enum EnumClassLevel { + + DOMAIN(0x777fff, true), KINGDOM(0x77c3ff), PHYLUM(0x77ffb6, true), DIVISION(0x77ffb6, true), CLASS(0x7bff77), ORDER(0xbeff77), FAMILY(0xfffd77), + SUBFAMILY(0xfffd77), TRIBE(0xfffd77), GENUS(0xffba77); + + private int colour; + private boolean isDroppable; + + private EnumClassLevel(int colour) { + this(colour, false); + } + + private EnumClassLevel(int colour, boolean isDroppable) { + this.colour = colour; + this.isDroppable = isDroppable; + } + + /** + * @return Colour to use for displaying this classification. + */ + public int getColour() { + return colour; + } + + /** + * @return Indicates whether display of this classification level can be ommitted in case of space constraints. + */ + public boolean isDroppable() { + return isDroppable; + } + } + + /** + * @return Level inside the full hierarchy this particular classification is located at. + */ + EnumClassLevel getLevel(); + + /** + * @return Unique String identifier. + */ + String getUID(); + + /** + * @return Localized branch name for user display. + */ + String getName(); + + /** + * A branch approximates a "genus" in real life. Real life examples: "Micrapis", "Megapis" + * + * @return flavour text (may be null) + */ + String getScientific(); + + /** + * @return Localized description of this branch. (May be null.) + */ + String getDescription(); + + /** + * @return Member groups of this one. + */ + IClassification[] getMemberGroups(); + + /** + * Adds subgroups to this group. + */ + void addMemberGroup(IClassification group); + + /** + * @return Member species of this group. + */ + IAlleleSpecies[] getMemberSpecies(); + + /** + * Used by the allele registry to populate internal collection of branch members on the fly. + * + * @param species + */ + void addMemberSpecies(IAlleleSpecies species); + + /** + * @return Parent classification, null if this is root. + */ + IClassification getParent(); + + /** + * Only used internally by the AlleleRegistry if this classification has been added to another one. + * + * @param parent + */ + void setParent(IClassification parent); +} diff --git a/forestry_common/core/forestry/api/genetics/IEffectData.java b/forestry_common/core/forestry/api/genetics/IEffectData.java new file mode 100755 index 000000000..33137f1fe --- /dev/null +++ b/forestry_common/core/forestry/api/genetics/IEffectData.java @@ -0,0 +1,29 @@ +/******************************************************************************* + * Copyright 2011-2014 by SirSengir + * + * This work is licensed under a Creative Commons Attribution-NonCommercial-NoDerivs 3.0 Unported License. + * + * To view a copy of this license, visit http://creativecommons.org/licenses/by-nc-nd/3.0/. + ******************************************************************************/ +package forestry.api.genetics; + +import forestry.api.core.INBTTagable; + +/** + * Container to hold some temporary data for bee, tree and butterfly effects. + * + * @author SirSengir + */ +public interface IEffectData extends INBTTagable { + void setInteger(int index, int val); + + void setFloat(int index, float val); + + void setBoolean(int index, boolean val); + + int getInteger(int index); + + float getFloat(int index); + + boolean getBoolean(int index); +} diff --git a/forestry_common/core/forestry/api/genetics/IFlowerProvider.java b/forestry_common/core/forestry/api/genetics/IFlowerProvider.java new file mode 100755 index 000000000..58d3e76b8 --- /dev/null +++ b/forestry_common/core/forestry/api/genetics/IFlowerProvider.java @@ -0,0 +1,58 @@ +/******************************************************************************* + * Copyright 2011-2014 by SirSengir + * + * This work is licensed under a Creative Commons Attribution-NonCommercial-NoDerivs 3.0 Unported License. + * + * To view a copy of this license, visit http://creativecommons.org/licenses/by-nc-nd/3.0/. + ******************************************************************************/ +package forestry.api.genetics; + +import net.minecraft.item.ItemStack; +import net.minecraft.world.World; + +public interface IFlowerProvider { + /** + * @param world + * @param individual + * @param x + * @param y + * @param z + * @return True if the block at the passed coordinates is a valid flower for the species. + */ + boolean isAcceptedFlower(World world, IIndividual individual, int x, int y, int z); + + boolean isAcceptedPollinatable(World world, IPollinatable pollinatable); + + /** + * @param world + * @param individual + * @param x + * @param y + * @param z + * @return True if a flower was planted. + */ + boolean growFlower(World world, IIndividual individual, int x, int y, int z); + + /** + * @return Short, human-readable identifier used in the beealyzer. + */ + String getDescription(); + + /** + * Allows the flower provider to affect the produce at the given location. + * @param world + * @param individual + * @param x + * @param y + * @param z + * @param products + * @return Array of itemstacks being the (modified or unmodified) produce. + */ + ItemStack[] affectProducts(World world, IIndividual individual, int x, int y, int z, ItemStack[] products); + + /** + * @return Array of itemstacks representing valid flowers for the flower provider. The first in the array is for use as an icon Return null or an empty + * array if the flower does not have an itemstack + */ + ItemStack[] getItemStacks(); +} diff --git a/forestry_common/core/forestry/api/genetics/IFruitBearer.java b/forestry_common/core/forestry/api/genetics/IFruitBearer.java new file mode 100755 index 000000000..8d8463a2a --- /dev/null +++ b/forestry_common/core/forestry/api/genetics/IFruitBearer.java @@ -0,0 +1,52 @@ +/******************************************************************************* + * Copyright 2011-2014 by SirSengir + * + * This work is licensed under a Creative Commons Attribution-NonCommercial-NoDerivs 3.0 Unported License. + * + * To view a copy of this license, visit http://creativecommons.org/licenses/by-nc-nd/3.0/. + ******************************************************************************/ +package forestry.api.genetics; + +import java.util.Collection; + +import net.minecraft.item.ItemStack; + +/** + * Can be implemented by tile entities which can bear fruit. + * + * @author SirSengir + */ +public interface IFruitBearer { + + /** + * @return true if the actual tile can bear fruits. + */ + boolean hasFruit(); + + /** + * @return Family of the potential fruits on this tile. + */ + IFruitFamily getFruitFamily(); + + /** + * Picks the fruits of this tile, resetting it to unripe fruits. + * + * @param tool + * Tool used in picking the fruits. May be null. + * @return Picked fruits. + */ + Collection pickFruit(ItemStack tool); + + /** + * @return float indicating the ripeness of the fruit with >= 1.0f indicating full ripeness. + */ + float getRipeness(); + + /** + * Increases the ripeness of the fruit. + * + * @param add + * Float to add to the ripeness. Will truncate to valid values. + */ + void addRipeness(float add); +} diff --git a/forestry_common/core/forestry/api/genetics/IFruitFamily.java b/forestry_common/core/forestry/api/genetics/IFruitFamily.java new file mode 100755 index 000000000..cf5322ba0 --- /dev/null +++ b/forestry_common/core/forestry/api/genetics/IFruitFamily.java @@ -0,0 +1,34 @@ +/******************************************************************************* + * Copyright 2011-2014 by SirSengir + * + * This work is licensed under a Creative Commons Attribution-NonCommercial-NoDerivs 3.0 Unported License. + * + * To view a copy of this license, visit http://creativecommons.org/licenses/by-nc-nd/3.0/. + ******************************************************************************/ +package forestry.api.genetics; + +public interface IFruitFamily { + + /** + * @return Unique String identifier. + */ + String getUID(); + + /** + * @return Localized family name for user display. + */ + String getName(); + + /** + * A scientific-y name for this fruit family + * + * @return flavour text (may be null) + */ + String getScientific(); + + /** + * @return Localized description of this fruit family. (May be null.) + */ + String getDescription(); + +} diff --git a/forestry_common/core/forestry/api/genetics/IGenome.java b/forestry_common/core/forestry/api/genetics/IGenome.java new file mode 100755 index 000000000..03e2dd226 --- /dev/null +++ b/forestry_common/core/forestry/api/genetics/IGenome.java @@ -0,0 +1,32 @@ +/******************************************************************************* + * Copyright 2011-2014 by SirSengir + * + * This work is licensed under a Creative Commons Attribution-NonCommercial-NoDerivs 3.0 Unported License. + * + * To view a copy of this license, visit http://creativecommons.org/licenses/by-nc-nd/3.0/. + ******************************************************************************/ +package forestry.api.genetics; + +import forestry.api.core.INBTTagable; + +/** + * Holds the {@link IChromosome}s which comprise the traits of a given individual. + * + * Only the default implementation is supported. + */ +public interface IGenome extends INBTTagable { + + IAlleleSpecies getPrimary(); + + IAlleleSpecies getSecondary(); + + IChromosome[] getChromosomes(); + + IAllele getActiveAllele(int chromosome); + + IAllele getInactiveAllele(int chromosome); + + boolean isGeneticEqual(IGenome other); + + ISpeciesRoot getSpeciesRoot(); +} diff --git a/forestry_common/core/forestry/api/genetics/IHousing.java b/forestry_common/core/forestry/api/genetics/IHousing.java new file mode 100755 index 000000000..c89aee2f0 --- /dev/null +++ b/forestry_common/core/forestry/api/genetics/IHousing.java @@ -0,0 +1,54 @@ +/******************************************************************************* + * Copyright 2011-2014 by SirSengir + * + * This work is licensed under a Creative Commons Attribution-NonCommercial-NoDerivs 3.0 Unported License. + * + * To view a copy of this license, visit http://creativecommons.org/licenses/by-nc-nd/3.0/. + ******************************************************************************/ +package forestry.api.genetics; + +import net.minecraft.item.ItemStack; +import net.minecraft.world.World; + +import forestry.api.core.EnumHumidity; +import forestry.api.core.EnumTemperature; + +/** + * Any housing, hatchery or nest which is a fixed location in the world. + */ +public interface IHousing { + + /** + * @return String containing the login of this housing's owner. + */ + String getOwnerName(); + + World getWorld(); + + int getXCoord(); + + int getYCoord(); + + int getZCoord(); + + int getBiomeId(); + + EnumTemperature getTemperature(); + + EnumHumidity getHumidity(); + + void setErrorState(int state); + + int getErrorOrdinal(); + + /** + * Adds products to the housing's inventory. + * + * @param product + * ItemStack with the product to add. + * @param all + * @return Boolean indicating success or failure. + */ + boolean addProduct(ItemStack product, boolean all); + +} diff --git a/forestry_common/core/forestry/api/genetics/IIndividual.java b/forestry_common/core/forestry/api/genetics/IIndividual.java new file mode 100755 index 000000000..a4cdd3a4d --- /dev/null +++ b/forestry_common/core/forestry/api/genetics/IIndividual.java @@ -0,0 +1,59 @@ +/******************************************************************************* + * Copyright 2011-2014 by SirSengir + * + * This work is licensed under a Creative Commons Attribution-NonCommercial-NoDerivs 3.0 Unported License. + * + * To view a copy of this license, visit http://creativecommons.org/licenses/by-nc-nd/3.0/. + ******************************************************************************/ +package forestry.api.genetics; + +import java.util.List; + +import forestry.api.core.INBTTagable; + +/** + * An actual individual with genetic information. + * + * Only the default implementation is supported. + */ +public interface IIndividual extends INBTTagable { + + String getIdent(); + + String getDisplayName(); + + void addTooltip(List list); + + /** + * Call to mark the IIndividual as analyzed. + * @return true if the IIndividual has not been analyzed previously. + */ + boolean analyze(); + + boolean isAnalyzed(); + + boolean hasEffect(); + + boolean isSecret(); + + IGenome getGenome(); + + /** + * Check whether the genetic makeup of two IIndividuals is identical. Ignores additional data like generations, irregular mating, etc.. + * @param other + * @return true if the given other IIndividual has the amount of chromosomes and their alleles are identical. + */ + boolean isGeneticEqual(IIndividual other); + + /** + * @return A deep copy of this individual. + */ + IIndividual copy(); + + /** + * @param chromosomeOrdinal Ordinal of the chromosome to check. + * @return true if both primary and secondary allele on the given chromosome match. + */ + boolean isPureBred(int chromosomeOrdinal); + +} diff --git a/forestry_common/core/forestry/api/genetics/IIndividualLiving.java b/forestry_common/core/forestry/api/genetics/IIndividualLiving.java new file mode 100755 index 000000000..6898c74eb --- /dev/null +++ b/forestry_common/core/forestry/api/genetics/IIndividualLiving.java @@ -0,0 +1,47 @@ +/******************************************************************************* + * Copyright 2011-2014 by SirSengir + * + * This work is licensed under a Creative Commons Attribution-NonCommercial-NoDerivs 3.0 Unported License. + * + * To view a copy of this license, visit http://creativecommons.org/licenses/by-nc-nd/3.0/. + ******************************************************************************/ +package forestry.api.genetics; + +import net.minecraft.world.World; + +public interface IIndividualLiving extends IIndividual { + + /** + * @return Genetic information of the mate, null if unmated. + */ + IGenome getMate(); + + /** + * @return Current health of the individual. + */ + int getHealth(); + + /** + * @return Maximum health of the individual. + */ + int getMaxHealth(); + + /** + * Age the individual. + * @param world + * @param ageModifier + */ + void age(World world, float ageModifier); + + /** + * Mate with the given individual. + * @param individual the {@link IIndividual} to mate this one with. + */ + void mate(IIndividual individual); + + /** + * @return true if the individual is among the living. + */ + boolean isAlive(); + +} diff --git a/forestry_common/core/forestry/api/genetics/ILegacyHandler.java b/forestry_common/core/forestry/api/genetics/ILegacyHandler.java new file mode 100755 index 000000000..08a015858 --- /dev/null +++ b/forestry_common/core/forestry/api/genetics/ILegacyHandler.java @@ -0,0 +1,17 @@ +/******************************************************************************* + * Copyright 2011-2014 by SirSengir + * + * This work is licensed under a Creative Commons Attribution-NonCommercial-NoDerivs 3.0 Unported License. + * + * To view a copy of this license, visit http://creativecommons.org/licenses/by-nc-nd/3.0/. + ******************************************************************************/ +package forestry.api.genetics; + +/** + * AlleleManager.alleleRegistry can be cast to this type. + */ +public interface ILegacyHandler { + void registerLegacyMapping(int id, String uid); + + IAllele getFromLegacyMap(int id); +} diff --git a/forestry_common/core/forestry/api/genetics/IMutation.java b/forestry_common/core/forestry/api/genetics/IMutation.java new file mode 100755 index 000000000..21ef0a08a --- /dev/null +++ b/forestry_common/core/forestry/api/genetics/IMutation.java @@ -0,0 +1,70 @@ +/******************************************************************************* + * Copyright 2011-2014 by SirSengir + * + * This work is licensed under a Creative Commons Attribution-NonCommercial-NoDerivs 3.0 Unported License. + * + * To view a copy of this license, visit http://creativecommons.org/licenses/by-nc-nd/3.0/. + ******************************************************************************/ +package forestry.api.genetics; + +import java.util.Collection; + +/** + * Individuals can be seeded either as hive drops or as mutation results. + * + * {@link IAlleleRegistry} manages these. + * + * @author SirSengir + */ +public interface IMutation { + + /** + * @return {@link ISpeciesRoot} this mutation is associated with. + */ + ISpeciesRoot getRoot(); + + /** + * @return first of the alleles implementing IAlleleSpecies required for this mutation. + */ + IAllele getAllele0(); + + /** + * @return second of the alleles implementing IAlleleSpecies required for this mutation. + */ + IAllele getAllele1(); + + /** + * @return Array of {@link IAllele} representing the full default genome of the mutated side. + * + * Make sure to return a proper array for the species class. Returning an allele of the wrong type will cause cast errors on runtime. + */ + IAllele[] getTemplate(); + + /** + * @return Unmodified base chance for mutation to fire. + */ + float getBaseChance(); + + /** + * @return Collection of localized, human-readable strings describing special mutation conditions, if any. + */ + Collection getSpecialConditions(); + + /** + * @param allele + * @return true if the passed allele is one of the alleles participating in this mutation. + */ + boolean isPartner(IAllele allele); + + /** + * @param allele + * @return the other allele which was not passed as argument. + */ + IAllele getPartner(IAllele allele); + + /** + * @return true if the mutation should not be displayed in the beealyzer. + */ + boolean isSecret(); + +} diff --git a/forestry_common/core/forestry/api/genetics/IPollinatable.java b/forestry_common/core/forestry/api/genetics/IPollinatable.java new file mode 100755 index 000000000..270421b0a --- /dev/null +++ b/forestry_common/core/forestry/api/genetics/IPollinatable.java @@ -0,0 +1,50 @@ +/******************************************************************************* + * Copyright 2011-2014 by SirSengir + * + * This work is licensed under a Creative Commons Attribution-NonCommercial-NoDerivs 3.0 Unported License. + * + * To view a copy of this license, visit http://creativecommons.org/licenses/by-nc-nd/3.0/. + ******************************************************************************/ +package forestry.api.genetics; + +import java.util.EnumSet; + +import net.minecraftforge.common.EnumPlantType; + +/** + * Can be implemented by tile entities, if they wish to be pollinatable. + * + * @author SirSengir + */ +public interface IPollinatable { + + /** + * @return plant types this pollinatable is classified as. (Can be used by bees to determine whether to interact or not. + */ + EnumSet getPlantType(); + + /** + * @return IIndividual containing the genetic information of this IPollinatable + */ + IIndividual getPollen(); + + /** + * Checks whether this {@link IPollinatable} can mate with the given pollen. + * + * Must be the one to check genetic equivalency. + * + * @param pollen + * IIndividual representing the pollen. + * @return true if mating is possible, false otherwise. + */ + boolean canMateWith(IIndividual pollen); + + /** + * Pollinates this entity. + * + * @param pollen + * IIndividual representing the pollen. + */ + void mateWith(IIndividual pollen); + +} diff --git a/forestry_common/core/forestry/api/genetics/ISpeciesRoot.java b/forestry_common/core/forestry/api/genetics/ISpeciesRoot.java new file mode 100755 index 000000000..2ac219a2d --- /dev/null +++ b/forestry_common/core/forestry/api/genetics/ISpeciesRoot.java @@ -0,0 +1,167 @@ +/******************************************************************************* + * Copyright 2011-2014 by SirSengir + * + * This work is licensed under a Creative Commons Attribution-NonCommercial-NoDerivs 3.0 Unported License. + * + * To view a copy of this license, visit http://creativecommons.org/licenses/by-nc-nd/3.0/. + ******************************************************************************/ +package forestry.api.genetics; + +import java.util.ArrayList; +import java.util.Collection; +import java.util.Map; +import java.util.Random; + +import net.minecraft.item.ItemStack; +import net.minecraft.nbt.NBTTagCompound; +import net.minecraft.world.World; + +/** + * Describes a class of species (i.e. bees, trees, butterflies), provides helper functions and access to common functionality. + */ +public interface ISpeciesRoot { + + /** + * @return A unique identifier for the species class. Should consist of "root" + a common name for the species class in camel-case, i.e. "rootBees", "rootTrees", "rootButterflies". + */ + String getUID(); + + /** + * @return Class of the sub-interface inheriting from {@link IIndividual}. + */ + Class getMemberClass(); + + /** + * @return Integer denoting the number of (counted) species of this type in the world. + */ + int getSpeciesCount(); + + /** + * Used to check whether a given itemstack contains genetic data corresponding to an {@link IIndividual} of this class. + * @param stack itemstack to check. + * @return true if the itemstack contains an {@link IIndividual} of this class, false otherwise. + */ + boolean isMember(ItemStack stack); + + /** + * Used to check whether a given itemstack contains genetic data corresponding to an {@link IIndividual} of this class and matches the given type. + * @param stack itemstack to check. + * @param type Integer denoting the type needed to match. (i.e. butterfly vs. butterfly serum; bee queens, princesses, drones; etc.) + * @return true if the itemstack contains an {@link IIndividual} of this class, false otherwise. + */ + boolean isMember(ItemStack stack, int type); + + /** + * Used to check whether the given {@link IIndividual} is member of this class. + * @param individual {@link IIndividual} to check. + * @return true if the individual is member of this class, false otherwise. + */ + boolean isMember(IIndividual individual); + + IIndividual getMember(ItemStack stack); + + IIndividual getMember(NBTTagCompound compound); + + ItemStack getMemberStack(IIndividual individual, int type); + + /* BREEDING TRACKER */ + IBreedingTracker getBreedingTracker(World world, String player); + + /* GENOME MANIPULATION */ + IIndividual templateAsIndividual(IAllele[] template); + + IIndividual templateAsIndividual(IAllele[] templateActive, IAllele[] templateInactive); + + IChromosome[] templateAsChromosomes(IAllele[] template); + + IChromosome[] templateAsChromosomes(IAllele[] templateActive, IAllele[] templateInactive); + + IGenome templateAsGenome(IAllele[] template); + + IGenome templateAsGenome(IAllele[] templateActive, IAllele[] templateInactive); + + /* TEMPLATES */ + /** + * Registers a bee template using the UID of the first allele as identifier. + * + * @param template + */ + void registerTemplate(IAllele[] template); + + /** + * Registers a bee template using the passed identifier. + * + * @param template + */ + void registerTemplate(String identifier, IAllele[] template); + + /** + * Retrieves a registered template using the passed identifier. + * + * @param identifier + * @return Array of {@link IAllele} representing a genome. + */ + IAllele[] getTemplate(String identifier); + + /** + * @return Default individual template for use when stuff breaks. + */ + IAllele[] getDefaultTemplate(); + + /** + * @param rand Random to use. + * @return A random template from the pool of registered species templates. + */ + IAllele[] getRandomTemplate(Random rand); + + Map getGenomeTemplates(); + ArrayList getIndividualTemplates(); + + /* MUTATIONS */ + /** + * Use to register mutations. + * + * @param mutation + */ + void registerMutation(IMutation mutation); + + /** + * @return All registered mutations. + */ + Collection getMutations(boolean shuffle); + + /** + * @param other Allele to match mutations against. + * @return All registered mutations the given allele is part of. + */ + Collection getCombinations(IAllele other); + + /** + * @param result {@link IAllele} to search for. + * @return All registered mutations the given {@link IAllele} is the result of. + */ + Collection getPaths(IAllele result, int chromosomeOrdinal); + + /* RESEARCH */ + /** + * @return List of generic catalysts which should be accepted for research by species of this class. + */ + Map getResearchCatalysts(); + + /** + * Sets an item stack as a valid (generic) research catalyst for this class. + * @param itemstack ItemStack to set as suitable. + * @param suitability Float between 0 and 1 to indicate suitability. + */ + void setResearchSuitability(ItemStack itemstack, float suitability); + + /** + * @return Array of {@link IChromosomeType} which are in this species genome + */ + IChromosomeType[] getKaryotype(); + + /** + * @return {@link IChromosomeType} which is the "key" for this species class, usually the species chromosome. + */ + IChromosomeType getKaryotypeKey(); +} diff --git a/forestry_common/core/forestry/api/genetics/package-info.java b/forestry_common/core/forestry/api/genetics/package-info.java new file mode 100755 index 000000000..a876fa19d --- /dev/null +++ b/forestry_common/core/forestry/api/genetics/package-info.java @@ -0,0 +1,10 @@ +/******************************************************************************* + * Copyright 2011-2014 by SirSengir + * + * This work is licensed under a Creative Commons Attribution-NonCommercial-NoDerivs 3.0 Unported License. + * + * To view a copy of this license, visit http://creativecommons.org/licenses/by-nc-nd/3.0/. + ******************************************************************************/ +@API(apiVersion="1.0", owner="ForestryAPI|core", provides="ForestryAPI|genetics") +package forestry.api.genetics; +import cpw.mods.fml.common.API; diff --git a/forestry_common/core/forestry/api/lepidopterology/EnumButterflyChromosome.java b/forestry_common/core/forestry/api/lepidopterology/EnumButterflyChromosome.java new file mode 100755 index 000000000..92b565d3c --- /dev/null +++ b/forestry_common/core/forestry/api/lepidopterology/EnumButterflyChromosome.java @@ -0,0 +1,100 @@ +/******************************************************************************* + * Copyright 2011-2014 by SirSengir + * + * This work is licensed under a Creative Commons Attribution-NonCommercial-NoDerivs 3.0 Unported License. + * + * To view a copy of this license, visit http://creativecommons.org/licenses/by-nc-nd/3.0/. + ******************************************************************************/ +package forestry.api.lepidopterology; + +import forestry.api.genetics.AlleleManager; +import forestry.api.genetics.IAllele; +import forestry.api.genetics.IAlleleArea; +import forestry.api.genetics.IAlleleBoolean; +import forestry.api.genetics.IAlleleFloat; +import forestry.api.genetics.IAlleleFlowers; +import forestry.api.genetics.IAlleleInteger; +import forestry.api.genetics.IAlleleTolerance; +import forestry.api.genetics.IChromosomeType; +import forestry.api.genetics.ISpeciesRoot; + +public enum EnumButterflyChromosome implements IChromosomeType { + /** + * Species of the bee. Alleles here must implement {@link IAlleleButterflySpecies}. + */ + SPECIES(IAlleleButterflySpecies.class), + /** + * Physical size. + */ + SIZE(IAlleleFloat.class), + /** + * Flight speed. + */ + SPEED(IAlleleFloat.class), + /** + * How long the butterfly can last without access to matching pollinatables. + */ + LIFESPAN(IAlleleInteger.class), + /** + * Species with a higher metabolism have a higher appetite and may cause more damage to their environment. + */ + METABOLISM(IAlleleInteger.class), + /** + * Determines likelyhood of caterpillars and length of caterpillar/pupation phase. Also: Number of max caterpillars after mating? + */ + FERTILITY(IAlleleInteger.class), + /** + * Not sure yet. + */ + TEMPERATURE_TOLERANCE(IAlleleTolerance.class), + /** + * Not sure yet. + */ + HUMIDITY_TOLERANCE(IAlleleTolerance.class), + /** + * Only nocturnal butterflys/moths will fly at night. Allows daylight activity for naturally nocturnal species. + */ + NOCTURNAL(IAlleleBoolean.class), + /** + * Only tolerant flyers will fly in the rain. + */ + TOLERANT_FLYER(IAlleleBoolean.class), + /** + * Fire resistance. + */ + FIRE_RESIST(IAlleleBoolean.class), + /** + * Required flowers/leaves. + */ + FLOWER_PROVIDER(IAlleleFlowers.class), + /** + * Extra effect to surroundings. (?) + */ + EFFECT(IAlleleButterflyEffect.class), + /** + * Not used yet + */ + TERRITORY(IAlleleArea.class), + ; + + Class clss; + + EnumButterflyChromosome(Class clss) { + this.clss = clss; + } + + @Override + public Class getAlleleClass() { + return clss; + } + + @Override + public String getName() { + return this.toString().toLowerCase(); + } + + @Override + public ISpeciesRoot getSpeciesRoot() { + return AlleleManager.alleleRegistry.getSpeciesRoot("rootButterflies"); + } +} diff --git a/forestry_common/core/forestry/api/lepidopterology/EnumFlutterType.java b/forestry_common/core/forestry/api/lepidopterology/EnumFlutterType.java new file mode 100755 index 000000000..037c75a12 --- /dev/null +++ b/forestry_common/core/forestry/api/lepidopterology/EnumFlutterType.java @@ -0,0 +1,17 @@ +/******************************************************************************* + * Copyright 2011-2014 by SirSengir + * + * This work is licensed under a Creative Commons Attribution-NonCommercial-NoDerivs 3.0 Unported License. + * + * To view a copy of this license, visit http://creativecommons.org/licenses/by-nc-nd/3.0/. + ******************************************************************************/ +package forestry.api.lepidopterology; + +public enum EnumFlutterType { + BUTTERFLY, + SERUM, + CATERPILLAR, + NONE; + + public static final EnumFlutterType[] VALUES = values(); +} diff --git a/forestry_common/core/forestry/api/lepidopterology/IAlleleButterflyEffect.java b/forestry_common/core/forestry/api/lepidopterology/IAlleleButterflyEffect.java new file mode 100755 index 000000000..a37430005 --- /dev/null +++ b/forestry_common/core/forestry/api/lepidopterology/IAlleleButterflyEffect.java @@ -0,0 +1,23 @@ +/******************************************************************************* + * Copyright 2011-2014 by SirSengir + * + * This work is licensed under a Creative Commons Attribution-NonCommercial-NoDerivs 3.0 Unported License. + * + * To view a copy of this license, visit http://creativecommons.org/licenses/by-nc-nd/3.0/. + ******************************************************************************/ +package forestry.api.lepidopterology; + +import forestry.api.genetics.IAlleleEffect; +import forestry.api.genetics.IEffectData; + +public interface IAlleleButterflyEffect extends IAlleleEffect { + + /** + * Used by butterflies to trigger effects in the world. + * @param butterfly {@link IEntityButterfly} + * @param storedData + * @return {@link forestry.api.genetics.IEffectData} for the next cycle. + */ + IEffectData doEffect(IEntityButterfly butterfly, IEffectData storedData); + +} diff --git a/forestry_common/core/forestry/api/lepidopterology/IAlleleButterflySpecies.java b/forestry_common/core/forestry/api/lepidopterology/IAlleleButterflySpecies.java new file mode 100755 index 000000000..2b5e6fb9d --- /dev/null +++ b/forestry_common/core/forestry/api/lepidopterology/IAlleleButterflySpecies.java @@ -0,0 +1,61 @@ +/******************************************************************************* + * Copyright 2011-2014 by SirSengir + * + * This work is licensed under a Creative Commons Attribution-NonCommercial-NoDerivs 3.0 Unported License. + * + * To view a copy of this license, visit http://creativecommons.org/licenses/by-nc-nd/3.0/. + ******************************************************************************/ +package forestry.api.lepidopterology; + +import java.util.EnumSet; +import java.util.Map; + +import net.minecraft.item.ItemStack; + +import net.minecraftforge.common.BiomeDictionary; + +import forestry.api.genetics.IAlleleSpecies; + +public interface IAlleleButterflySpecies extends IAlleleSpecies { + + /** + * @return the IBeeRoot + */ + IButterflyRoot getRoot(); + + /** + * @return Path of the texture to use for entity rendering. + */ + String getEntityTexture(); + + /** + * Allows butterflies to restrict random spawns beyond the restrictions set by getTemperature() and getHumidity(). + * + * @return EnumSet of biome tags this butterfly species can be spawned in. + */ + EnumSet getSpawnBiomes(); + + /** + * @return true if a prospective spawn biome must not match a biome tag outside of getSpawnBiomes. + */ + boolean strictSpawnMatch(); + + /** + * @return Float between 0 and 1 representing the rarity of the species, will affect spawn rate. + */ + float getRarity(); + + /** + * @return Float representing the distance below which this butterfly will take flight if it detects a player which is not sneaking. + */ + float getFlightDistance(); + + /** + * @return true if this species is only active at night. + */ + boolean isNocturnal(); + + Map getButterflyLoot(); + + Map getCaterpillarLoot(); +} diff --git a/forestry_common/core/forestry/api/lepidopterology/IButterfly.java b/forestry_common/core/forestry/api/lepidopterology/IButterfly.java new file mode 100755 index 000000000..161b92c46 --- /dev/null +++ b/forestry_common/core/forestry/api/lepidopterology/IButterfly.java @@ -0,0 +1,79 @@ +/******************************************************************************* + * Copyright 2011-2014 by SirSengir + * + * This work is licensed under a Creative Commons Attribution-NonCommercial-NoDerivs 3.0 Unported License. + * + * To view a copy of this license, visit http://creativecommons.org/licenses/by-nc-nd/3.0/. + ******************************************************************************/ +package forestry.api.lepidopterology; + +import net.minecraft.item.ItemStack; +import net.minecraft.world.World; + +import forestry.api.genetics.IIndividualLiving; + +public interface IButterfly extends IIndividualLiving { + + IButterflyGenome getGenome(); + + /** + * @return Genetic information of the mate, null if unmated. + */ + IButterflyGenome getMate(); + + /** + * @return Physical size of the butterfly. + */ + float getSize(); + + /** + * @param world + * @param x + * @param y + * @param z + * @return true if the butterfly can naturally spawn at the given location at this time. (Used to auto-spawn butterflies from tree leaves.) + */ + boolean canSpawn(World world, double x, double y, double z); + + /** + * @param world + * @param x + * @param y + * @param z + * @return true if the butterfly can take flight at the given location at this time. (Used to auto-spawn butterflies from dropped items.) + */ + boolean canTakeFlight(World world, double x, double y, double z); + + /** + * @param world + * @param x + * @param y + * @param z + * @return true if the environment (temperature, humidity) is valid for the butterfly at the given location. + */ + boolean isAcceptedEnvironment(World world, double x, double y, double z); + + IButterfly spawnCaterpillar(IButterflyNursery nursery); + + /** + * @param entity + * @param playerKill Whether or not the butterfly was killed by a player. + * @param lootLevel Loot level according to the weapon used to kill the butterfly. + * @return Array of itemstacks to drop on death of the given entity. + */ + ItemStack[] getLootDrop(IEntityButterfly entity, boolean playerKill, int lootLevel); + + /** + * @param nursery + * @param playerKill Whether or not the nursery was broken by a player. + * @param lootLevel Fortune level. + * @return Array of itemstacks to drop on breaking of the nursery. + */ + ItemStack[] getCaterpillarDrop(IButterflyNursery nursery, boolean playerKill, int lootLevel); + + /** + * Create an exact copy of this butterfly. + */ + IButterfly copy(); + +} diff --git a/forestry_common/core/forestry/api/lepidopterology/IButterflyGenome.java b/forestry_common/core/forestry/api/lepidopterology/IButterflyGenome.java new file mode 100755 index 000000000..91875e373 --- /dev/null +++ b/forestry_common/core/forestry/api/lepidopterology/IButterflyGenome.java @@ -0,0 +1,44 @@ +/******************************************************************************* + * Copyright 2011-2014 by SirSengir + * + * This work is licensed under a Creative Commons Attribution-NonCommercial-NoDerivs 3.0 Unported License. + * + * To view a copy of this license, visit http://creativecommons.org/licenses/by-nc-nd/3.0/. + ******************************************************************************/ +package forestry.api.lepidopterology; + +import forestry.api.genetics.EnumTolerance; +import forestry.api.genetics.IFlowerProvider; +import forestry.api.genetics.IGenome; + +public interface IButterflyGenome extends IGenome { + + IAlleleButterflySpecies getPrimary(); + + IAlleleButterflySpecies getSecondary(); + + float getSize(); + + int getLifespan(); + + int getMetabolism(); + + int getFertility(); + + float getSpeed(); + + EnumTolerance getToleranceTemp(); + + EnumTolerance getToleranceHumid(); + + boolean getNocturnal(); + + boolean getTolerantFlyer(); + + boolean getFireResist(); + + IFlowerProvider getFlowerProvider(); + + IAlleleButterflyEffect getEffect(); + +} diff --git a/forestry_common/core/forestry/api/lepidopterology/IButterflyMutation.java b/forestry_common/core/forestry/api/lepidopterology/IButterflyMutation.java new file mode 100755 index 000000000..cc7fc3d23 --- /dev/null +++ b/forestry_common/core/forestry/api/lepidopterology/IButterflyMutation.java @@ -0,0 +1,16 @@ +/******************************************************************************* + * Copyright 2011-2014 by SirSengir + * + * This work is licensed under a Creative Commons Attribution-NonCommercial-NoDerivs 3.0 Unported License. + * + * To view a copy of this license, visit http://creativecommons.org/licenses/by-nc-nd/3.0/. + ******************************************************************************/ +package forestry.api.lepidopterology; + +import forestry.api.genetics.IAllele; +import forestry.api.genetics.IGenome; +import forestry.api.genetics.IMutation; + +public interface IButterflyMutation extends IMutation { + float getChance(IButterflyNursery housing, IAllele allele0, IAllele allele1, IGenome genome0, IGenome genome1); +} diff --git a/forestry_common/core/forestry/api/lepidopterology/IButterflyNursery.java b/forestry_common/core/forestry/api/lepidopterology/IButterflyNursery.java new file mode 100755 index 000000000..4e2add8dc --- /dev/null +++ b/forestry_common/core/forestry/api/lepidopterology/IButterflyNursery.java @@ -0,0 +1,23 @@ +/******************************************************************************* + * Copyright 2011-2014 by SirSengir + * + * This work is licensed under a Creative Commons Attribution-NonCommercial-NoDerivs 3.0 Unported License. + * + * To view a copy of this license, visit http://creativecommons.org/licenses/by-nc-nd/3.0/. + ******************************************************************************/ +package forestry.api.lepidopterology; + +import forestry.api.genetics.IHousing; +import forestry.api.genetics.IIndividual; + +public interface IButterflyNursery extends IHousing { + + IButterfly getCaterpillar(); + + IIndividual getNanny(); + + void setCaterpillar(IButterfly butterfly); + + boolean canNurse(IButterfly butterfly); + +} diff --git a/forestry_common/core/forestry/api/lepidopterology/IButterflyRoot.java b/forestry_common/core/forestry/api/lepidopterology/IButterflyRoot.java new file mode 100755 index 000000000..2fd727a31 --- /dev/null +++ b/forestry_common/core/forestry/api/lepidopterology/IButterflyRoot.java @@ -0,0 +1,62 @@ +/******************************************************************************* + * Copyright 2011-2014 by SirSengir + * + * This work is licensed under a Creative Commons Attribution-NonCommercial-NoDerivs 3.0 Unported License. + * + * To view a copy of this license, visit http://creativecommons.org/licenses/by-nc-nd/3.0/. + ******************************************************************************/ +package forestry.api.lepidopterology; + +import java.util.ArrayList; +import java.util.Collection; + +import net.minecraft.entity.EntityLiving; +import net.minecraft.item.ItemStack; +import net.minecraft.nbt.NBTTagCompound; +import net.minecraft.world.World; + +import forestry.api.genetics.IAllele; +import forestry.api.genetics.IIndividual; +import forestry.api.genetics.ISpeciesRoot; + +public interface IButterflyRoot extends ISpeciesRoot { + + boolean isMember(ItemStack stack); + + IButterfly getMember(ItemStack stack); + + IButterfly getMember(NBTTagCompound compound); + + ItemStack getMemberStack(IIndividual butterfly, int type); + + /* GENOME CONVERSION */ + IButterfly templateAsIndividual(IAllele[] template); + + IButterfly templateAsIndividual(IAllele[] templateActive, IAllele[] templateInactive); + + IButterflyGenome templateAsGenome(IAllele[] template); + + IButterflyGenome templateAsGenome(IAllele[] templateActive, IAllele[] templateInactive); + + /* BUTTERFLY SPECIFIC */ + ILepidopteristTracker getBreedingTracker(World world, String player); + + /** + * Spawns the given butterfly in the world. + * @param butterfly + * @return butterfly entity on success, null otherwise. + */ + EntityLiving spawnButterflyInWorld(World world, IButterfly butterfly, double x, double y, double z); + + /** + * @return true if passed item is mated. + */ + boolean isMated(ItemStack stack); + + /* TEMPLATES */ + ArrayList getIndividualTemplates(); + + /* MUTATIONS */ + Collection getMutations(boolean shuffle); + +} diff --git a/forestry_common/core/forestry/api/lepidopterology/IEntityButterfly.java b/forestry_common/core/forestry/api/lepidopterology/IEntityButterfly.java new file mode 100755 index 000000000..0a1932016 --- /dev/null +++ b/forestry_common/core/forestry/api/lepidopterology/IEntityButterfly.java @@ -0,0 +1,31 @@ +/******************************************************************************* + * Copyright 2011-2014 by SirSengir + * + * This work is licensed under a Creative Commons Attribution-NonCommercial-NoDerivs 3.0 Unported License. + * + * To view a copy of this license, visit http://creativecommons.org/licenses/by-nc-nd/3.0/. + ******************************************************************************/ +package forestry.api.lepidopterology; + +import net.minecraft.entity.EntityCreature; +import net.minecraft.entity.passive.IAnimals; + +import forestry.api.genetics.IIndividual; + +public interface IEntityButterfly extends IAnimals { + + void changeExhaustion(int change); + + int getExhaustion(); + + IButterfly getButterfly(); + + /** + * @return The entity as an EntityCreature to save casting. + */ + EntityCreature getEntity(); + + IIndividual getPollen(); + + void setPollen(IIndividual pollen); +} diff --git a/forestry_common/core/forestry/api/lepidopterology/ILepidopteristTracker.java b/forestry_common/core/forestry/api/lepidopterology/ILepidopteristTracker.java new file mode 100755 index 000000000..94880c9c0 --- /dev/null +++ b/forestry_common/core/forestry/api/lepidopterology/ILepidopteristTracker.java @@ -0,0 +1,16 @@ +/******************************************************************************* + * Copyright 2011-2014 by SirSengir + * + * This work is licensed under a Creative Commons Attribution-NonCommercial-NoDerivs 3.0 Unported License. + * + * To view a copy of this license, visit http://creativecommons.org/licenses/by-nc-nd/3.0/. + ******************************************************************************/ +package forestry.api.lepidopterology; + +import forestry.api.genetics.IBreedingTracker; + +public interface ILepidopteristTracker extends IBreedingTracker { + + void registerCatch(IButterfly butterfly); + +} diff --git a/forestry_common/core/forestry/api/lepidopterology/package-info.java b/forestry_common/core/forestry/api/lepidopterology/package-info.java new file mode 100755 index 000000000..cca141240 --- /dev/null +++ b/forestry_common/core/forestry/api/lepidopterology/package-info.java @@ -0,0 +1,10 @@ +/******************************************************************************* + * Copyright 2011-2014 by SirSengir + * + * This work is licensed under a Creative Commons Attribution-NonCommercial-NoDerivs 3.0 Unported License. + * + * To view a copy of this license, visit http://creativecommons.org/licenses/by-nc-nd/3.0/. + ******************************************************************************/ +@API(apiVersion="1.0", owner="ForestryAPI|core", provides="ForestryAPI|lepidopterology") +package forestry.api.lepidopterology; +import cpw.mods.fml.common.API; diff --git a/forestry_common/core/forestry/api/mail/EnumPostage.java b/forestry_common/core/forestry/api/mail/EnumPostage.java new file mode 100755 index 000000000..ee31000cb --- /dev/null +++ b/forestry_common/core/forestry/api/mail/EnumPostage.java @@ -0,0 +1,22 @@ +/******************************************************************************* + * Copyright 2011-2014 by SirSengir + * + * This work is licensed under a Creative Commons Attribution-NonCommercial-NoDerivs 3.0 Unported License. + * + * To view a copy of this license, visit http://creativecommons.org/licenses/by-nc-nd/3.0/. + ******************************************************************************/ +package forestry.api.mail; + +public enum EnumPostage { + P_0(0), P_1(1), P_2(2), P_5(5), P_10(10), P_20(20), P_50(50), P_100(100), P_200(200); + + private final int value; + + private EnumPostage(int value) { + this.value = value; + } + + public int getValue() { + return this.value; + } +} diff --git a/forestry_common/core/forestry/api/mail/ILetter.java b/forestry_common/core/forestry/api/mail/ILetter.java new file mode 100755 index 000000000..8dfcc96f4 --- /dev/null +++ b/forestry_common/core/forestry/api/mail/ILetter.java @@ -0,0 +1,62 @@ +/******************************************************************************* + * Copyright 2011-2014 by SirSengir + * + * This work is licensed under a Creative Commons Attribution-NonCommercial-NoDerivs 3.0 Unported License. + * + * To view a copy of this license, visit http://creativecommons.org/licenses/by-nc-nd/3.0/. + ******************************************************************************/ +package forestry.api.mail; + +import java.util.List; + +import net.minecraft.inventory.IInventory; +import net.minecraft.item.ItemStack; + +import forestry.api.core.INBTTagable; + +public interface ILetter extends IInventory, INBTTagable { + + ItemStack[] getPostage(); + + void setProcessed(boolean flag); + + boolean isProcessed(); + + boolean isMailable(); + + void setSender(MailAddress address); + + MailAddress getSender(); + + boolean hasRecipient(); + + void setRecipient(MailAddress address); + + MailAddress[] getRecipients(); + + String getRecipientString(); + + void setText(String text); + + String getText(); + + @SuppressWarnings("rawtypes") + void addTooltip(List list); + + boolean isPostPaid(); + + int requiredPostage(); + + void invalidatePostage(); + + ItemStack[] getAttachments(); + + void addAttachment(ItemStack itemstack); + + void addAttachments(ItemStack[] itemstacks); + + int countAttachments(); + + void addStamps(ItemStack stamps); + +} diff --git a/forestry_common/core/forestry/api/mail/ILetterHandler.java b/forestry_common/core/forestry/api/mail/ILetterHandler.java new file mode 100755 index 000000000..51f7b21d7 --- /dev/null +++ b/forestry_common/core/forestry/api/mail/ILetterHandler.java @@ -0,0 +1,15 @@ +/******************************************************************************* + * Copyright 2011-2014 by SirSengir + * + * This work is licensed under a Creative Commons Attribution-NonCommercial-NoDerivs 3.0 Unported License. + * + * To view a copy of this license, visit http://creativecommons.org/licenses/by-nc-nd/3.0/. + ******************************************************************************/ +package forestry.api.mail; + +import net.minecraft.item.ItemStack; +import net.minecraft.world.World; + +public interface ILetterHandler { + IPostalState handleLetter(World world, String recipient, ItemStack letterStack, boolean doLodge); +} diff --git a/forestry_common/core/forestry/api/mail/IPostOffice.java b/forestry_common/core/forestry/api/mail/IPostOffice.java new file mode 100755 index 000000000..68df4bc9d --- /dev/null +++ b/forestry_common/core/forestry/api/mail/IPostOffice.java @@ -0,0 +1,32 @@ +/******************************************************************************* + * Copyright 2011-2014 by SirSengir + * + * This work is licensed under a Creative Commons Attribution-NonCommercial-NoDerivs 3.0 Unported License. + * + * To view a copy of this license, visit http://creativecommons.org/licenses/by-nc-nd/3.0/. + ******************************************************************************/ +package forestry.api.mail; + +import java.util.Map; + +import net.minecraft.item.ItemStack; +import net.minecraft.world.World; + +public interface IPostOffice { + + void collectPostage(ItemStack[] stamps); + + IPostalState lodgeLetter(World world, ItemStack itemstack, boolean doLodge); + + ItemStack getAnyStamp(int max); + + ItemStack getAnyStamp(EnumPostage postage, int max); + + ItemStack getAnyStamp(EnumPostage[] postages, int max); + + void registerTradeStation(ITradeStation trade); + + void deregisterTradeStation(ITradeStation trade); + + Map getActiveTradeStations(World world); +} diff --git a/forestry_common/core/forestry/api/mail/IPostRegistry.java b/forestry_common/core/forestry/api/mail/IPostRegistry.java new file mode 100755 index 000000000..bfb21444b --- /dev/null +++ b/forestry_common/core/forestry/api/mail/IPostRegistry.java @@ -0,0 +1,54 @@ +/******************************************************************************* + * Copyright 2011-2014 by SirSengir + * + * This work is licensed under a Creative Commons Attribution-NonCommercial-NoDerivs 3.0 Unported License. + * + * To view a copy of this license, visit http://creativecommons.org/licenses/by-nc-nd/3.0/. + ******************************************************************************/ +package forestry.api.mail; + +import java.util.Map; + +import net.minecraft.item.ItemStack; +import net.minecraft.world.World; + +public interface IPostRegistry { + + /* POST OFFICE */ + IPostOffice getPostOffice(World world); + + /* LETTERS */ + boolean isLetter(ItemStack itemstack); + + ILetter createLetter(MailAddress sender, MailAddress recipient); + + ILetter getLetter(ItemStack itemstack); + + ItemStack createLetterStack(ILetter letter); + + /* CARRIERS */ + /** + * Registers a new {@link IPostalCarrier}. See {@link IPostalCarrier} for details. + * @param carrier {@link IPostalCarrier} to register. + */ + void registerCarrier(IPostalCarrier carrier); + + IPostalCarrier getCarrier(String uid); + + Map getRegisteredCarriers(); + + /* TRADE STATIONS */ + void deleteTradeStation(World world, String moniker); + + ITradeStation getOrCreateTradeStation(World world, String owner, String moniker); + + ITradeStation getTradeStation(World world, String moniker); + + boolean isAvailableTradeMoniker(World world, String moniker); + + boolean isValidTradeMoniker(World world, String moniker); + + /* PO BOXES */ + boolean isValidPOBox(World world, String username); + +} diff --git a/forestry_common/core/forestry/api/mail/IPostalCarrier.java b/forestry_common/core/forestry/api/mail/IPostalCarrier.java new file mode 100755 index 000000000..b5c0fbecd --- /dev/null +++ b/forestry_common/core/forestry/api/mail/IPostalCarrier.java @@ -0,0 +1,50 @@ +/******************************************************************************* + * Copyright 2011-2014 by SirSengir + * + * This work is licensed under a Creative Commons Attribution-NonCommercial-NoDerivs 3.0 Unported License. + * + * To view a copy of this license, visit http://creativecommons.org/licenses/by-nc-nd/3.0/. + ******************************************************************************/ +package forestry.api.mail; + +import net.minecraft.item.ItemStack; +import net.minecraft.util.IIcon; +import net.minecraft.world.World; + +import cpw.mods.fml.relauncher.Side; +import cpw.mods.fml.relauncher.SideOnly; + +/** + * Postal Carriers are systems which can be hooked into Forestry's mail system to handle mail delivery. + * + * The two available carriers in vanilla Forestry are + * "player" - Delivers mail to individual players. + * "trader" - Handles mail addressed to trade stations. + */ +public interface IPostalCarrier { + + /** + * @return A lower-case identifier without spaces. + */ + String getUID(); + + /** + * @return A human-readable name for this carrier. + */ + String getName(); + + @SideOnly(Side.CLIENT) + IIcon getIcon(); + + /** + * Handle delivery of a letter addressed to this carrier. + * @param world The world the {@link IPostOffice} handles. + * @param office {link @IPostOffice} which received this letter and handed it to the carrier. + * @param recipient An identifier for the recipient as typed by the player into the address field. + * @param letterstack ItemStack representing the letter. See {@link IPostRegistry} for helper functions to validate and extract it. + * @param doDeliver Whether or not the letter is supposed to actually be delivered or if delivery is only to be simulated. + * @return {link IPostalState} holding information on success or failure for delivery. + */ + IPostalState deliverLetter(World world, IPostOffice office, String recipient, ItemStack letterstack, boolean doDeliver); + +} diff --git a/forestry_common/core/forestry/api/mail/IPostalState.java b/forestry_common/core/forestry/api/mail/IPostalState.java new file mode 100755 index 000000000..4ad579db5 --- /dev/null +++ b/forestry_common/core/forestry/api/mail/IPostalState.java @@ -0,0 +1,16 @@ +/******************************************************************************* + * Copyright 2011-2014 by SirSengir + * + * This work is licensed under a Creative Commons Attribution-NonCommercial-NoDerivs 3.0 Unported License. + * + * To view a copy of this license, visit http://creativecommons.org/licenses/by-nc-nd/3.0/. + ******************************************************************************/ +package forestry.api.mail; + +public interface IPostalState { + boolean isOk(); + + String getIdentifier(); + + int ordinal(); +} diff --git a/forestry_common/core/forestry/api/mail/IStamps.java b/forestry_common/core/forestry/api/mail/IStamps.java new file mode 100755 index 000000000..a623b6cc3 --- /dev/null +++ b/forestry_common/core/forestry/api/mail/IStamps.java @@ -0,0 +1,16 @@ +/******************************************************************************* + * Copyright 2011-2014 by SirSengir + * + * This work is licensed under a Creative Commons Attribution-NonCommercial-NoDerivs 3.0 Unported License. + * + * To view a copy of this license, visit http://creativecommons.org/licenses/by-nc-nd/3.0/. + ******************************************************************************/ +package forestry.api.mail; + +import net.minecraft.item.ItemStack; + +public interface IStamps { + + EnumPostage getPostage(ItemStack itemstack); + +} diff --git a/forestry_common/core/forestry/api/mail/ITradeStation.java b/forestry_common/core/forestry/api/mail/ITradeStation.java new file mode 100755 index 000000000..d6d8a59b2 --- /dev/null +++ b/forestry_common/core/forestry/api/mail/ITradeStation.java @@ -0,0 +1,26 @@ +/******************************************************************************* + * Copyright 2011-2014 by SirSengir + * + * This work is licensed under a Creative Commons Attribution-NonCommercial-NoDerivs 3.0 Unported License. + * + * To view a copy of this license, visit http://creativecommons.org/licenses/by-nc-nd/3.0/. + ******************************************************************************/ +package forestry.api.mail; + +import net.minecraft.inventory.IInventory; + +public interface ITradeStation extends ILetterHandler, IInventory { + + String getMoniker(); + + boolean isValid(); + + void invalidate(); + + void setVirtual(boolean isVirtual); + + boolean isVirtual(); + + TradeStationInfo getTradeInfo(); + +} diff --git a/forestry_common/core/forestry/api/mail/MailAddress.java b/forestry_common/core/forestry/api/mail/MailAddress.java new file mode 100755 index 000000000..4876a38d4 --- /dev/null +++ b/forestry_common/core/forestry/api/mail/MailAddress.java @@ -0,0 +1,62 @@ +/******************************************************************************* + * Copyright 2011-2014 by SirSengir + * + * This work is licensed under a Creative Commons Attribution-NonCommercial-NoDerivs 3.0 Unported License. + * + * To view a copy of this license, visit http://creativecommons.org/licenses/by-nc-nd/3.0/. + ******************************************************************************/ +package forestry.api.mail; + +import net.minecraft.nbt.NBTTagCompound; + +import forestry.api.core.INBTTagable; + +public class MailAddress implements INBTTagable { + private String type; + private String identifier; + + private MailAddress() { + } + + public MailAddress(String identifier) { + this(identifier, "player"); + } + + public MailAddress(String identifier, String type) { + this.identifier = identifier; + this.type = type; + } + + public String getType() { + return type; + } + + public String getIdentifier() { + return identifier; + } + + public boolean isPlayer() { + return "player".equals(type); + } + + @Override + public void readFromNBT(NBTTagCompound nbttagcompound) { + if(nbttagcompound.hasKey("TP")) + type = nbttagcompound.getString("TP"); + else + type = nbttagcompound.getShort("TYP") == 0 ? "player" : "trader"; + identifier = nbttagcompound.getString("ID"); + } + + @Override + public void writeToNBT(NBTTagCompound nbttagcompound) { + nbttagcompound.setString("TP", type); + nbttagcompound.setString("ID", identifier); + } + + public static MailAddress loadFromNBT(NBTTagCompound nbttagcompound) { + MailAddress address = new MailAddress(); + address.readFromNBT(nbttagcompound); + return address; + } +} diff --git a/forestry_common/core/forestry/api/mail/PostManager.java b/forestry_common/core/forestry/api/mail/PostManager.java new file mode 100755 index 000000000..6f6a5ef82 --- /dev/null +++ b/forestry_common/core/forestry/api/mail/PostManager.java @@ -0,0 +1,13 @@ +/******************************************************************************* + * Copyright 2011-2014 by SirSengir + * + * This work is licensed under a Creative Commons Attribution-NonCommercial-NoDerivs 3.0 Unported License. + * + * To view a copy of this license, visit http://creativecommons.org/licenses/by-nc-nd/3.0/. + ******************************************************************************/ +package forestry.api.mail; + + +public class PostManager { + public static IPostRegistry postRegistry; +} diff --git a/forestry_common/core/forestry/api/mail/TradeStationInfo.java b/forestry_common/core/forestry/api/mail/TradeStationInfo.java new file mode 100755 index 000000000..4b7931fbf --- /dev/null +++ b/forestry_common/core/forestry/api/mail/TradeStationInfo.java @@ -0,0 +1,26 @@ +/******************************************************************************* + * Copyright 2011-2014 by SirSengir + * + * This work is licensed under a Creative Commons Attribution-NonCommercial-NoDerivs 3.0 Unported License. + * + * To view a copy of this license, visit http://creativecommons.org/licenses/by-nc-nd/3.0/. + ******************************************************************************/ +package forestry.api.mail; + +import net.minecraft.item.ItemStack; + +public class TradeStationInfo { + public final String moniker; + public final String owner; + public final ItemStack tradegood; + public final ItemStack[] required; + public final IPostalState state; + + public TradeStationInfo(String moniker, String owner, ItemStack tradegood, ItemStack[] required, IPostalState state) { + this.moniker = moniker; + this.owner = owner; + this.tradegood = tradegood; + this.required = required; + this.state = state; + } +} diff --git a/forestry_common/core/forestry/api/mail/package-info.java b/forestry_common/core/forestry/api/mail/package-info.java new file mode 100755 index 000000000..cd8d3c6e0 --- /dev/null +++ b/forestry_common/core/forestry/api/mail/package-info.java @@ -0,0 +1,10 @@ +/******************************************************************************* + * Copyright 2011-2014 by SirSengir + * + * This work is licensed under a Creative Commons Attribution-NonCommercial-NoDerivs 3.0 Unported License. + * + * To view a copy of this license, visit http://creativecommons.org/licenses/by-nc-nd/3.0/. + ******************************************************************************/ +@API(apiVersion="1.0", owner="ForestryAPI|core", provides="ForestryAPI|mail") +package forestry.api.mail; +import cpw.mods.fml.common.API; diff --git a/forestry_common/core/forestry/api/package-info.java b/forestry_common/core/forestry/api/package-info.java new file mode 100755 index 000000000..30e9bc340 --- /dev/null +++ b/forestry_common/core/forestry/api/package-info.java @@ -0,0 +1,10 @@ +/******************************************************************************* + * Copyright 2011-2014 by SirSengir + * + * This work is licensed under a Creative Commons Attribution-NonCommercial-NoDerivs 3.0 Unported License. + * + * To view a copy of this license, visit http://creativecommons.org/licenses/by-nc-nd/3.0/. + ******************************************************************************/ +@API(apiVersion="1.0", owner="Forestry", provides="ForestryAPI|core") +package forestry.api; +import cpw.mods.fml.common.API; diff --git a/forestry_common/core/forestry/api/recipes/IBottlerManager.java b/forestry_common/core/forestry/api/recipes/IBottlerManager.java new file mode 100755 index 000000000..7faaf22c4 --- /dev/null +++ b/forestry_common/core/forestry/api/recipes/IBottlerManager.java @@ -0,0 +1,42 @@ +/******************************************************************************* + * Copyright 2011-2014 by SirSengir + * + * This work is licensed under a Creative Commons Attribution-NonCommercial-NoDerivs 3.0 Unported License. + * + * To view a copy of this license, visit http://creativecommons.org/licenses/by-nc-nd/3.0/. + ******************************************************************************/ +package forestry.api.recipes; + +import net.minecraft.item.ItemStack; + +import net.minecraftforge.fluids.FluidStack; + +/** + * Provides an interface to the recipe manager of the bottler. + * + * The manager is initialized at the beginning of Forestry's BaseMod.load() cycle. Begin adding recipes in BaseMod.ModsLoaded() and this shouldn't be null even + * if your mod loads before Forestry. + * + * Accessible via {@link RecipeManagers} + * + * Note that this is untested with anything other than biofuel->fuelcan conversion. + * + * @author SirSengir + */ +public interface IBottlerManager extends ICraftingProvider { + /** + * Add a recipe to the bottler. + * The bottler will populate its recipe list dynamically from the LiquidContainerRegistry. Recipes added explicitely will take precedence. + * + * @param cyclesPerUnit + * Amount of work cycles required to run through the conversion once. + * @param input + * LiquidStack representing the input liquid. + * @param can + * ItemStack representing the cans, capsules and/or cells required + * @param bottled + * ItemStack representing the finished product + */ + @Deprecated + public void addRecipe(int cyclesPerUnit, FluidStack input, ItemStack can, ItemStack bottled); +} diff --git a/forestry_common/core/forestry/api/recipes/ICarpenterManager.java b/forestry_common/core/forestry/api/recipes/ICarpenterManager.java new file mode 100755 index 000000000..f5516e2c1 --- /dev/null +++ b/forestry_common/core/forestry/api/recipes/ICarpenterManager.java @@ -0,0 +1,73 @@ +/******************************************************************************* + * Copyright 2011-2014 by SirSengir + * + * This work is licensed under a Creative Commons Attribution-NonCommercial-NoDerivs 3.0 Unported License. + * + * To view a copy of this license, visit http://creativecommons.org/licenses/by-nc-nd/3.0/. + ******************************************************************************/ +package forestry.api.recipes; + +import net.minecraft.item.ItemStack; +import net.minecraft.item.crafting.ShapedRecipes; + +import net.minecraftforge.fluids.FluidStack; + +/** + * Provides an interface to the recipe manager of the carpenter. + * + * The manager is initialized at the beginning of Forestry's BaseMod.load() cycle. Begin adding recipes in BaseMod.ModsLoaded() and this shouldn't be null even + * if your mod loads before Forestry. + * + * Accessible via {@link RecipeManagers} + * + * Only shaped recipes can be added currently. + * + * @author SirSengir + */ +public interface ICarpenterManager extends ICraftingProvider { + /** + * Add a shaped recipe to the carpenter. + * + * @param box + * ItemStack of one item representing the required box (carton, crate) for this recipe. May be null. + * @param product + * Crafting result. + * @param materials + * Materials needed in the crafting matrix. This gets passed directly to {@link ShapedRecipes}. Notation is the same. + */ + public void addRecipe(ItemStack box, ItemStack product, Object materials[]); + + /** + * Add a shaped recipe to the carpenter. + * + * @param packagingTime + * Number of work cycles required to craft the recipe once. + * @param box + * ItemStack of one item representing the required box (carton, crate) for this recipe. May be null. + * @param product + * Crafting result. + * @param materials + * Materials needed in the crafting matrix. This gets passed directly to {@link ShapedRecipes}. Notation is the same. + */ + public void addRecipe(int packagingTime, ItemStack box, ItemStack product, Object materials[]); + + /** + * Add a shaped recipe to the carpenter. + * + * @param packagingTime + * Number of work cycles required to craft the recipe once. + * @param liquid + * Liquid required in carpenter's tank. + * @param box + * ItemStack of one item representing the required box (carton, crate) for this recipe. May be null. + * @param product + * Crafting result. + * @param materials + * Materials needed in the crafting matrix. This gets passed directly to {@link ShapedRecipes}. Notation is the same. + */ + public void addRecipe(int packagingTime, FluidStack liquid, ItemStack box, ItemStack product, Object materials[]); + + public void addCrating(String toCrate, ItemStack unpack, ItemStack crated); + + public void addCrating(ItemStack itemStack); +} diff --git a/forestry_common/core/forestry/api/recipes/ICentrifugeManager.java b/forestry_common/core/forestry/api/recipes/ICentrifugeManager.java new file mode 100755 index 000000000..115868c03 --- /dev/null +++ b/forestry_common/core/forestry/api/recipes/ICentrifugeManager.java @@ -0,0 +1,81 @@ +/******************************************************************************* + * Copyright 2011-2014 by SirSengir + * + * This work is licensed under a Creative Commons Attribution-NonCommercial-NoDerivs 3.0 Unported License. + * + * To view a copy of this license, visit http://creativecommons.org/licenses/by-nc-nd/3.0/. + ******************************************************************************/ +package forestry.api.recipes; + +import java.util.HashMap; + +import net.minecraft.item.ItemStack; + +/** + * Provides an interface to the recipe manager of the centrifuge. + * + * The manager is initialized at the beginning of Forestry's BaseMod.load() cycle. Begin adding recipes in BaseMod.ModsLoaded() and this shouldn't be null even + * if your mod loads before Forestry. + * + * Accessible via {@link RecipeManagers} + * + * @author SirSengir + */ +public interface ICentrifugeManager extends ICraftingProvider { + + /** + * Add a recipe to the centrifuge + * + * @param timePerItem + * Time to centrifugate one item of the given type + * @param resource + * ItemStack containing information on item id and damage. Stack size will be ignored. + * @param products + * HashMap specifying the possible products and the chances of them resulting from centrifugation. + */ + public void addRecipe(int timePerItem, ItemStack resource, HashMap products); + + /** + * Add a recipe to the centrifuge + * + * @param timePerItem + * Time to centrifugate one item of the given type + * @param resource + * ItemStack containing information on item id and damage. Stack size will be ignored. + * @param produce + * Array of ItemStacks that can be the result of this recipe. + * @param chances + * Array of integers corresponding and matching to produce providing the chance (0-100) for the ItemStack at the given index to be + * produced. + */ + public void addRecipe(int timePerItem, ItemStack resource, ItemStack[] produce, int[] chances); + + /** + * Add a recipe to the centrifuge + * + * @param timePerItem + * Time to centrifugate one item of the given type + * @param resource + * ItemStack containing information on item id and damage. Stack size will be ignored. + * @param primary + * Primary product produced by centrifugating one item. Yield 100 %. + * @param secondary + * Secondary product that may be produced when centrifugating the given item. May be null. + * @param chance + * Chance (1 - 100) for centrifugation to yield the secondary product. + */ + public void addRecipe(int timePerItem, ItemStack resource, ItemStack primary, ItemStack secondary, int chance); + + /** + * Add a recipe to the centrifuge + * + * @param timePerItem + * Time to centrifugate one item of the given type + * @param resource + * ItemStack containing information on item id and damage. Stack size will be ignored. + * @param primary + * Primary product produced by centrifugating one item. Yield 100 %. + */ + public void addRecipe(int timePerItem, ItemStack resource, ItemStack primary); + +} diff --git a/forestry_common/core/forestry/api/recipes/ICraftingProvider.java b/forestry_common/core/forestry/api/recipes/ICraftingProvider.java new file mode 100755 index 000000000..39f3c3456 --- /dev/null +++ b/forestry_common/core/forestry/api/recipes/ICraftingProvider.java @@ -0,0 +1,19 @@ +/******************************************************************************* + * Copyright 2011-2014 by SirSengir + * + * This work is licensed under a Creative Commons Attribution-NonCommercial-NoDerivs 3.0 Unported License. + * + * To view a copy of this license, visit http://creativecommons.org/licenses/by-nc-nd/3.0/. + ******************************************************************************/ +package forestry.api.recipes; + +import java.util.Map; + +public interface ICraftingProvider { + /** + * Access to the full list of recipes contained in the crafting provider. + * + * @return List of the given format where the first array represents inputs and the second outputs. Objects can be either ItemStack or LiquidStack. + */ + public Map getRecipes(); +} diff --git a/forestry_common/core/forestry/api/recipes/IFabricatorManager.java b/forestry_common/core/forestry/api/recipes/IFabricatorManager.java new file mode 100755 index 000000000..7b0a20f18 --- /dev/null +++ b/forestry_common/core/forestry/api/recipes/IFabricatorManager.java @@ -0,0 +1,20 @@ +/******************************************************************************* + * Copyright 2011-2014 by SirSengir + * + * This work is licensed under a Creative Commons Attribution-NonCommercial-NoDerivs 3.0 Unported License. + * + * To view a copy of this license, visit http://creativecommons.org/licenses/by-nc-nd/3.0/. + ******************************************************************************/ +package forestry.api.recipes; + +import net.minecraft.item.ItemStack; + +import net.minecraftforge.fluids.FluidStack; + +public interface IFabricatorManager extends ICraftingProvider { + + void addRecipe(ItemStack plan, FluidStack molten, ItemStack result, Object[] pattern); + + void addSmelting(ItemStack resource, FluidStack molten, int meltingPoint); + +} diff --git a/forestry_common/core/forestry/api/recipes/IFermenterManager.java b/forestry_common/core/forestry/api/recipes/IFermenterManager.java new file mode 100755 index 000000000..2fcfce4d5 --- /dev/null +++ b/forestry_common/core/forestry/api/recipes/IFermenterManager.java @@ -0,0 +1,55 @@ +/******************************************************************************* + * Copyright 2011-2014 by SirSengir + * + * This work is licensed under a Creative Commons Attribution-NonCommercial-NoDerivs 3.0 Unported License. + * + * To view a copy of this license, visit http://creativecommons.org/licenses/by-nc-nd/3.0/. + ******************************************************************************/ +package forestry.api.recipes; + +import net.minecraft.item.ItemStack; + +import net.minecraftforge.fluids.FluidStack; + +/** + * Provides an interface to the recipe manager of the fermenter. + * + * The manager is initialized at the beginning of Forestry's BaseMod.load() + * cycle. Begin adding recipes in BaseMod.ModsLoaded() and this shouldn't be + * null even if your mod loads before Forestry. + * + * Accessible via {@link RecipeManagers} + * + * @author SirSengir + */ +public interface IFermenterManager extends ICraftingProvider { + + /** + * Add a recipe to the fermenter + * + * @param resource ItemStack representing the resource. + * @param fermentationValue Value of the given resource, i.e. how much needs + * to be fermented for the output to be deposited into the product tank. + * @param modifier Modifies the amount of liquid output per work cycle. + * (water = 1.0f, honey = 1.5f) + * @param output LiquidStack representing output liquid. Amount is + * determined by fermentationValue*modifier. + * @param liquid LiquidStack representing resource liquid and amount. + * @throws NullPointerException if resource, output or liquid is null + */ + public void addRecipe(ItemStack resource, int fermentationValue, float modifier, FluidStack output, FluidStack liquid); + + /** + * Add a recipe to the fermenter. Defaults to water as input liquid. + * + * @param resource ItemStack representing the resource. + * @param modifier Modifies the amount of liquid output per work cycle. + * (water = 1.0f, honey = 1.5f) + * @param fermentationValue Value of the given resource, i.e. how much needs + * to be fermented for the output to be deposited into the product tank. + * @param output LiquidStack representing output liquid. Amount is + * determined by fermentationValue*modifier. + * @throws NullPointerException if resource, output or liquid is null + */ + public void addRecipe(ItemStack resource, int fermentationValue, float modifier, FluidStack output); +} diff --git a/forestry_common/core/forestry/api/recipes/IGenericCrate.java b/forestry_common/core/forestry/api/recipes/IGenericCrate.java new file mode 100755 index 000000000..06121b6cb --- /dev/null +++ b/forestry_common/core/forestry/api/recipes/IGenericCrate.java @@ -0,0 +1,18 @@ +/******************************************************************************* + * Copyright 2011-2014 by SirSengir + * + * This work is licensed under a Creative Commons Attribution-NonCommercial-NoDerivs 3.0 Unported License. + * + * To view a copy of this license, visit http://creativecommons.org/licenses/by-nc-nd/3.0/. + ******************************************************************************/ +package forestry.api.recipes; + +import net.minecraft.item.ItemStack; + +public interface IGenericCrate { + + void setContained(ItemStack crate, ItemStack contained); + + ItemStack getContained(ItemStack crate); + +} diff --git a/forestry_common/core/forestry/api/recipes/IMoistenerManager.java b/forestry_common/core/forestry/api/recipes/IMoistenerManager.java new file mode 100755 index 000000000..fe92700cd --- /dev/null +++ b/forestry_common/core/forestry/api/recipes/IMoistenerManager.java @@ -0,0 +1,35 @@ +/******************************************************************************* + * Copyright 2011-2014 by SirSengir + * + * This work is licensed under a Creative Commons Attribution-NonCommercial-NoDerivs 3.0 Unported License. + * + * To view a copy of this license, visit http://creativecommons.org/licenses/by-nc-nd/3.0/. + ******************************************************************************/ +package forestry.api.recipes; + +import net.minecraft.item.ItemStack; + +/** + * Provides an interface to the recipe manager of the moistener. + * + * The manager is initialized at the beginning of Forestry's BaseMod.load() cycle. Begin adding recipes in BaseMod.ModsLoaded() and this shouldn't be null even + * if your mod loads before Forestry. + * + * Accessible via {@link RecipeManagers} + * + * @author SirSengir + */ +public interface IMoistenerManager extends ICraftingProvider { + + /** + * Add a recipe to the moistener + * + * @param resource + * Item required in resource stack. Will be reduced by one per produced item. + * @param product + * Item to produce per resource processed. + * @param timePerItem + * Moistener runs at 1 - 4 time ticks per ingame tick depending on light level. For mycelium this value is currently 5000. + */ + public void addRecipe(ItemStack resource, ItemStack product, int timePerItem); +} diff --git a/forestry_common/core/forestry/api/recipes/ISqueezerManager.java b/forestry_common/core/forestry/api/recipes/ISqueezerManager.java new file mode 100755 index 000000000..108493460 --- /dev/null +++ b/forestry_common/core/forestry/api/recipes/ISqueezerManager.java @@ -0,0 +1,53 @@ +/******************************************************************************* + * Copyright 2011-2014 by SirSengir + * + * This work is licensed under a Creative Commons Attribution-NonCommercial-NoDerivs 3.0 Unported License. + * + * To view a copy of this license, visit http://creativecommons.org/licenses/by-nc-nd/3.0/. + ******************************************************************************/ +package forestry.api.recipes; + +import net.minecraft.item.ItemStack; + +import net.minecraftforge.fluids.FluidStack; + +/** + * Provides an interface to the recipe manager of the suqeezer. + * + * The manager is initialized at the beginning of Forestry's BaseMod.load() cycle. Begin adding recipes in BaseMod.ModsLoaded() and this shouldn't be null even + * if your mod loads before Forestry. + * + * Accessible via {@link RecipeManagers} + * + * @author SirSengir + */ +public interface ISqueezerManager extends ICraftingProvider { + + /** + * Add a recipe to the squeezer. + * + * @param timePerItem + * Number of work cycles required to squeeze one set of resources. + * @param resources + * Array of item stacks representing the required resources for one process. Stack size will be taken into account. + * @param liquid + * {@link FluidStack} representing the output of this recipe. + * @param remnants + * Item stack representing the possible remnants from this recipe. + * @param chance + * Chance remnants will be produced by a single recipe cycle. + */ + public void addRecipe(int timePerItem, ItemStack[] resources, FluidStack liquid, ItemStack remnants, int chance); + + /** + * Add a recipe to the squeezer. + * + * @param timePerItem + * Number of work cycles required to squeeze one set of resources. + * @param resources + * Array of item stacks representing the required resources for one process. Stack size will be taken into account. + * @param liquid + * {@link FluidStack} representing the output of this recipe. + */ + public void addRecipe(int timePerItem, ItemStack[] resources, FluidStack liquid); +} diff --git a/forestry_common/core/forestry/api/recipes/IStillManager.java b/forestry_common/core/forestry/api/recipes/IStillManager.java new file mode 100755 index 000000000..fdeaf01f6 --- /dev/null +++ b/forestry_common/core/forestry/api/recipes/IStillManager.java @@ -0,0 +1,36 @@ +/******************************************************************************* + * Copyright 2011-2014 by SirSengir + * + * This work is licensed under a Creative Commons Attribution-NonCommercial-NoDerivs 3.0 Unported License. + * + * To view a copy of this license, visit http://creativecommons.org/licenses/by-nc-nd/3.0/. + ******************************************************************************/ +package forestry.api.recipes; + +import net.minecraftforge.fluids.FluidStack; + +/** + * Provides an interface to the recipe manager of the still. + * + * The manager is initialized at the beginning of Forestry's BaseMod.load() cycle. Begin adding recipes in BaseMod.ModsLoaded() and this shouldn't be null even + * if your mod loads before Forestry. + * + * Accessible via {@link RecipeManagers} + * + * Note that this is untested with anything other than biomass->biofuel conversion. + * + * @author SirSengir + */ +public interface IStillManager extends ICraftingProvider { + /** + * Add a recipe to the still + * + * @param cyclesPerUnit + * Amount of work cycles required to run through the conversion once. + * @param input + * ItemStack representing the input liquid. + * @param output + * ItemStack representing the output liquid + */ + public void addRecipe(int cyclesPerUnit, FluidStack input, FluidStack output); +} diff --git a/forestry_common/core/forestry/api/recipes/IVariableFermentable.java b/forestry_common/core/forestry/api/recipes/IVariableFermentable.java new file mode 100755 index 000000000..5b7d1a871 --- /dev/null +++ b/forestry_common/core/forestry/api/recipes/IVariableFermentable.java @@ -0,0 +1,23 @@ +/******************************************************************************* + * Copyright 2011-2014 by SirSengir + * + * This work is licensed under a Creative Commons Attribution-NonCommercial-NoDerivs 3.0 Unported License. + * + * To view a copy of this license, visit http://creativecommons.org/licenses/by-nc-nd/3.0/. + ******************************************************************************/ +package forestry.api.recipes; + +import net.minecraft.item.ItemStack; + +/** + * Fermenter checks any valid fermentation item for an implementation of this interface. + * This does not supersede adding a proper recipe to the fermenter! + */ +public interface IVariableFermentable { + + /** + * @param itemstack + * @return Float representing the modification to be applied to the matching recipe's biomass output. + */ + float getFermentationModifier(ItemStack itemstack); +} diff --git a/forestry_common/core/forestry/api/recipes/RecipeManagers.java b/forestry_common/core/forestry/api/recipes/RecipeManagers.java new file mode 100755 index 000000000..3b3fae344 --- /dev/null +++ b/forestry_common/core/forestry/api/recipes/RecipeManagers.java @@ -0,0 +1,51 @@ +/******************************************************************************* + * Copyright 2011-2014 by SirSengir + * + * This work is licensed under a Creative Commons Attribution-NonCommercial-NoDerivs 3.0 Unported License. + * + * To view a copy of this license, visit http://creativecommons.org/licenses/by-nc-nd/3.0/. + ******************************************************************************/ +package forestry.api.recipes; + +import java.util.Collection; + +/** + * Contains all available recipe managers for Forestry machines and items. + * + * @author SirSengir + */ +public class RecipeManagers { + + public static Collection craftingProviders; + + /** + * Allows you to add recipes to the bottler. See {@link IBottlerManager} for details. + */ + public static IBottlerManager bottlerManager; + /** + * Allows you to add recipes to the carpenter. See {@link ICarpenterManager} for details. + */ + public static ICarpenterManager carpenterManager; + /** + * Allows you to add recipes to the centrifuge. See {@link ICentrifugeManager} for details. + */ + public static ICentrifugeManager centrifugeManager; + /** + * Allows you to add recipes to the fermenter. See {@link IFermenterManager} for details. + */ + public static IFermenterManager fermenterManager; + /** + * Allows you to add recipes to the moistener. See {@link IMoistenerManager} for details. + */ + public static IMoistenerManager moistenerManager; + /** + * Allows you to add recipes to the squeezer. See {@link ISqueezerManager} for details. + */ + public static ISqueezerManager squeezerManager; + /** + * Allows you to add recipes to the still. See {@link IStillManager} for details. + */ + public static IStillManager stillManager; + + public static IFabricatorManager fabricatorManager; +} diff --git a/forestry_common/core/forestry/api/recipes/package-info.java b/forestry_common/core/forestry/api/recipes/package-info.java new file mode 100755 index 000000000..b1da99013 --- /dev/null +++ b/forestry_common/core/forestry/api/recipes/package-info.java @@ -0,0 +1,10 @@ +/******************************************************************************* + * Copyright 2011-2014 by SirSengir + * + * This work is licensed under a Creative Commons Attribution-NonCommercial-NoDerivs 3.0 Unported License. + * + * To view a copy of this license, visit http://creativecommons.org/licenses/by-nc-nd/3.0/. + ******************************************************************************/ +@API(apiVersion="1.0", owner="ForestryAPI|core", provides="ForestryAPI|recipes") +package forestry.api.recipes; +import cpw.mods.fml.common.API; diff --git a/forestry_common/core/forestry/api/storage/BackpackEvent.java b/forestry_common/core/forestry/api/storage/BackpackEvent.java new file mode 100755 index 000000000..da0032e39 --- /dev/null +++ b/forestry_common/core/forestry/api/storage/BackpackEvent.java @@ -0,0 +1,27 @@ +/******************************************************************************* + * Copyright 2011-2014 by SirSengir + * + * This work is licensed under a Creative Commons Attribution-NonCommercial-NoDerivs 3.0 Unported License. + * + * To view a copy of this license, visit http://creativecommons.org/licenses/by-nc-nd/3.0/. + ******************************************************************************/ +package forestry.api.storage; + +import net.minecraft.entity.player.EntityPlayer; +import net.minecraft.inventory.IInventory; + +import cpw.mods.fml.common.eventhandler.Event; + + +public abstract class BackpackEvent extends Event { + + public final EntityPlayer player; + public final IBackpackDefinition backpackDefinition; + public final IInventory backpackInventory; + + public BackpackEvent(EntityPlayer player, IBackpackDefinition backpackDefinition, IInventory backpackInventory) { + this.player = player; + this.backpackDefinition = backpackDefinition; + this.backpackInventory = backpackInventory; + } +} diff --git a/forestry_common/core/forestry/api/storage/BackpackManager.java b/forestry_common/core/forestry/api/storage/BackpackManager.java new file mode 100755 index 000000000..8999416f1 --- /dev/null +++ b/forestry_common/core/forestry/api/storage/BackpackManager.java @@ -0,0 +1,29 @@ +/******************************************************************************* + * Copyright 2011-2014 by SirSengir + * + * This work is licensed under a Creative Commons Attribution-NonCommercial-NoDerivs 3.0 Unported License. + * + * To view a copy of this license, visit http://creativecommons.org/licenses/by-nc-nd/3.0/. + ******************************************************************************/ +package forestry.api.storage; + +import java.util.ArrayList; +import java.util.HashMap; + +import net.minecraft.item.ItemStack; + +public class BackpackManager { + /** + * 0 - Miner's Backpack 1 - Digger's Backpack 2 - Forester's Backpack 3 - Hunter's Backpack 4 - Adventurer's Backpack + * + * Use IMC messages to achieve the same effect! + */ + public static ArrayList[] backpackItems; + + public static IBackpackInterface backpackInterface; + + /** + * Only use this if you know what you are doing. Prefer backpackInterface. + */ + public static HashMap definitions = new HashMap(); +} diff --git a/forestry_common/core/forestry/api/storage/BackpackResupplyEvent.java b/forestry_common/core/forestry/api/storage/BackpackResupplyEvent.java new file mode 100755 index 000000000..8a1ac9e06 --- /dev/null +++ b/forestry_common/core/forestry/api/storage/BackpackResupplyEvent.java @@ -0,0 +1,26 @@ +/******************************************************************************* + * Copyright 2011-2014 by SirSengir + * + * This work is licensed under a Creative Commons Attribution-NonCommercial-NoDerivs 3.0 Unported License. + * + * To view a copy of this license, visit http://creativecommons.org/licenses/by-nc-nd/3.0/. + ******************************************************************************/ +package forestry.api.storage; + +import net.minecraft.entity.player.EntityPlayer; +import net.minecraft.inventory.IInventory; + +import cpw.mods.fml.common.eventhandler.Cancelable; + +/** + * Use @SubscribeEvent on a method taking this event as an argument. Will fire whenever a backpack tries to resupply to a player inventory. Processing will stop + * if the event is canceled. + */ +@Cancelable +public class BackpackResupplyEvent extends BackpackEvent { + + public BackpackResupplyEvent(EntityPlayer player, IBackpackDefinition backpackDefinition, IInventory backpackInventory) { + super(player, backpackDefinition, backpackInventory); + } + +} diff --git a/forestry_common/core/forestry/api/storage/BackpackStowEvent.java b/forestry_common/core/forestry/api/storage/BackpackStowEvent.java new file mode 100755 index 000000000..195fce1b5 --- /dev/null +++ b/forestry_common/core/forestry/api/storage/BackpackStowEvent.java @@ -0,0 +1,29 @@ +/******************************************************************************* + * Copyright 2011-2014 by SirSengir + * + * This work is licensed under a Creative Commons Attribution-NonCommercial-NoDerivs 3.0 Unported License. + * + * To view a copy of this license, visit http://creativecommons.org/licenses/by-nc-nd/3.0/. + ******************************************************************************/ +package forestry.api.storage; + +import net.minecraft.entity.player.EntityPlayer; +import net.minecraft.inventory.IInventory; +import net.minecraft.item.ItemStack; + +import cpw.mods.fml.common.eventhandler.Cancelable; + +/** + * Use @SubscribeEvent on a method taking this event as an argument. Will fire whenever a backpack tries to store an item. Processing will stop if the stacksize + * of stackToStow drops to 0 or less or the event is canceled. + */ +@Cancelable +public class BackpackStowEvent extends BackpackEvent { + + public final ItemStack stackToStow; + + public BackpackStowEvent(EntityPlayer player, IBackpackDefinition backpackDefinition, IInventory backpackInventory, ItemStack stackToStow) { + super(player, backpackDefinition, backpackInventory); + this.stackToStow = stackToStow; + } +} diff --git a/forestry_common/core/forestry/api/storage/EnumBackpackType.java b/forestry_common/core/forestry/api/storage/EnumBackpackType.java new file mode 100755 index 000000000..c56121d5e --- /dev/null +++ b/forestry_common/core/forestry/api/storage/EnumBackpackType.java @@ -0,0 +1,12 @@ +/******************************************************************************* + * Copyright 2011-2014 by SirSengir + * + * This work is licensed under a Creative Commons Attribution-NonCommercial-NoDerivs 3.0 Unported License. + * + * To view a copy of this license, visit http://creativecommons.org/licenses/by-nc-nd/3.0/. + ******************************************************************************/ +package forestry.api.storage; + +public enum EnumBackpackType { + T1, T2 +} diff --git a/forestry_common/core/forestry/api/storage/IBackpackDefinition.java b/forestry_common/core/forestry/api/storage/IBackpackDefinition.java new file mode 100755 index 000000000..6203b015e --- /dev/null +++ b/forestry_common/core/forestry/api/storage/IBackpackDefinition.java @@ -0,0 +1,61 @@ +/******************************************************************************* + * Copyright 2011-2014 by SirSengir + * + * This work is licensed under a Creative Commons Attribution-NonCommercial-NoDerivs 3.0 Unported License. + * + * To view a copy of this license, visit http://creativecommons.org/licenses/by-nc-nd/3.0/. + ******************************************************************************/ +package forestry.api.storage; + +import java.util.Collection; + +import net.minecraft.entity.player.EntityPlayer; +import net.minecraft.item.ItemStack; + +public interface IBackpackDefinition { + + /** + * @return A unique string identifier + */ + String getKey(); + + /** + * @return Human-readable name of the backpack. + */ + String getName(); + + /** + * @return Primary colour for the backpack icon. + */ + int getPrimaryColour(); + + /** + * @return Secondary colour for backpack icon. + */ + int getSecondaryColour(); + + /** + * Adds an item as valid for this backpack. + * + * @param validItem + */ + void addValidItem(ItemStack validItem); + + /** + * Returns an arraylist of all items valid for this backpack type. + * + * @param player + * @return Collection of itemstack which are valid items for this backpack type. May be empty or null and does not necessarily include all valid items. + */ + Collection getValidItems(EntityPlayer player); + + /** + * Returns true if the itemstack is a valid item for this backpack type. + * + * @param player + * @param itemstack + * @return true if the given itemstack is valid for this backpack, false otherwise. + */ + boolean isValidItem(EntityPlayer player, ItemStack itemstack); + +} diff --git a/forestry_common/core/forestry/api/storage/IBackpackInterface.java b/forestry_common/core/forestry/api/storage/IBackpackInterface.java new file mode 100755 index 000000000..2450cc188 --- /dev/null +++ b/forestry_common/core/forestry/api/storage/IBackpackInterface.java @@ -0,0 +1,24 @@ +/******************************************************************************* + * Copyright 2011-2014 by SirSengir + * + * This work is licensed under a Creative Commons Attribution-NonCommercial-NoDerivs 3.0 Unported License. + * + * To view a copy of this license, visit http://creativecommons.org/licenses/by-nc-nd/3.0/. + ******************************************************************************/ +package forestry.api.storage; + +import net.minecraft.item.Item; + +public interface IBackpackInterface { + + /** + * Adds a backpack with the given definition and type, returning the item. + * + * @param definition + * Definition of backpack behaviour. + * @param type + * Type of backpack. (T1 or T2 (= Woven) + * @return Created backpack item. + */ + Item addBackpack(IBackpackDefinition definition, EnumBackpackType type); +} diff --git a/forestry_common/core/forestry/api/storage/package-info.java b/forestry_common/core/forestry/api/storage/package-info.java new file mode 100755 index 000000000..e18563c62 --- /dev/null +++ b/forestry_common/core/forestry/api/storage/package-info.java @@ -0,0 +1,10 @@ +/******************************************************************************* + * Copyright 2011-2014 by SirSengir + * + * This work is licensed under a Creative Commons Attribution-NonCommercial-NoDerivs 3.0 Unported License. + * + * To view a copy of this license, visit http://creativecommons.org/licenses/by-nc-nd/3.0/. + ******************************************************************************/ +@API(apiVersion="1.0", owner="ForestryAPI|core", provides="ForestryAPI|storage") +package forestry.api.storage; +import cpw.mods.fml.common.API; diff --git a/forestry_common/core/forestry/api/world/ITreeGenData.java b/forestry_common/core/forestry/api/world/ITreeGenData.java new file mode 100755 index 000000000..2858ad0b0 --- /dev/null +++ b/forestry_common/core/forestry/api/world/ITreeGenData.java @@ -0,0 +1,25 @@ +/******************************************************************************* + * Copyright 2011-2014 by SirSengir + * + * This work is licensed under a Creative Commons Attribution-NonCommercial-NoDerivs 3.0 Unported License. + * + * To view a copy of this license, visit http://creativecommons.org/licenses/by-nc-nd/3.0/. + ******************************************************************************/ +package forestry.api.world; + +import net.minecraft.world.World; + +public interface ITreeGenData { + + int getGirth(World world, int x, int y, int z); + + float getHeightModifier(); + + boolean canGrow(World world, int x, int y, int z, int expectedGirth, int expectedHeight); + + void setLeaves(World world, String owner, int x, int y, int z); + + boolean allowsFruitBlocks(); + + boolean trySpawnFruitBlock(World world, int x, int y, int z); +} diff --git a/forestry_common/core/forestry/api/world/IWorldGenInterface.java b/forestry_common/core/forestry/api/world/IWorldGenInterface.java new file mode 100755 index 000000000..91d2abcc2 --- /dev/null +++ b/forestry_common/core/forestry/api/world/IWorldGenInterface.java @@ -0,0 +1,24 @@ +/******************************************************************************* + * Copyright 2011-2014 by SirSengir + * + * This work is licensed under a Creative Commons Attribution-NonCommercial-NoDerivs 3.0 Unported License. + * + * To view a copy of this license, visit http://creativecommons.org/licenses/by-nc-nd/3.0/. + ******************************************************************************/ +package forestry.api.world; + +import net.minecraft.world.gen.feature.WorldGenerator; + +public interface IWorldGenInterface { + + /** + * Retrieves generators for trees identified by a given string. + * + * Returned generator classes take an {@link ITreeGenData} in the constructor. + * + * @param ident + * Unique identifier for tree type. Forestry's convention is 'treeSpecies', i.e. 'treeBaobab', 'treeSequoia'. + * @return All generators matching the given ident. + */ + Class[] getTreeGenerators(String ident); +} diff --git a/forestry_common/core/forestry/api/world/WorldGenManager.java b/forestry_common/core/forestry/api/world/WorldGenManager.java new file mode 100755 index 000000000..0a5accd0c --- /dev/null +++ b/forestry_common/core/forestry/api/world/WorldGenManager.java @@ -0,0 +1,12 @@ +/******************************************************************************* + * Copyright 2011-2014 by SirSengir + * + * This work is licensed under a Creative Commons Attribution-NonCommercial-NoDerivs 3.0 Unported License. + * + * To view a copy of this license, visit http://creativecommons.org/licenses/by-nc-nd/3.0/. + ******************************************************************************/ +package forestry.api.world; + +public class WorldGenManager { + public static IWorldGenInterface worldgenInterface; +} diff --git a/forestry_common/core/forestry/api/world/package-info.java b/forestry_common/core/forestry/api/world/package-info.java new file mode 100755 index 000000000..25762a119 --- /dev/null +++ b/forestry_common/core/forestry/api/world/package-info.java @@ -0,0 +1,10 @@ +/******************************************************************************* + * Copyright 2011-2014 by SirSengir + * + * This work is licensed under a Creative Commons Attribution-NonCommercial-NoDerivs 3.0 Unported License. + * + * To view a copy of this license, visit http://creativecommons.org/licenses/by-nc-nd/3.0/. + ******************************************************************************/ +@API(apiVersion="1.0", owner="ForestryAPI|core", provides="ForestryAPI|world") +package forestry.api.world; +import cpw.mods.fml.common.API; diff --git a/forestry_common/core/forestry/core/CommandForestry.java b/forestry_common/core/forestry/core/CommandForestry.java new file mode 100755 index 000000000..c4f55d29d --- /dev/null +++ b/forestry_common/core/forestry/core/CommandForestry.java @@ -0,0 +1,166 @@ +/******************************************************************************* + * Copyright 2011-2014 by SirSengir + * + * This work is licensed under a Creative Commons Attribution-NonCommercial-NoDerivs 3.0 Unported License. + * + * To view a copy of this license, visit http://creativecommons.org/licenses/by-nc-nd/3.0/. + ******************************************************************************/ +package forestry.core; + +import java.util.List; + +import net.minecraft.command.CommandException; +import net.minecraft.command.ICommand; +import net.minecraft.command.ICommandSender; +import net.minecraft.command.WrongUsageException; +import net.minecraft.entity.player.EntityPlayer; + +import forestry.api.core.IPlugin; +import forestry.api.core.PluginInfo; +import forestry.core.config.Version; +import forestry.core.proxy.Proxies; +import forestry.core.utils.CommandMC; +import forestry.plugins.PluginManager; + +public class CommandForestry extends CommandMC { + + @Override + public int compareTo(Object arg0) { + return this.getCommandName().compareTo(((ICommand) arg0).getCommandName()); + } + + @Override + public String getCommandName() { + return "forestry"; + } + + @Override + public String getCommandUsage(ICommandSender sender) { + return "/" + this.getCommandName() + " help"; + } + + @SuppressWarnings("rawtypes") + @Override + public List getCommandAliases() { + return null; + } + + @Override + public void processCommand(ICommandSender sender, String[] arguments) { + + if (arguments.length <= 0) + throw new WrongUsageException("Type '" + this.getCommandUsage(sender) + "' for help."); + + if (arguments[0].matches("version")) { + commandVersion(sender, arguments); + return; + } else if (arguments[0].matches("plugins")) { + commandPlugins(sender, arguments); + return; + } else if (arguments[0].matches("help")) { + sendChatMessage(sender, "Format: '" + this.getCommandName() + " '"); + sendChatMessage(sender, "Available commands:"); + sendChatMessage(sender, "- version : Version information."); + sendChatMessage(sender, "- plugins : list of Forestry plugins."); + sendChatMessage(sender, "- plugins info : information on plugin."); + return; + } + + throw new WrongUsageException(this.getCommandUsage(sender)); + } + + private void commandVersion(ICommandSender sender, String[] arguments) { + String colour = Version.isOutdated() ? "\u00A7c" : "\u00A7a"; + + sendChatMessage(sender, String.format(colour + "Forestry %s for Minecraft %s (Latest: %s).", Version.getVersion(), + Proxies.common.getMinecraftVersion(), Version.getRecommendedVersion())); + if (Version.isOutdated()) + for (String updateLine : Version.getChangelog()) + sendChatMessage(sender, "\u00A79" + updateLine); + } + + private void commandPlugins(ICommandSender sender, String[] arguments) { + + if (arguments.length <= 1) + listPluginsForSender(sender); + else if (arguments[1].matches("info")) + listPluginInfoForSender(sender, arguments); + + } + + private void listPluginsForSender(ICommandSender sender) { + + String pluginList = ""; + + for (IPlugin plugin : PluginManager.plugins) { + if (!pluginList.isEmpty()) + pluginList += ", "; + pluginList += makeListEntry(plugin); + } + + sendChatMessage(sender, pluginList); + } + + private void listPluginInfoForSender(ICommandSender sender, String[] arguments) { + + if (arguments.length < 3) + throw new WrongUsageException("/" + getCommandName() + " plugins info "); + + IPlugin found = null; + for (IPlugin plugin : PluginManager.plugins) { + PluginInfo info = plugin.getClass().getAnnotation(PluginInfo.class); + if (info == null) + continue; + + if ((info.pluginID().equalsIgnoreCase(arguments[2]) || info.name().equalsIgnoreCase(arguments[2]))) { + found = plugin; + break; + } + } + + if (found == null) + throw new CommandException("No information available for plugin " + arguments[2] + "."); + + String entry = "\u00A7c"; + if (found.isAvailable()) + entry = "\u00A7a"; + PluginInfo info = found.getClass().getAnnotation(PluginInfo.class); + if (info != null) { + sendChatMessage(sender, entry + "Plugin: " + info.name()); + if (!info.version().isEmpty()) + sendChatMessage(sender, "\u00A79Version: " + info.version()); + if (!info.author().isEmpty()) + sendChatMessage(sender, "\u00A79Author(s): " + info.author()); + if (!info.url().isEmpty()) + sendChatMessage(sender, "\u00A79URL: " + info.url()); + if (!info.description().isEmpty()) + sendChatMessage(sender, info.description()); + } + + } + + private String makeListEntry(IPlugin plugin) { + String entry = "\u00A7c"; + if (plugin.isAvailable()) + entry = "\u00A7a"; + + PluginInfo info = plugin.getClass().getAnnotation(PluginInfo.class); + if (info != null) { + entry += info.pluginID(); + if (!info.version().isEmpty()) + entry += " (" + info.version() + ")"; + } else + entry += "???"; + + return entry; + } + + @Override + public boolean canCommandSenderUseCommand(ICommandSender sender) { + if (sender instanceof EntityPlayer) + return Proxies.common.isOp((EntityPlayer) sender); + else + return sender.canCommandSenderUseCommand(4, getCommandName()); + } + +} diff --git a/forestry_common/core/forestry/core/CreativeTabForestry.java b/forestry_common/core/forestry/core/CreativeTabForestry.java new file mode 100755 index 000000000..7cf288bdf --- /dev/null +++ b/forestry_common/core/forestry/core/CreativeTabForestry.java @@ -0,0 +1,58 @@ +/******************************************************************************* + * Copyright 2011-2014 by SirSengir + * + * This work is licensed under a Creative Commons Attribution-NonCommercial-NoDerivs 3.0 Unported License. + * + * To view a copy of this license, visit http://creativecommons.org/licenses/by-nc-nd/3.0/. + ******************************************************************************/ +package forestry.core; + +import net.minecraft.creativetab.CreativeTabs; +import net.minecraft.item.Item; +import net.minecraft.item.ItemStack; + +import forestry.api.core.ItemInterface; +import forestry.api.core.Tabs; +import forestry.core.utils.StringUtil; + +public class CreativeTabForestry extends CreativeTabs { + + static { + Tabs.tabApiculture = new CreativeTabForestry(1, "apiculture"); + Tabs.tabArboriculture = new CreativeTabForestry(2, "arboriculture"); + Tabs.tabLepidopterology = new CreativeTabForestry(3, "lepidopterology"); + } + public static final CreativeTabs tabForestry = new CreativeTabForestry(0, "forestry"); + + private final int icon; + + public CreativeTabForestry(int icon, String label) { + super(label); + this.icon = icon; + } + + @Override + public ItemStack getIconItemStack() { + switch (icon) { + case 1: + return ItemInterface.getItem("beeDroneGE"); + case 2: + return ItemInterface.getItem("sapling"); + case 3: + return ItemInterface.getItem("butterflyGE"); + case 0: + default: + return ItemInterface.getItem("fertilizerCompound"); + } + } + + @Override + public String getTranslatedTabLabel() { + return StringUtil.localize("itemGroup." + this.getTabLabel()); + } + + @Override + public Item getTabIconItem() { + return null; // not used due to overridden getIconItemStack + } +} diff --git a/forestry_common/core/forestry/core/EnumErrorCode.java b/forestry_common/core/forestry/core/EnumErrorCode.java new file mode 100755 index 000000000..cd41ed758 --- /dev/null +++ b/forestry_common/core/forestry/core/EnumErrorCode.java @@ -0,0 +1,119 @@ +/******************************************************************************* + * Copyright 2011-2014 by SirSengir + * + * This work is licensed under a Creative Commons Attribution-NonCommercial-NoDerivs 3.0 Unported License. + * + * To view a copy of this license, visit http://creativecommons.org/licenses/by-nc-nd/3.0/. + ******************************************************************************/ +package forestry.core; + +import net.minecraft.client.renderer.texture.IIconRegister; +import net.minecraft.util.IIcon; + +import cpw.mods.fml.relauncher.Side; +import cpw.mods.fml.relauncher.SideOnly; + +import forestry.core.render.TextureManager; + +public enum EnumErrorCode { + + UNKNOWN("unknown", 0), + + OK("ok", 1), + + INVALIDBIOME("invalidBiome", 2), + + ISRAINING("isRaining", 3), + + NOTRAINING("notRaining", 4), + + NOFUEL("noFuel", 5), // Biogas & Peat-fired + + NOHEAT("noHeat", 6), // Biogas engine + + NODISPOSAL("noDisposal", 7), + + NORESOURCE("noResource", 8), + + NOTGLOOMY("notGloomy", 9), + + NOTLUCID("notLucid", 10), + + NOTDAY("notDay", 11), + + NOTNIGHT("notNight", 12), + + NOFLOWER("noFlower", 13), + + NOQUEEN("noQueen", 14), + + NODRONE("noDrone", 15), + + NOSKY("noSky", 16), + + NOSPACE("noSpace", 17), + + NORECIPE("noRecipe", 19), + + NOENERGYNET("noEnergyNet", 20), + + NOTHINGANALYZE("noSpecimen", 15), + + FORCEDCOOLDOWN("forcedCooldown", 21), + + NOHONEY("noHoney", 22), + + NOTPOSTPAID("notPostpaid", 23), + + NORECIPIENT("noRecipient", 24), + + NOTALPHANUMERIC("notAlphaNumeric", 25), + + NOTUNIQUE("notUnique", 26), + + NOSTAMPS("noStamps", 23), + + NOCIRCUITBOARD("noCircuitBoard", 28), + + WRONGSTACKSIZE("wrongStacksize", 26), + + NOFERTILIZER("noFertilizer", 5), + + NOFARMLAND("noFarmland", 27), + + CIRCUITMISMATCH("circuitMismatch", 26), + + NOLIQUID("noLiquid", 29); + + private String name; + @SideOnly(Side.CLIENT) + private IIcon icon; + + private EnumErrorCode(String name, int iconIndex) { + this.name = name; + } + + public String getDescription() { + return "errors." + name + ".desc"; + } + + public String getHelp() { + return "errors." + name + ".help"; + } + + @SideOnly(Side.CLIENT) + public void registerIcons(IIconRegister register) { + icon = TextureManager.getInstance().registerTex(register, "errors/" + name); + } + + @SideOnly(Side.CLIENT) + public IIcon getIcon() { + return icon; + } + + @SideOnly(Side.CLIENT) + public static void initIcons(IIconRegister register) { + for (EnumErrorCode code : values()) + code.registerIcons(register); + } +} diff --git a/forestry_common/core/forestry/core/EventHandlerCore.java b/forestry_common/core/forestry/core/EventHandlerCore.java new file mode 100755 index 000000000..c5f576990 --- /dev/null +++ b/forestry_common/core/forestry/core/EventHandlerCore.java @@ -0,0 +1,97 @@ +/******************************************************************************* + * Copyright 2011-2014 by SirSengir + * + * This work is licensed under a Creative Commons Attribution-NonCommercial-NoDerivs 3.0 Unported License. + * + * To view a copy of this license, visit http://creativecommons.org/licenses/by-nc-nd/3.0/. + ******************************************************************************/ +package forestry.core; + +import net.minecraft.item.ItemStack; + +import cpw.mods.fml.common.eventhandler.Event.Result; +import cpw.mods.fml.common.eventhandler.SubscribeEvent; +import cpw.mods.fml.relauncher.Side; +import cpw.mods.fml.relauncher.SideOnly; + +import net.minecraftforge.client.event.TextureStitchEvent; +import net.minecraftforge.event.entity.player.EntityItemPickupEvent; +import net.minecraftforge.event.world.WorldEvent; +import net.minecraftforge.oredict.OreDictionary; + +import forestry.core.interfaces.IOreDictionaryHandler; +import forestry.core.interfaces.IPickupHandler; +import forestry.core.interfaces.ISaveEventHandler; +import forestry.core.render.TextureManager; +import forestry.core.utils.LiquidHelper; +import forestry.plugins.PluginManager; + +public class EventHandlerCore { + + public EventHandlerCore() { + for(String name : OreDictionary.getOreNames()) + for(ItemStack ore : OreDictionary.getOres(name)) + handleOreRegistration(name, ore); + } + + @SubscribeEvent + public void handleItemPickup(EntityItemPickupEvent event) { + + if (event.isCanceled()) + return; + + for (IPickupHandler handler : PluginManager.pickupHandlers) + if (!handler.onItemPickup(event.entityPlayer, event.item)) { + event.setResult(Result.ALLOW); + return; + } + } + + @SubscribeEvent + public void handleOreRegistration(OreDictionary.OreRegisterEvent event) { + + if (event.isCanceled()) + return; + + handleOreRegistration(event.Name, event.Ore); + } + + private void handleOreRegistration(String name, ItemStack ore) { + for (IOreDictionaryHandler handler : PluginManager.dictionaryHandlers) + handler.onOreRegistration(name, ore); + } + + @SubscribeEvent + public void handleWorldLoad(WorldEvent.Load event) { + for (ISaveEventHandler handler : PluginManager.saveEventHandlers) + handler.onWorldLoad(event.world); + } + + @SubscribeEvent + public void handleWorldSave(WorldEvent.Save event) { + for (ISaveEventHandler handler : PluginManager.saveEventHandlers) + handler.onWorldSave(event.world); + } + + @SubscribeEvent + public void handleWorldUnload(WorldEvent.Unload event) { + for (ISaveEventHandler handler : PluginManager.saveEventHandlers) + handler.onWorldUnload(event.world); + } + + @SubscribeEvent + @SideOnly(Side.CLIENT) + public void handleTextureRemap(TextureStitchEvent.Pre event) { + if(event.map.getTextureType() == 1) { + EnumErrorCode.initIcons(event.map); + TextureManager.getInstance().initDefaultIcons(event.map); + } else if(event.map.getTextureType() == 0) + LiquidHelper.resetLiquidIcons(event.map); + } + + @SubscribeEvent + @SideOnly(Side.CLIENT) + public void handleTexturePostmap(TextureStitchEvent.Post event) { + } + +} diff --git a/forestry_common/core/forestry/core/ForestryClient.java b/forestry_common/core/forestry/core/ForestryClient.java new file mode 100755 index 000000000..480f2d50c --- /dev/null +++ b/forestry_common/core/forestry/core/ForestryClient.java @@ -0,0 +1,41 @@ +/******************************************************************************* + * Copyright 2011-2014 by SirSengir + * + * This work is licensed under a Creative Commons Attribution-NonCommercial-NoDerivs 3.0 Unported License. + * + * To view a copy of this license, visit http://creativecommons.org/licenses/by-nc-nd/3.0/. + ******************************************************************************/ +package forestry.core; + +import cpw.mods.fml.client.registry.RenderingRegistry; + +import forestry.apiculture.render.BlockCandleRenderer; +import forestry.core.proxy.Proxies; +import forestry.core.render.BlockRenderingHandler; + +public class ForestryClient extends ForestryCore { + + public static int byBlockModelId; + public static int candleRenderId; + public static int blockModelIdEngine; + + @Override + public void init(Object basemod) { + + super.init(basemod); + + byBlockModelId = Proxies.render.getNextAvailableRenderId(); + candleRenderId = Proxies.render.getNextAvailableRenderId(); + blockModelIdEngine = Proxies.render.getNextAvailableRenderId(); + + BlockRenderingHandler renderHandler = new BlockRenderingHandler(); + RenderingRegistry.registerBlockHandler(byBlockModelId, renderHandler); + RenderingRegistry.registerBlockHandler(candleRenderId, new BlockCandleRenderer()); + } + + @Override + public void postInit() { + super.postInit(); + } + +} diff --git a/forestry_common/core/forestry/core/ForestryConstants.java b/forestry_common/core/forestry/core/ForestryConstants.java new file mode 100755 index 000000000..a45f7c057 --- /dev/null +++ b/forestry_common/core/forestry/core/ForestryConstants.java @@ -0,0 +1,30 @@ +/******************************************************************************* + * Copyright 2011-2014 by SirSengir + * + * This work is licensed under a Creative Commons Attribution-NonCommercial-NoDerivs 3.0 Unported License. + * + * To view a copy of this license, visit http://creativecommons.org/licenses/by-nc-nd/3.0/. + ******************************************************************************/ +package forestry.core; + +import forestry.api.core.IForestryConstants; +import forestry.core.config.Defaults; + +public class ForestryConstants implements IForestryConstants { + + @Override + public int getApicultureVillagerID() { + return Defaults.ID_VILLAGER_BEEKEEPER; + } + + @Override + public int getArboricultureVillagerID() { + return Defaults.ID_VILLAGER_LUMBERJACK; + } + + @Override + public String getVillagerChestGenKey() { + return Defaults.CHEST_GEN_HOOK_NATURALIST_CHEST; + } + +} diff --git a/forestry_common/core/forestry/core/ForestryCore.java b/forestry_common/core/forestry/core/ForestryCore.java new file mode 100755 index 000000000..1d5cd84d5 --- /dev/null +++ b/forestry_common/core/forestry/core/ForestryCore.java @@ -0,0 +1,251 @@ +/******************************************************************************* + * Copyright 2011-2014 by SirSengir + * + * This work is licensed under a Creative Commons Attribution-NonCommercial-NoDerivs 3.0 Unported License. + * + * To view a copy of this license, visit http://creativecommons.org/licenses/by-nc-nd/3.0/. + ******************************************************************************/ +package forestry.core; + +import java.io.File; + +import net.minecraft.command.CommandHandler; +import net.minecraft.command.ICommand; +import net.minecraft.init.Blocks; +import net.minecraft.init.Items; +import net.minecraft.item.ItemStack; +import net.minecraft.server.MinecraftServer; + +import cpw.mods.fml.common.event.FMLInterModComms; +import cpw.mods.fml.common.event.FMLInterModComms.IMCMessage; +import cpw.mods.fml.common.network.NetworkRegistry; +import cpw.mods.fml.common.registry.GameRegistry; + +import net.minecraftforge.common.MinecraftForge; + +import com.google.common.collect.ImmutableList; + +import forestry.api.apiculture.FlowerManager; +import forestry.api.core.ForestryAPI; +import forestry.api.core.IPlugin; +import forestry.api.fuels.EngineBronzeFuel; +import forestry.api.fuels.EngineCopperFuel; +import forestry.api.fuels.FermenterFuel; +import forestry.api.fuels.FuelManager; +import forestry.api.fuels.MoistenerFuel; +import forestry.api.fuels.RainSubstrate; +import forestry.core.config.Config; +import forestry.core.config.Defaults; +import forestry.core.config.ForestryItem; +import forestry.core.config.Version; +import forestry.core.gadgets.TileEngine; +import forestry.core.gadgets.TileMachine; +import forestry.core.gadgets.TileMill; +import forestry.core.proxy.Proxies; +import forestry.core.utils.LiquidHelper; +import forestry.plugins.NativePlugin; +import forestry.plugins.PluginCore; +import forestry.plugins.PluginManager; + +public class ForestryCore { + + public void preInit(File modLocation, Object basemod) { + ForestryAPI.instance = basemod; + ForestryAPI.forestryConstants = new ForestryConstants(); + + PluginManager.loadPlugins(modLocation); + + // Register event handler + MinecraftForge.EVENT_BUS.register(new EventHandlerCore()); + + Config.load(); + if (!Config.disableVersionCheck) + Version.versionCheck(); + + for (IPlugin plugin : PluginManager.plugins) { + if (plugin instanceof PluginCore) + plugin.preInit(); + } + + for (IPlugin plugin : PluginManager.plugins) { + if (plugin instanceof PluginCore) + continue; + + if (plugin.isAvailable()) + plugin.preInit(); + else + Proxies.log.fine("Skipped plugin " + plugin.getClass() + " because preconditions were not met."); + } + + } + + public void init(Object basemod) { + + // Register Liquids & Containers + registerLiquidContainers(); + + // Register world generator + GameRegistry.registerWorldGenerator(new WorldGenerator(), 0); + + // Set fuels and resources for the fermenter + FuelManager.fermenterFuel.put(ForestryItem.fertilizerCompound.getItemStack(), new FermenterFuel(ForestryItem.fertilizerCompound.getItemStack(), + GameMode.getGameMode().getIntegerSetting("fermenter.value.fertilizer"), GameMode.getGameMode().getIntegerSetting("fermenter.cycles.fertilizer"))); + FuelManager.fermenterFuel.put(ForestryItem.fertilizerBio.getItemStack(), new FermenterFuel(ForestryItem.fertilizerBio.getItemStack(), GameMode + .getGameMode().getIntegerSetting("fermenter.value.compost"), GameMode.getGameMode().getIntegerSetting("fermenter.cycles.compost"))); + FuelManager.fermenterFuel.put(ForestryItem.mulch.getItemStack(), new FermenterFuel(ForestryItem.mulch.getItemStack(), GameMode.getGameMode() + .getIntegerSetting("fermenter.value.compost"), GameMode.getGameMode().getIntegerSetting("fermenter.cycles.compost"))); + + // Add moistener resources + FuelManager.moistenerResource.put(new ItemStack(Items.wheat), new MoistenerFuel(new ItemStack(Items.wheat), ForestryItem.mouldyWheat.getItemStack(), 0, + 300)); + FuelManager.moistenerResource.put(ForestryItem.mouldyWheat.getItemStack(), new MoistenerFuel(ForestryItem.mouldyWheat.getItemStack(), ForestryItem.decayingWheat.getItemStack(), 1, 600)); + FuelManager.moistenerResource.put(ForestryItem.decayingWheat.getItemStack(), new MoistenerFuel(ForestryItem.decayingWheat.getItemStack(), + ForestryItem.mulch.getItemStack(), 2, 900)); + + // Set fuels for our own engines + FuelManager.copperEngineFuel.put(ForestryItem.peat.getItemStack(), new EngineCopperFuel(ForestryItem.peat.getItemStack(), + Defaults.ENGINE_COPPER_FUEL_VALUE_PEAT, Defaults.ENGINE_COPPER_CYCLE_DURATION_PEAT)); + FuelManager.copperEngineFuel.put(ForestryItem.bituminousPeat.getItemStack(), new EngineCopperFuel(ForestryItem.bituminousPeat.getItemStack(), + Defaults.ENGINE_COPPER_FUEL_VALUE_BITUMINOUS_PEAT, Defaults.ENGINE_COPPER_CYCLE_DURATION_BITUMINOUS_PEAT)); + FuelManager.bronzeEngineFuel.put(LiquidHelper.getFluid(Defaults.LIQUID_BIOMASS), new EngineBronzeFuel(LiquidHelper.getFluid(Defaults.LIQUID_BIOMASS), + Defaults.ENGINE_FUEL_VALUE_BIOMASS, (int) (Defaults.ENGINE_CYCLE_DURATION_BIOMASS * GameMode.getGameMode().getFloatSetting("fuel.biomass.biogas")), 1)); + FuelManager.bronzeEngineFuel.put(LiquidHelper.getFluid(Defaults.LIQUID_WATER), new EngineBronzeFuel(LiquidHelper.getFluid(Defaults.LIQUID_WATER), + Defaults.ENGINE_FUEL_VALUE_WATER, Defaults.ENGINE_CYCLE_DURATION_WATER, 3)); + FuelManager.bronzeEngineFuel.put(LiquidHelper.getFluid(Defaults.LIQUID_MILK), new EngineBronzeFuel(LiquidHelper.getFluid(Defaults.LIQUID_MILK), + Defaults.ENGINE_FUEL_VALUE_MILK, Defaults.ENGINE_CYCLE_DURATION_MILK, 3)); + FuelManager.bronzeEngineFuel.put(LiquidHelper.getFluid(Defaults.LIQUID_SEEDOIL), new EngineBronzeFuel(LiquidHelper.getFluid(Defaults.LIQUID_SEEDOIL), + Defaults.ENGINE_FUEL_VALUE_SEED_OIL, Defaults.ENGINE_CYCLE_DURATION_SEED_OIL, 1)); + FuelManager.bronzeEngineFuel.put(LiquidHelper.getFluid(Defaults.LIQUID_HONEY), new EngineBronzeFuel(LiquidHelper.getFluid(Defaults.LIQUID_HONEY), + Defaults.ENGINE_FUEL_VALUE_HONEY, Defaults.ENGINE_CYCLE_DURATION_HONEY, 1)); + FuelManager.bronzeEngineFuel.put(LiquidHelper.getFluid(Defaults.LIQUID_JUICE), new EngineBronzeFuel(LiquidHelper.getFluid(Defaults.LIQUID_JUICE), + Defaults.ENGINE_FUEL_VALUE_JUICE, Defaults.ENGINE_CYCLE_DURATION_JUICE, 1)); + + // Set rain substrates + FuelManager.rainSubstrate.put(ForestryItem.iodineCharge.getItemStack(), new RainSubstrate(ForestryItem.iodineCharge.getItemStack(), + Defaults.RAINMAKER_RAIN_DURATION_IODINE, 0.01f)); + FuelManager.rainSubstrate.put(ForestryItem.craftingMaterial.getItemStack(1, 4), new RainSubstrate(ForestryItem.craftingMaterial.getItemStack(1, 4), 0.075f)); + + // Set additional apiary flowers + FlowerManager.plainFlowers.add(new ItemStack(Blocks.red_flower)); + FlowerManager.plainFlowers.add(new ItemStack(Blocks.yellow_flower)); + + // Register gui handler + NetworkRegistry.INSTANCE.registerGuiHandler(basemod, new GuiHandler()); + + // Register machines + GameRegistry.registerTileEntity(TileMill.class, "forestry.Grower"); + GameRegistry.registerTileEntity(TileEngine.class, "forestry.Engine"); + GameRegistry.registerTileEntity(TileMachine.class, "forestry.Machine"); + + + } + + public void postInit() { + + for (IPlugin plugin : PluginManager.plugins) { + if (plugin.isAvailable()) + plugin.doInit(); + } + + for (IPlugin plugin : PluginManager.plugins) { + if (plugin.isAvailable()) + plugin.postInit(); + } + + Proxies.common.registerTickHandlers(); + + // Handle IMC messages. + processIMCMessages(FMLInterModComms.fetchRuntimeMessages(ForestryAPI.instance)); + } + + public void serverStarting(MinecraftServer server) { + CommandHandler commandManager = (CommandHandler) server.getCommandManager(); + for (IPlugin plugin : PluginManager.plugins) { + if (plugin.isAvailable() && plugin instanceof NativePlugin) { + ICommand[] commands = ((NativePlugin) plugin).getConsoleCommands(); + if (commands == null) + continue; + for (ICommand command : commands) { + commandManager.registerCommand(command); + } + } + } + } + + public void processIMCMessages(ImmutableList messages) { + for (IMCMessage message : messages) { + for (IPlugin plugin : PluginManager.plugins) { + if (!(plugin instanceof NativePlugin)) + continue; + + if (((NativePlugin) plugin).processIMCMessage(message)) + break; + } + } + } + + public String getPriorities() { + return "after:mod_IC2;after:mod_BuildCraftCore;after:mod_BuildCraftEnergy;after:mod_BuildCraftFactory;after:mod_BuildCraftSilicon;after:mod_BuildCraftTransport;after:mod_RedPowerWorld"; + } + + private void registerLiquidContainers() { + // Add lava and water buckets to the API in case this has not been done yet. + if (LiquidHelper.isEmptyLiquidData()) { + LiquidHelper.injectLiquidContainer(Defaults.LIQUID_LAVA, Defaults.BUCKET_VOLUME, new ItemStack(Items.lava_bucket), new ItemStack(Items.bucket)); + LiquidHelper.injectLiquidContainer(Defaults.LIQUID_WATER, Defaults.BUCKET_VOLUME, new ItemStack(Items.water_bucket), new ItemStack(Items.bucket)); + } + + // Glass + LiquidHelper.getOrCreateLiquid(Defaults.LIQUID_GLASS); + + // Set default lava, water and biofuel buckets + LiquidHelper.getOrCreateLiquid(Defaults.LIQUID_MILK); + LiquidHelper.injectLiquidContainer(Defaults.LIQUID_MILK, Defaults.BUCKET_VOLUME, new ItemStack(Items.milk_bucket), new ItemStack(Items.bucket)); + + // Lava + LiquidHelper.injectTinContainer(Defaults.LIQUID_LAVA, Defaults.BUCKET_VOLUME, ForestryItem.canLava.getItemStack(), + ForestryItem.canEmpty.getItemStack()); + LiquidHelper.injectRefractoryContainer(Defaults.LIQUID_LAVA, Defaults.BUCKET_VOLUME, ForestryItem.refractoryLava.getItemStack(), ForestryItem.refractoryEmpty.getItemStack()); + + // Water + LiquidHelper.injectLiquidContainer(Defaults.LIQUID_WATER, Defaults.BUCKET_VOLUME, new ItemStack(Items.potionitem, 1, 0), + new ItemStack(Items.glass_bottle)); + LiquidHelper.injectTinContainer(Defaults.LIQUID_WATER, Defaults.BUCKET_VOLUME, ForestryItem.canWater.getItemStack(), + ForestryItem.canEmpty.getItemStack()); + LiquidHelper.injectWaxContainer(Defaults.LIQUID_WATER, Defaults.BUCKET_VOLUME, ForestryItem.waxCapsuleWater.getItemStack(), ForestryItem.waxCapsule.getItemStack()); + LiquidHelper.injectRefractoryContainer(Defaults.LIQUID_WATER, Defaults.BUCKET_VOLUME, ForestryItem.refractoryWater.getItemStack(), ForestryItem.refractoryEmpty.getItemStack()); + + LiquidHelper.getOrCreateLiquid(Defaults.LIQUID_BIOMASS); + LiquidHelper.injectLiquidContainer(Defaults.LIQUID_BIOMASS, Defaults.BUCKET_VOLUME, ForestryItem.bucketBiomass.getItemStack(), new ItemStack(Items.bucket)); + LiquidHelper.injectTinContainer(Defaults.LIQUID_BIOMASS, Defaults.BUCKET_VOLUME, ForestryItem.canBiomass.getItemStack(), ForestryItem.canEmpty.getItemStack()); + LiquidHelper.injectWaxContainer(Defaults.LIQUID_BIOMASS, Defaults.BUCKET_VOLUME, ForestryItem.waxCapsuleBiomass.getItemStack(), ForestryItem.waxCapsule.getItemStack()); + LiquidHelper.injectRefractoryContainer(Defaults.LIQUID_BIOMASS, Defaults.BUCKET_VOLUME, ForestryItem.refractoryBiomass.getItemStack(), ForestryItem.refractoryEmpty.getItemStack()); + + LiquidHelper.getOrCreateLiquid(Defaults.LIQUID_ETHANOL); + LiquidHelper.injectLiquidContainer(Defaults.LIQUID_ETHANOL, Defaults.BUCKET_VOLUME, ForestryItem.bucketBiofuel.getItemStack(), new ItemStack(Items.bucket)); + LiquidHelper.injectTinContainer(Defaults.LIQUID_ETHANOL, Defaults.BUCKET_VOLUME, ForestryItem.canBiofuel.getItemStack(), ForestryItem.canEmpty.getItemStack()); + LiquidHelper.injectWaxContainer(Defaults.LIQUID_ETHANOL, Defaults.BUCKET_VOLUME, ForestryItem.waxCapsuleBiofuel.getItemStack(), ForestryItem.waxCapsule.getItemStack()); + LiquidHelper.injectRefractoryContainer(Defaults.LIQUID_ETHANOL, Defaults.BUCKET_VOLUME, ForestryItem.refractoryBiofuel.getItemStack(), ForestryItem.refractoryEmpty.getItemStack()); + + LiquidHelper.getOrCreateLiquid(Defaults.LIQUID_SEEDOIL); + LiquidHelper.injectTinContainer(Defaults.LIQUID_SEEDOIL, Defaults.BUCKET_VOLUME, ForestryItem.canSeedOil.getItemStack(), ForestryItem.canEmpty.getItemStack()); + LiquidHelper.injectWaxContainer(Defaults.LIQUID_SEEDOIL, Defaults.BUCKET_VOLUME, ForestryItem.waxCapsuleSeedOil.getItemStack(), ForestryItem.waxCapsule.getItemStack()); + LiquidHelper.injectRefractoryContainer(Defaults.LIQUID_SEEDOIL, Defaults.BUCKET_VOLUME, ForestryItem.refractorySeedOil.getItemStack(), ForestryItem.refractoryEmpty.getItemStack()); + + LiquidHelper.getOrCreateLiquid(Defaults.LIQUID_HONEY); + LiquidHelper.injectTinContainer(Defaults.LIQUID_HONEY, Defaults.BUCKET_VOLUME, ForestryItem.canHoney.getItemStack(), ForestryItem.canEmpty.getItemStack()); + LiquidHelper.injectWaxContainer(Defaults.LIQUID_HONEY, Defaults.BUCKET_VOLUME, ForestryItem.waxCapsuleHoney.getItemStack(), ForestryItem.waxCapsule.getItemStack()); + LiquidHelper.injectRefractoryContainer(Defaults.LIQUID_HONEY, Defaults.BUCKET_VOLUME, ForestryItem.refractoryHoney.getItemStack(), ForestryItem.refractoryEmpty.getItemStack()); + + LiquidHelper.getOrCreateLiquid(Defaults.LIQUID_JUICE); + LiquidHelper.injectTinContainer(Defaults.LIQUID_JUICE, Defaults.BUCKET_VOLUME, ForestryItem.canJuice.getItemStack(), ForestryItem.canEmpty.getItemStack()); + LiquidHelper.injectWaxContainer(Defaults.LIQUID_JUICE, Defaults.BUCKET_VOLUME, ForestryItem.waxCapsuleJuice.getItemStack(), ForestryItem.waxCapsule.getItemStack()); + LiquidHelper.injectRefractoryContainer(Defaults.LIQUID_JUICE, Defaults.BUCKET_VOLUME, ForestryItem.refractoryJuice.getItemStack(), ForestryItem.refractoryEmpty.getItemStack()); + + LiquidHelper.getOrCreateLiquid(Defaults.LIQUID_ICE); + LiquidHelper.injectTinContainer(Defaults.LIQUID_ICE, Defaults.BUCKET_VOLUME, ForestryItem.canIce.getItemStack(), ForestryItem.canEmpty.getItemStack()); + LiquidHelper.injectWaxContainer(Defaults.LIQUID_ICE, Defaults.BUCKET_VOLUME, ForestryItem.waxCapsuleIce.getItemStack(), ForestryItem.waxCapsule.getItemStack()); + LiquidHelper.injectRefractoryContainer(Defaults.LIQUID_ICE, Defaults.BUCKET_VOLUME, ForestryItem.refractoryIce.getItemStack(), ForestryItem.refractoryEmpty.getItemStack()); + + } +} diff --git a/forestry_common/core/forestry/core/GameMode.java b/forestry_common/core/forestry/core/GameMode.java new file mode 100755 index 000000000..a544fa502 --- /dev/null +++ b/forestry_common/core/forestry/core/GameMode.java @@ -0,0 +1,204 @@ +/******************************************************************************* + * Copyright 2011-2014 by SirSengir + * + * This work is licensed under a Creative Commons Attribution-NonCommercial-NoDerivs 3.0 Unported License. + * + * To view a copy of this license, visit http://creativecommons.org/licenses/by-nc-nd/3.0/. + ******************************************************************************/ +package forestry.core; + +import java.util.HashMap; + +import net.minecraft.init.Items; +import net.minecraft.item.ItemStack; + +import forestry.api.core.ForestryAPI; +import forestry.api.core.IGameMode; +import forestry.core.config.Config; +import forestry.core.config.Configuration; +import forestry.core.config.ForestryBlock; +import forestry.core.config.ForestryItem; +import forestry.core.config.Property; +import forestry.core.proxy.Proxies; + +public class GameMode implements IGameMode { + + public static IGameMode getGameMode() { + + if (ForestryAPI.activeMode == null) + ForestryAPI.activeMode = new GameMode(Config.gameMode); + + return ForestryAPI.activeMode; + } + + private String identifier = "EASY"; + private final String category; + + private final HashMap booleanSettings = new HashMap(); + private final HashMap integerSettings = new HashMap(); + private final HashMap floatSettings = new HashMap(); + private final HashMap stackSettings = new HashMap(); + + private static final float ENERGY_DEMAND_MODIFIER = 1.0f; + private static final float FUEL_MODIFIER = 1.0f; + + private static final int FARM_FERTILIZER_VALUE = 2000; + + private final ItemStack recipeFertilizerOutputApatite = ForestryItem.fertilizerCompound.getItemStack(8); + private final ItemStack recipeFertilizerOutputAsh = ForestryItem.fertilizerCompound.getItemStack(16); + private final ItemStack recipeCompostOutputWheat = ForestryItem.fertilizerBio.getItemStack(4); + private final ItemStack recipeCompostOutputAsh = ForestryItem.fertilizerBio.getItemStack(1); + + private final ItemStack recipeHumusOutputFertilizer = new ItemStack(ForestryBlock.soil, 8, 0); + private final ItemStack recipeHumusOutputCompost = new ItemStack(ForestryBlock.soil, 8, 0); + + private final ItemStack recipeBogEarthOutputBucket = new ItemStack(ForestryBlock.soil, 6, 1); + private final ItemStack recipeBogEarthOutputCans = new ItemStack(ForestryBlock.soil, 8, 1); + + private final ItemStack recipeCanOutput = ForestryItem.canEmpty.getItemStack(12); + private final ItemStack recipeCapsuleOutput = ForestryItem.waxCapsule.getItemStack(4); + private final ItemStack recipeRefractoryOutput = ForestryItem.refractoryEmpty.getItemStack(4); + + private static final int FERMENTATION_DURATION_FERTILIZER = 200; + private static final int FERMENTATION_DURATION_COMPOST = 250; + + private static final int FERMENTED_CYCLE_FERTILIZER = 56; + private static final int FERMENTED_CYCLE_COMPOST = 48; + + private static final int FERMENTED_SAPLING = 250; + private static final int FERMENTED_CACTI = 50; + private static final int FERMENTED_WHEAT = 50; + private static final int FERMENTED_CANE = 50; + private static final int FERMENTED_MUSHROOM = 50; + + private static final int SQUEEZED_LIQUID_SEED = 10; + private static final int SQUEEZED_LIQUID_APPLE = 200; + private static final int SQUEEZED_MULCH_APPLE = 20; + + public GameMode(String identifier) { + + this.identifier = identifier; + this.category = "gamemodes/" + identifier; + + Configuration config = Config.config; + + initSetting("energy.demand.modifier", ENERGY_DEMAND_MODIFIER, -1, "modifies the energy required to activate machines, as well as the max amount of energy stored and accepted."); + initSetting("farms.fertilizer.value", FARM_FERTILIZER_VALUE, -1, "modifies the time a piece of fertilizer lasts in a farm."); + + initSetting("fuel.ethanol.generator", FUEL_MODIFIER, -1, "modifies the energy provided by ethanol in a Bio Generator."); + initSetting("fuel.ethanol.combustion", FUEL_MODIFIER, -1, "modifies the energy provided by ethanol in Buildcraft Combustion Engines."); + initSetting("fuel.biomass.generator", FUEL_MODIFIER, -1, "modifies the energy provided by Biomass in a Bio Generator."); + initSetting("fuel.biomass.biogas", FUEL_MODIFIER, -1, "modifies the energy provided by Biomass in Biogas Engines."); + + initSetting("recipe.output.fertilizer.apatite", recipeFertilizerOutputApatite, "amount of fertilizer yielded by the recipe using apatite."); + initSetting("recipe.output.fertilizer.ash", recipeFertilizerOutputAsh, "amount of fertilizer yielded by the recipe using ash."); + initSetting("recipe.output.compost.wheat", recipeCompostOutputWheat, "amount of compost yielded by the recipe using wheat."); + initSetting("recipe.output.compost.ash", recipeCompostOutputAsh, "amount of compost yielded by the recipe using ash."); + initSetting("recipe.output.humus.fertilizer", recipeHumusOutputFertilizer, "amount of humus yielded by the recipe using fertilizer."); + initSetting("recipe.output.humus.compost", recipeHumusOutputCompost, "amount of humus yielded by the recipe using compost."); + initSetting("recipe.output.bogearth.bucket", recipeBogEarthOutputBucket, "amount of bog earth yielded by the recipe using buckets."); + initSetting("recipe.output.bogearth.can", recipeBogEarthOutputCans, "amount of bog earth yielded by the recipes using cans, cells or capsules."); + + initSetting("recipe.output.can", recipeCanOutput, "amount yielded by the recipe for tin cans."); + initSetting("recipe.output.capsule", recipeCapsuleOutput, "amount yielded by the recipe for wax capsules."); + initSetting("recipe.output.refractory", recipeRefractoryOutput, "amount yielded by the recipe for refractory capsules."); + + initSetting("fermenter.cycles.fertilizer", FERMENTATION_DURATION_FERTILIZER, -1, "modifies the amount of cycles fertilizer can keep a fermenter going."); + initSetting("fermenter.cycles.compost", FERMENTATION_DURATION_COMPOST, -1, "modifies the amount of cycles compost can keep a fermenter going."); + + initSetting("fermenter.value.fertilizer", FERMENTED_CYCLE_FERTILIZER, -1, "modifies the amount of biomass per cycle a fermenter will produce using fertilizer."); + initSetting("fermenter.value.compost", FERMENTED_CYCLE_COMPOST, -1, "modifies the amount of biomass per cycle a fermenter will produce using compost."); + + initSetting("fermenter.yield.sapling", FERMENTED_SAPLING, FERMENTED_SAPLING * 8, "modifies the base amount of biomass a sapling will yield in a fermenter, affected by sappiness trait."); + initSetting("fermenter.yield.cactus", FERMENTED_CACTI, FERMENTED_CACTI * 8, "modifies the amount of biomass a piece of cactus will yield in a fermenter."); + initSetting("fermenter.yield.wheat", FERMENTED_WHEAT, FERMENTED_WHEAT * 8, "modifies the amount of biomass a piece of wheat will yield in a fermenter."); + initSetting("fermenter.yield.cane", FERMENTED_CANE, FERMENTED_CANE * 8, "modifies the amount of biomass a piece of sugar cane will yield in a fermenter."); + initSetting("fermenter.yield.mushroom", FERMENTED_MUSHROOM, FERMENTED_MUSHROOM * 8, "modifies the amount of biomass a mushroom will yield in a fermenter."); + + initSetting("squeezer.liquid.seed", SQUEEZED_LIQUID_SEED, SQUEEZED_LIQUID_SEED * 8, "modifies the amount of seed oil squeezed from a single seed. other sources are based off this."); + initSetting("squeezer.liquid.apple", SQUEEZED_LIQUID_APPLE, SQUEEZED_LIQUID_APPLE * 8, "modifies the amount of juice squeezed from a single apple. other sources are based off this."); + initSetting("squeezer.mulch.apple", SQUEEZED_MULCH_APPLE, SQUEEZED_MULCH_APPLE * 8, "modifies the chance of mulch per squeezed apple."); + initSetting("energy.engine.clockwork", true, "set to false to disable the clockwork engine."); + + config.save(); + + } + + private void initSetting(String ident, ItemStack def, String comment) { + Property property = Config.config.get(ident, category, def.stackSize); + property.Comment = comment; + ItemStack changed = def.copy(); + changed.stackSize = Integer.parseInt(property.Value); + stackSettings.put(ident, changed); + } + + private void initSetting(String ident, int def, int max, String comment) { + Property property = Config.config.get(ident, category, def); + if(max < 0) { + property.Comment = comment; + integerSettings.put(ident, Integer.parseInt(property.Value)); + } else { + property.Comment = comment + " (max: " + max + ")"; + integerSettings.put(ident, Math.min(Integer.parseInt(property.Value), max)); + } + Config.config.set(ident, category, integerSettings.get(ident)); + + } + + private void initSetting(String ident, float def, float max, String comment) { + Property property = Config.config.get(ident, category, def); + if(max < 0) { + property.Comment = comment; + floatSettings.put(ident, Float.parseFloat(property.Value)); + } else { + property.Comment = comment + " (max: " + max + ")"; + floatSettings.put(ident, Math.min(Float.parseFloat(property.Value), max)); + } + Config.config.set(ident, category, floatSettings.get(ident)); + } + + private void initSetting(String ident, boolean def, String comment) { + Property property = Config.config.get(ident, category, def); + property.Comment = comment; + booleanSettings.put(ident, Boolean.parseBoolean(property.Value)); + Config.config.set(ident, category, booleanSettings.get(ident)); + } + + @Override + public int getIntegerSetting(String ident) { + if(integerSettings.containsKey(ident)) + return integerSettings.get(ident); + Proxies.log.warning("No such setting: " + ident); + return -1; + } + + @Override + public float getFloatSetting(String ident) { + if(floatSettings.containsKey(ident)) + return floatSettings.get(ident); + Proxies.log.warning("No such setting: " + ident); + return 1; + } + + @Override + public boolean getBooleanSetting(String ident) { + if(booleanSettings.containsKey(ident)) + return booleanSettings.get(ident); + Proxies.log.warning("No such setting: " + ident); + return false; + } + + @Override + public ItemStack getStackSetting(String ident) { + if(stackSettings.containsKey(ident)) + return stackSettings.get(ident); + Proxies.log.warning("No such setting: " + ident); + return new ItemStack(Items.apple, 1); + } + + @Override + public String getIdentifier() { + return identifier; + } + +} diff --git a/forestry_common/core/forestry/core/GuiHandler.java b/forestry_common/core/forestry/core/GuiHandler.java new file mode 100755 index 000000000..fe3540abb --- /dev/null +++ b/forestry_common/core/forestry/core/GuiHandler.java @@ -0,0 +1,87 @@ +/******************************************************************************* + * Copyright 2011-2014 by SirSengir + * + * This work is licensed under a Creative Commons Attribution-NonCommercial-NoDerivs 3.0 Unported License. + * + * To view a copy of this license, visit http://creativecommons.org/licenses/by-nc-nd/3.0/. + ******************************************************************************/ +package forestry.core; + +import net.minecraft.entity.player.EntityPlayer; +import net.minecraft.world.World; + +import cpw.mods.fml.common.network.IGuiHandler; + +import forestry.core.circuits.ContainerSolderingIron; +import forestry.core.circuits.GuiSolderingIron; +import forestry.core.circuits.ItemSolderingIron.SolderingInventory; +import forestry.core.gadgets.TileAnalyzer; +import forestry.core.gadgets.TileEscritoire; +import forestry.core.gui.ContainerAnalyzer; +import forestry.core.gui.ContainerEscritoire; +import forestry.core.gui.GuiAnalyzer; +import forestry.core.gui.GuiEscritoire; +import forestry.core.network.GuiId; +import forestry.plugins.PluginManager; + +public class GuiHandler extends GuiHandlerBase { + + @Override + public Object getClientGuiElement(int id, EntityPlayer player, World world, int x, int y, int z) { + int cleanId = decodeGuiID(id); + + if (cleanId < GuiId.values().length) + switch (GuiId.values()[cleanId]) { + + case AnalyzerGUI: + return new GuiAnalyzer(player.inventory, (TileAnalyzer) getTileForestry(world, x, y, z)); + + case NaturalistBenchGUI: + return new GuiEscritoire(player, (TileEscritoire) getTileForestry(world, x, y, z)); + + case SolderingIronGUI: + return new GuiSolderingIron(player.inventory, new SolderingInventory()); + + default: + for (IGuiHandler handler : PluginManager.guiHandlers) { + Object element = handler.getClientGuiElement(id, player, world, x, y, z); + if (element != null) + return element; + } + + return null; + } + + return null; + } + + @Override + public Object getServerGuiElement(int id, EntityPlayer player, World world, int x, int y, int z) { + int cleanId = decodeGuiID(id); + + if (cleanId < GuiId.values().length) + switch (GuiId.values()[cleanId]) { + + case AnalyzerGUI: + return new ContainerAnalyzer(player.inventory, (TileAnalyzer) getTileForestry(world, x, y, z)); + + case NaturalistBenchGUI: + return new ContainerEscritoire(player, (TileEscritoire) getTileForestry(world, x, y, z)); + + case SolderingIronGUI: + return new ContainerSolderingIron(player.inventory, new SolderingInventory()); + + default: + for (IGuiHandler handler : PluginManager.guiHandlers) { + Object element = handler.getServerGuiElement(id, player, world, x, y, z); + if (element != null) + return element; + } + + return null; + + } + + return null; + } +} diff --git a/forestry_common/core/forestry/core/GuiHandlerBase.java b/forestry_common/core/forestry/core/GuiHandlerBase.java new file mode 100755 index 000000000..3cd76a3cd --- /dev/null +++ b/forestry_common/core/forestry/core/GuiHandlerBase.java @@ -0,0 +1,64 @@ +/******************************************************************************* + * Copyright 2011-2014 by SirSengir + * + * This work is licensed under a Creative Commons Attribution-NonCommercial-NoDerivs 3.0 Unported License. + * + * To view a copy of this license, visit http://creativecommons.org/licenses/by-nc-nd/3.0/. + ******************************************************************************/ +package forestry.core; + +import net.minecraft.entity.player.EntityPlayer; +import net.minecraft.item.ItemStack; +import net.minecraft.world.World; + +import cpw.mods.fml.common.network.IGuiHandler; + +import forestry.api.genetics.AlleleManager; +import forestry.api.genetics.ISpeciesRoot; +import forestry.core.gadgets.TileForestry; +import forestry.core.gadgets.TileNaturalistChest; +import forestry.core.gui.ContainerNaturalistInventory; +import forestry.core.gui.GuiNaturalistInventory; +import forestry.core.proxy.Proxies; + +public abstract class GuiHandlerBase implements IGuiHandler { + + public TileForestry getTileForestry(World world, int x, int y, int z) { + try { + return (TileForestry) world.getTileEntity(x, y, z); + } catch (Exception ex) { + Proxies.log.warning("Failed to cast a tile entity to a TileForestry at " + x + "/" + y + "/" + z); + } + + return null; + } + + public GuiNaturalistInventory getNaturalistChestGui(String rootUID, EntityPlayer player, World world, int x, int y, int z, int page) { + TileNaturalistChest tile = (TileNaturalistChest) getTileForestry(world, x, y, z); + ISpeciesRoot speciesRoot = AlleleManager.alleleRegistry.getSpeciesRoot(rootUID); + return new GuiNaturalistInventory(speciesRoot, player, new ContainerNaturalistInventory(speciesRoot, player.inventory, tile, page, 25), tile, page, 5); + } + + public ContainerNaturalistInventory getNaturalistChestContainer(String rootUID, EntityPlayer player, World world, int x, int y, int z, int page) { + ISpeciesRoot speciesRoot = AlleleManager.alleleRegistry.getSpeciesRoot(rootUID); + speciesRoot.getBreedingTracker(world, player.getGameProfile().getId()).synchToPlayer(player); + return new ContainerNaturalistInventory(speciesRoot, + player.inventory, (TileNaturalistChest) getTileForestry(world, x, y, z), page, 25); + } + + public ItemStack getEquippedItem(EntityPlayer player) { + return player.getCurrentEquippedItem(); + } + + public static int encodeGuiData(int guiId, int data) { + return data << 8 | guiId; + } + + public static int decodeGuiID(int guiId) { + return guiId & 0xFF; + } + + public static int decodeGuiData(int guiId) { + return guiId >> 8; + } +} diff --git a/forestry_common/core/forestry/core/PickupHandlerCore.java b/forestry_common/core/forestry/core/PickupHandlerCore.java new file mode 100755 index 000000000..afa29f302 --- /dev/null +++ b/forestry_common/core/forestry/core/PickupHandlerCore.java @@ -0,0 +1,33 @@ +/******************************************************************************* + * Copyright 2011-2014 by SirSengir + * + * This work is licensed under a Creative Commons Attribution-NonCommercial-NoDerivs 3.0 Unported License. + * + * To view a copy of this license, visit http://creativecommons.org/licenses/by-nc-nd/3.0/. + ******************************************************************************/ +package forestry.core; + +import net.minecraft.entity.item.EntityItem; +import net.minecraft.entity.player.EntityPlayer; +import net.minecraft.item.ItemStack; + +import forestry.api.genetics.AlleleManager; +import forestry.api.genetics.ISpeciesRoot; +import forestry.core.interfaces.IPickupHandler; + +public class PickupHandlerCore implements IPickupHandler { + + @Override + public boolean onItemPickup(EntityPlayer entityPlayer, EntityItem entityitem) { + ItemStack itemstack = entityitem.getEntityItem(); + if (itemstack == null || itemstack.stackSize <= 0) + return false; + + ISpeciesRoot root = AlleleManager.alleleRegistry.getSpeciesRoot(itemstack); + if(root != null) + root.getBreedingTracker(entityitem.worldObj, entityPlayer.getGameProfile().getId()).registerPickup(root.getMember(itemstack)); + + return true; + } + +} diff --git a/forestry_common/core/forestry/core/SaveEventHandlerCore.java b/forestry_common/core/forestry/core/SaveEventHandlerCore.java new file mode 100755 index 000000000..efcedde16 --- /dev/null +++ b/forestry_common/core/forestry/core/SaveEventHandlerCore.java @@ -0,0 +1,28 @@ +/******************************************************************************* + * Copyright 2011-2014 by SirSengir + * + * This work is licensed under a Creative Commons Attribution-NonCommercial-NoDerivs 3.0 Unported License. + * + * To view a copy of this license, visit http://creativecommons.org/licenses/by-nc-nd/3.0/. + ******************************************************************************/ +package forestry.core; + +import net.minecraft.world.World; + +import forestry.core.interfaces.ISaveEventHandler; + +public class SaveEventHandlerCore implements ISaveEventHandler { + + @Override + public void onWorldLoad(World world) { + } + + @Override + public void onWorldSave(World world) { + } + + @Override + public void onWorldUnload(World world) { + } + +} diff --git a/forestry_common/core/forestry/core/TemperatureState.java b/forestry_common/core/forestry/core/TemperatureState.java new file mode 100755 index 000000000..29f5531ae --- /dev/null +++ b/forestry_common/core/forestry/core/TemperatureState.java @@ -0,0 +1,26 @@ +/******************************************************************************* + * Copyright 2011-2014 by SirSengir + * + * This work is licensed under a Creative Commons Attribution-NonCommercial-NoDerivs 3.0 Unported License. + * + * To view a copy of this license, visit http://creativecommons.org/licenses/by-nc-nd/3.0/. + ******************************************************************************/ +package forestry.core; + +public enum TemperatureState { + + UNKNOWN, + + COOL, + + WARMED_UP, + + OPERATING_TEMPERATURE, + + RUNNING_HOT, + + OVERHEATING, + + MELTING + +} diff --git a/forestry_common/core/forestry/core/TickHandlerCoreClient.java b/forestry_common/core/forestry/core/TickHandlerCoreClient.java new file mode 100755 index 000000000..7df49e2b4 --- /dev/null +++ b/forestry_common/core/forestry/core/TickHandlerCoreClient.java @@ -0,0 +1,76 @@ +/******************************************************************************* + * Copyright 2011-2014 by SirSengir + * + * This work is licensed under a Creative Commons Attribution-NonCommercial-NoDerivs 3.0 Unported License. + * + * To view a copy of this license, visit http://creativecommons.org/licenses/by-nc-nd/3.0/. + ******************************************************************************/ +package forestry.core; + +import java.util.concurrent.ConcurrentLinkedQueue; + +import net.minecraft.entity.player.EntityPlayer; +import net.minecraft.util.ChatComponentText; + +import cpw.mods.fml.common.FMLCommonHandler; +import cpw.mods.fml.common.eventhandler.SubscribeEvent; +import cpw.mods.fml.common.gameevent.TickEvent.Phase; +import cpw.mods.fml.common.gameevent.TickEvent.PlayerTickEvent; + +import forestry.core.config.Config; +import forestry.core.config.Version; +import forestry.core.proxy.Proxies; +import forestry.core.utils.Utils; + +public class TickHandlerCoreClient { + public TickHandlerCoreClient() { + FMLCommonHandler.instance().bus().register(this); + } + + private static ConcurrentLinkedQueue messages = new ConcurrentLinkedQueue(); + + public void queueChatMessage(String message) { + messages.add(message); + } + private boolean naggedVersion, naggedVerify; + private boolean hasNaturalistView; + + @SubscribeEvent + public void onPlayerTick(PlayerTickEvent event) { + if (event.phase != Phase.END) return; + + EntityPlayer player = Proxies.common.getClientInstance().thePlayer; + boolean hasNaturalistEye = Utils.hasNaturalistEye(player); + if (hasNaturalistEye != hasNaturalistView) { + hasNaturalistView = !hasNaturalistView; + Proxies.common.getClientInstance().renderGlobal.markBlockRangeForRenderUpdate( + (int) player.posX - 32, (int) player.posY - 32, (int) player.posZ - 32, + (int) player.posX + 32, (int) player.posY + 32, (int) player.posZ + 32); + } + + if (messages.size() > 0) { + String message; + while ((message = messages.poll()) != null) { + player.addChatMessage(new ChatComponentText(message)); + } + } + + /* + if (!Config.disableNags) + if (Proxies.common.isModLoaded("GregTech_Addon")) + queueChatMessage("\u00A76Forestry may have been modified by GregTech. It may behave unexpectedly and some config options may not work. Do not report issues with this install! You can disable this nag in the config."); + */ + + if (!naggedVersion && !Config.disableVersionCheck && Version.needsUpdateNoticeAndMarkAsSeen()) { + queueChatMessage(String.format("\u00A7cNew version of Forestry available: %s for Minecraft %s", Version.getRecommendedVersion(), + Proxies.common.getMinecraftVersion())); + queueChatMessage("\u00A7cThis message only displays once. Type '/forestry version' to see the changelog."); + naggedVersion = true; + } + + if (!naggedVerify && Config.invalidFingerprint) { + queueChatMessage("\u00A76Forestry's jar file was tampered with. Some machines have shut down and beekeeping has grown dangerous. Get a new jar from the official download page to fix that!"); + naggedVerify = true; + } + } +} diff --git a/forestry_common/core/forestry/core/TickHandlerCoreServer.java b/forestry_common/core/forestry/core/TickHandlerCoreServer.java new file mode 100755 index 000000000..aa1913b8c --- /dev/null +++ b/forestry_common/core/forestry/core/TickHandlerCoreServer.java @@ -0,0 +1,36 @@ +/******************************************************************************* + * Copyright 2011-2014 by SirSengir + * + * This work is licensed under a Creative Commons Attribution-NonCommercial-NoDerivs 3.0 Unported License. + * + * To view a copy of this license, visit http://creativecommons.org/licenses/by-nc-nd/3.0/. + ******************************************************************************/ +package forestry.core; + +import net.minecraft.entity.player.EntityPlayer; + +import cpw.mods.fml.common.FMLCommonHandler; +import cpw.mods.fml.common.eventhandler.SubscribeEvent; +import cpw.mods.fml.common.gameevent.TickEvent.Phase; +import cpw.mods.fml.common.gameevent.TickEvent.WorldTickEvent; + +import forestry.core.interfaces.IResupplyHandler; +import forestry.plugins.PluginManager; + +public class TickHandlerCoreServer { + public TickHandlerCoreServer() { + FMLCommonHandler.instance().bus().register(this); + } + + @SubscribeEvent + public void onWorldTick(WorldTickEvent event) { + if (event.phase != Phase.END) return; + + for (Object obj : event.world.playerEntities) { + EntityPlayer player = (EntityPlayer) obj; + for (IResupplyHandler handler : PluginManager.resupplyHandlers) + handler.resupply(player); + } + + } +} diff --git a/forestry_common/core/forestry/core/WorldGenerator.java b/forestry_common/core/forestry/core/WorldGenerator.java new file mode 100755 index 000000000..730d7edd9 --- /dev/null +++ b/forestry_common/core/forestry/core/WorldGenerator.java @@ -0,0 +1,78 @@ +/******************************************************************************* + * Copyright 2011-2014 by SirSengir + * + * This work is licensed under a Creative Commons Attribution-NonCommercial-NoDerivs 3.0 Unported License. + * + * To view a copy of this license, visit http://creativecommons.org/licenses/by-nc-nd/3.0/. + ******************************************************************************/ +package forestry.core; + +import java.util.Random; + +import net.minecraft.world.World; +import net.minecraft.world.chunk.IChunkProvider; + +import cpw.mods.fml.common.IWorldGenerator; + +import forestry.api.core.IPlugin; +import forestry.core.config.Config; +import forestry.core.config.ForestryBlock; +import forestry.core.proxy.Proxies; +import forestry.core.worldgen.WorldGenMinableMeta; +import forestry.plugins.NativePlugin; +import forestry.plugins.PluginManager; + +public class WorldGenerator implements IWorldGenerator { + + private WorldGenMinableMeta apatiteGenerator; + private WorldGenMinableMeta copperGenerator; + private WorldGenMinableMeta tinGenerator; + + @Override + public void generate(Random random, int chunkX, int chunkZ, World world, IChunkProvider chunkGenerator, IChunkProvider chunkProvider) { + + if (apatiteGenerator == null) { + apatiteGenerator = new WorldGenMinableMeta(ForestryBlock.resources, 0, 36); + copperGenerator = new WorldGenMinableMeta(ForestryBlock.resources, 1, 6); + tinGenerator = new WorldGenMinableMeta(ForestryBlock.resources, 2, 6); + } + + // shift to world coordinates + chunkX = chunkX << 4; + chunkZ = chunkZ << 4; + + // / APATITE + if (Config.generateApatiteOre) + if (random.nextFloat() < 0.8f) { + int randPosX = chunkX + random.nextInt(16); + int randPosY = random.nextInt(world.getActualHeight() - 72) + 56; // Does not generate below y = 64 + int randPosZ = chunkZ + random.nextInt(16); + if (apatiteGenerator.generate(world, random, randPosX, randPosY, randPosZ)) + Proxies.log.finest("Generated apatite vein around %s/%s/%s", randPosX, randPosY, randPosZ); + } + + // / COPPER + if (Config.generateCopperOre) + for (int i = 0; i < 20; i++) { + int randPosX = chunkX + random.nextInt(16); + int randPosY = random.nextInt(76) + 32; + int randPosZ = chunkZ + random.nextInt(16); + copperGenerator.generate(world, random, randPosX, randPosY, randPosZ); + } + + // / TIN + if (Config.generateTinOre) + for (int i = 0; i < 18; i++) { + int randPosX = chunkX + random.nextInt(16); + int randPosY = random.nextInt(76) + 16; + int randPosZ = chunkZ + random.nextInt(16); + tinGenerator.generate(world, random, randPosX, randPosY, randPosZ); + } + + // / PLUGIN WORLD GENERATION + for (IPlugin plugin : PluginManager.plugins) + if (plugin.isAvailable() && plugin instanceof NativePlugin) + ((NativePlugin) plugin).generateSurface(world, random, chunkX, chunkZ); + } + +} diff --git a/forestry_common/core/forestry/core/circuits/Circuit.java b/forestry_common/core/forestry/core/circuits/Circuit.java new file mode 100755 index 000000000..078257ea2 --- /dev/null +++ b/forestry_common/core/forestry/core/circuits/Circuit.java @@ -0,0 +1,92 @@ +/******************************************************************************* + * Copyright 2011-2014 by SirSengir + * + * This work is licensed under a Creative Commons Attribution-NonCommercial-NoDerivs 3.0 Unported License. + * + * To view a copy of this license, visit http://creativecommons.org/licenses/by-nc-nd/3.0/. + ******************************************************************************/ +package forestry.core.circuits; + +import java.util.List; + +import forestry.api.circuits.ChipsetManager; +import forestry.api.circuits.ICircuit; +import forestry.core.utils.StringUtil; + +public abstract class Circuit implements ICircuit { + + String uid; + int limit = 1; + boolean requiresDiscovery; + String name; + String[] descriptions; + + public Circuit(String uid, boolean requiresDiscovery, String name, String[] descriptions) { + this.uid = uid; + this.requiresDiscovery = requiresDiscovery; + this.name = name; + this.descriptions = descriptions; + + ChipsetManager.circuitRegistry.registerCircuit(this); + } + + protected void setLimit(int limit) { + this.limit = limit; + } + + @Override + public String getUID() { + return "forestry." + this.uid; + } + + @Override + public int getLimit() { + return this.limit; + } + + @Override + public boolean requiresDiscovery() { + return this.requiresDiscovery; + } + + @Override + public String getName() { + return "circuit." + this.name; + } + + @SuppressWarnings({ "rawtypes", "unchecked" }) + @Override + public void addTooltip(List list) { + for (String description : descriptions) + list.add(" - " + StringUtil.localize(description)); + } + + public static ICircuit energyElectricChoke1; + public static ICircuit energyFireDampener1; + public static ICircuit energyElectricEfficiency1; + public static ICircuit energyElectricBoost1; + public static ICircuit energyElectricBoost2; + + public static ICircuit farmArborealManaged; + public static ICircuit farmShroomManaged; + public static ICircuit farmCerealManaged; + public static ICircuit farmVegetableManaged; + public static ICircuit farmPeatManaged; + public static ICircuit farmSucculentManaged; + public static ICircuit farmPoaleManaged; + public static ICircuit farmFungal; + public static ICircuit farmInfernalManaged; + public static ICircuit farmGourdManaged; + + public static ICircuit farmShroomManual; + public static ICircuit farmCerealManual; + public static ICircuit farmVegetableManual; + public static ICircuit farmPeatManual; + public static ICircuit farmSucculentManual; + public static ICircuit farmPoalesManual; + public static ICircuit farmGourdManual; + public static ICircuit farmCocoaManual; + + public static ICircuit farmOrchardManual; + public static ICircuit farmRubberManual; +} diff --git a/forestry_common/core/forestry/core/circuits/CircuitBoard.java b/forestry_common/core/forestry/core/circuits/CircuitBoard.java new file mode 100755 index 000000000..4a0dfb49d --- /dev/null +++ b/forestry_common/core/forestry/core/circuits/CircuitBoard.java @@ -0,0 +1,169 @@ +/******************************************************************************* + * Copyright 2011-2014 by SirSengir + * + * This work is licensed under a Creative Commons Attribution-NonCommercial-NoDerivs 3.0 Unported License. + * + * To view a copy of this license, visit http://creativecommons.org/licenses/by-nc-nd/3.0/. + ******************************************************************************/ +package forestry.core.circuits; + +import java.util.ArrayList; +import java.util.List; + +import net.minecraft.nbt.NBTTagCompound; +import net.minecraft.nbt.NBTTagList; +import net.minecraft.tileentity.TileEntity; + +import forestry.api.circuits.ChipsetManager; +import forestry.api.circuits.ICircuit; +import forestry.api.circuits.ICircuitBoard; +import forestry.api.circuits.ICircuitLayout; + +public class CircuitBoard implements ICircuitBoard { + + EnumCircuitBoardType type; + ICircuitLayout layout; + ICircuit[] circuits; + + public CircuitBoard(EnumCircuitBoardType type, ICircuitLayout layout, ICircuit[] circuits) { + this.type = type; + this.layout = layout; + this.circuits = circuits; + } + + public CircuitBoard(NBTTagCompound nbttagcompound) { + readFromNBT(nbttagcompound); + } + + @Override + public int getPrimaryColor() { + return type.primaryColor; + } + + @Override + public int getSecondaryColor() { + return type.secondaryColor; + } + + @SuppressWarnings({ "rawtypes", "unchecked" }) + @Override + public void addTooltip(List list) { + if (layout != null) + list.add("\u00A76" + layout.getUsage() + ":"); + + for (ICircuit circuit : circuits) + if (circuit != null) + circuit.addTooltip(list); + } + + @Override + public void readFromNBT(NBTTagCompound nbttagcompound) { + + type = EnumCircuitBoardType.values()[nbttagcompound.getShort("T")]; + + // Layout + if (nbttagcompound.hasKey("LY")) + layout = ChipsetManager.circuitRegistry.getLayout(nbttagcompound.getString("LY")); + if (layout == null) + ChipsetManager.circuitRegistry.getDefaultLayout(); + + // FIXME: Legacy I + ArrayList readcircuits = new ArrayList(); + if (nbttagcompound.hasKey("CS")) { + + NBTTagList nbttaglist = nbttagcompound.getTagList("CS", 10); + for (int i = 0; i < nbttaglist.tagCount(); i++) { + NBTTagCompound nbttagcompound1 = nbttaglist.getCompoundTagAt(i); + readcircuits.add(ChipsetManager.circuitRegistry.getFromLegacyMap(nbttagcompound1.getInteger("I"))); + } + + circuits = readcircuits.toArray(new ICircuit[0]); + return; + + } + + // FIXME: Legacy II + if (nbttagcompound.hasKey("CL")) { + NBTTagList nbttaglist = nbttagcompound.getTagList("CL", 10); + for (int i = 0; i < nbttaglist.tagCount(); i++) { + NBTTagCompound nbttagcompound1 = nbttaglist.getCompoundTagAt(i); + readcircuits.add(ChipsetManager.circuitRegistry.getCircuit(nbttagcompound1.getString("I"))); + } + + circuits = readcircuits.toArray(new ICircuit[0]); + return; + } + + // New + if (circuits != null) + return; + + circuits = new ICircuit[4]; + for (int i = 0; i < 4; i++) { + if (!nbttagcompound.hasKey("CA.I" + i)) + continue; + circuits[i] = ChipsetManager.circuitRegistry.getCircuit(nbttagcompound.getString("CA.I" + i)); + } + } + + @Override + public void writeToNBT(NBTTagCompound nbttagcompound) { + + nbttagcompound.setShort("T", (short) type.ordinal()); + + // Layout + if (layout != null) + nbttagcompound.setString("LY", layout.getUID()); + + // Circuits + for (int i = 0; i < circuits.length; i++) { + ICircuit circuit = circuits[i]; + if (circuit == null) + continue; + + nbttagcompound.setString("CA.I" + i, circuit.getUID()); + } + + } + + @Override + public void onInsertion(TileEntity tile) { + for (int i = 0; i < circuits.length; i++) { + if (circuits[i] == null) + continue; + circuits[i].onInsertion(i, tile); + } + } + + @Override + public void onLoad(TileEntity tile) { + for (int i = 0; i < circuits.length; i++) { + if (circuits[i] == null) + continue; + circuits[i].onLoad(i, tile); + } + } + + @Override + public void onRemoval(TileEntity tile) { + for (int i = 0; i < circuits.length; i++) { + if (circuits[i] == null) + continue; + circuits[i].onRemoval(i, tile); + } + } + + @Override + public void onTick(TileEntity tile) { + for (int i = 0; i < circuits.length; i++) { + if (circuits[i] == null) + continue; + circuits[i].onTick(i, tile); + } + } + + @Override + public ICircuit[] getCircuits() { + return circuits; + } +} diff --git a/forestry_common/core/forestry/core/circuits/CircuitBoardManager.java b/forestry_common/core/forestry/core/circuits/CircuitBoardManager.java new file mode 100755 index 000000000..0445d5e11 --- /dev/null +++ b/forestry_common/core/forestry/core/circuits/CircuitBoardManager.java @@ -0,0 +1,11 @@ +/******************************************************************************* + * Copyright 2011-2014 by SirSengir + * + * This work is licensed under a Creative Commons Attribution-NonCommercial-NoDerivs 3.0 Unported License. + * + * To view a copy of this license, visit http://creativecommons.org/licenses/by-nc-nd/3.0/. + ******************************************************************************/ +package forestry.core.circuits; + +public class CircuitBoardManager { +} diff --git a/forestry_common/core/forestry/core/circuits/CircuitId.java b/forestry_common/core/forestry/core/circuits/CircuitId.java new file mode 100755 index 000000000..348e52bb0 --- /dev/null +++ b/forestry_common/core/forestry/core/circuits/CircuitId.java @@ -0,0 +1,16 @@ +/******************************************************************************* + * Copyright 2011-2014 by SirSengir + * + * This work is licensed under a Creative Commons Attribution-NonCommercial-NoDerivs 3.0 Unported License. + * + * To view a copy of this license, visit http://creativecommons.org/licenses/by-nc-nd/3.0/. + ******************************************************************************/ +package forestry.core.circuits; + +public class CircuitId { + public static final int ELECTRIC_CHOKE_I = 1; + public static final int FIRE_DAMPENER_I = 2; + public static final int ELECTRIC_EFFICIENCY_I = 3; + public static final int ELECTRIC_BOOST_I = 4; + public static final int ELECTRIC_BOOST_II = 5; +} diff --git a/forestry_common/core/forestry/core/circuits/CircuitLayout.java b/forestry_common/core/forestry/core/circuits/CircuitLayout.java new file mode 100755 index 000000000..0146ea1ef --- /dev/null +++ b/forestry_common/core/forestry/core/circuits/CircuitLayout.java @@ -0,0 +1,35 @@ +/******************************************************************************* + * Copyright 2011-2014 by SirSengir + * + * This work is licensed under a Creative Commons Attribution-NonCommercial-NoDerivs 3.0 Unported License. + * + * To view a copy of this license, visit http://creativecommons.org/licenses/by-nc-nd/3.0/. + ******************************************************************************/ +package forestry.core.circuits; + +import forestry.api.circuits.ICircuitLayout; +import forestry.core.utils.StringUtil; + +public class CircuitLayout implements ICircuitLayout { + + String uid; + + public CircuitLayout(String uid) { + this.uid = uid; + } + + @Override + public String getUID() { + return "forestry." + this.uid; + } + + @Override + public String getName() { + return StringUtil.localize("layout." + this.uid); + } + + @Override + public String getUsage() { + return StringUtil.localize("usage." + this.uid); + } +} diff --git a/forestry_common/core/forestry/core/circuits/CircuitLibrary.java b/forestry_common/core/forestry/core/circuits/CircuitLibrary.java new file mode 100755 index 000000000..b2844f861 --- /dev/null +++ b/forestry_common/core/forestry/core/circuits/CircuitLibrary.java @@ -0,0 +1,29 @@ +/******************************************************************************* + * Copyright 2011-2014 by SirSengir + * + * This work is licensed under a Creative Commons Attribution-NonCommercial-NoDerivs 3.0 Unported License. + * + * To view a copy of this license, visit http://creativecommons.org/licenses/by-nc-nd/3.0/. + ******************************************************************************/ +package forestry.core.circuits; + +import net.minecraft.nbt.NBTTagCompound; +import net.minecraft.world.WorldSavedData; + +import forestry.api.circuits.ICircuitLibrary; + +public class CircuitLibrary extends WorldSavedData implements ICircuitLibrary { + + public CircuitLibrary(String par1Str) { + super(par1Str); + } + + @Override + public void readFromNBT(NBTTagCompound var1) { + } + + @Override + public void writeToNBT(NBTTagCompound var1) { + } + +} diff --git a/forestry_common/core/forestry/core/circuits/CircuitRegistry.java b/forestry_common/core/forestry/core/circuits/CircuitRegistry.java new file mode 100755 index 000000000..ec6301181 --- /dev/null +++ b/forestry_common/core/forestry/core/circuits/CircuitRegistry.java @@ -0,0 +1,117 @@ +/******************************************************************************* + * Copyright 2011-2014 by SirSengir + * + * This work is licensed under a Creative Commons Attribution-NonCommercial-NoDerivs 3.0 Unported License. + * + * To view a copy of this license, visit http://creativecommons.org/licenses/by-nc-nd/3.0/. + ******************************************************************************/ +package forestry.core.circuits; + +import java.util.HashMap; +import java.util.LinkedHashMap; + +import net.minecraft.item.ItemStack; +import net.minecraft.nbt.NBTTagCompound; +import net.minecraft.world.World; + +import forestry.api.circuits.ICircuit; +import forestry.api.circuits.ICircuitBoard; +import forestry.api.circuits.ICircuitLayout; +import forestry.api.circuits.ICircuitLibrary; +import forestry.api.circuits.ICircuitRegistry; +import forestry.core.config.ForestryItem; + +public class CircuitRegistry implements ICircuitRegistry { + + private LinkedHashMap layoutMap = new LinkedHashMap(); + private LinkedHashMap circuitMap = new LinkedHashMap(); + private HashMap legacyMap = new HashMap(); + + @Override + public ICircuitLibrary getCircuitLibrary(World world, String playername) { + CircuitLibrary library = (CircuitLibrary) world.loadItemData(CircuitLibrary.class, "CircuitLibrary_" + playername); + + if (library == null) { + library = new CircuitLibrary(playername); + world.setItemData("CircuitLibrary_" + playername, library); + } + + return library; + } + + /* CIRCUIT LAYOUTS */ + @Override + public ICircuitLayout getDefaultLayout() { + if (layoutMap.containsKey("forestry.engine.tin")) + return layoutMap.get("forestry.engine.tin"); + else + return layoutMap.values().iterator().next(); + } + + @Override + public LinkedHashMap getRegisteredLayouts() { + return layoutMap; + } + + @Override + public void registerLayout(ICircuitLayout layout) { + layoutMap.put(layout.getUID(), layout); + } + + @Override + public ICircuitLayout getLayout(String uid) { + if (layoutMap.containsKey(uid)) + return layoutMap.get(uid); + else + return null; + } + + /* CIRCUITS */ + @Override + public HashMap getRegisteredCircuits() { + return circuitMap; + } + + @Override + public void registerCircuit(ICircuit circuit) { + circuitMap.put(circuit.getUID(), circuit); + } + + @Override + public ICircuit getCircuit(String uid) { + return circuitMap.get(uid); + } + + @Override + public void registerLegacyMapping(int id, String uid) { + this.legacyMap.put(id, uid); + } + + @Override + public ICircuit getFromLegacyMap(int id) { + if (!legacyMap.containsKey(id)) + return null; + + return getCircuit(legacyMap.get(id)); + } + + public void initialize() { + registerLayout(new CircuitLayout("engine.tin")); + } + + + + @Override + public boolean isChipset(ItemStack itemstack) { + return ForestryItem.circuitboards.isItemEqual(itemstack); + } + + @Override + public ICircuitBoard getCircuitboard(ItemStack itemstack) { + NBTTagCompound nbttagcompound = itemstack.getTagCompound(); + if (nbttagcompound == null) + return null; + + return new CircuitBoard(nbttagcompound); + } +} diff --git a/forestry_common/core/forestry/core/circuits/ContainerSolderingIron.java b/forestry_common/core/forestry/core/circuits/ContainerSolderingIron.java new file mode 100755 index 000000000..52bd3c688 --- /dev/null +++ b/forestry_common/core/forestry/core/circuits/ContainerSolderingIron.java @@ -0,0 +1,121 @@ +/******************************************************************************* + * Copyright 2011-2014 by SirSengir + * + * This work is licensed under a Creative Commons Attribution-NonCommercial-NoDerivs 3.0 Unported License. + * + * To view a copy of this license, visit http://creativecommons.org/licenses/by-nc-nd/3.0/. + ******************************************************************************/ +package forestry.core.circuits; + +import net.minecraft.entity.player.EntityPlayer; +import net.minecraft.entity.player.InventoryPlayer; +import net.minecraft.inventory.Slot; +import net.minecraft.item.ItemStack; +import net.minecraft.world.World; + +import forestry.api.circuits.ICircuitLayout; +import forestry.core.circuits.ItemSolderingIron.SolderingInventory; +import forestry.core.gui.ContainerItemInventory; +import forestry.core.gui.IGuiSelectable; +import forestry.core.gui.slots.SlotCustom; +import forestry.core.network.PacketIds; +import forestry.core.network.PacketPayload; +import forestry.core.network.PacketUpdate; +import forestry.core.proxy.Proxies; + +public class ContainerSolderingIron extends ContainerItemInventory implements IGuiSelectable { + + SolderingInventory inventory; + + public ContainerSolderingIron(InventoryPlayer inventoryplayer, SolderingInventory inventory) { + super(inventory, inventoryplayer.player); + this.inventory = inventory; + + // Input + this.addSlot(new SlotCustom(inventory, 0, 152, 12, new Object[] { ItemCircuitBoard.class })); + + // Output + this.addSlot(new SlotCustom(inventory, 1, 152, 92, new Object[] { ItemCircuitBoard.class })); + + // Ingredients + this.addSlot(new Slot(inventory, 2, 12, 32)); + this.addSlot(new Slot(inventory, 3, 12, 52)); + this.addSlot(new Slot(inventory, 4, 12, 72)); + this.addSlot(new Slot(inventory, 5, 12, 92)); + + // Player inventory + for (int i1 = 0; i1 < 3; i1++) + for (int l1 = 0; l1 < 9; l1++) + addSecuredSlot(inventoryplayer, l1 + i1 * 9 + 9, 8 + l1 * 18, 123 + i1 * 18); + // Player hotbar + for (int j1 = 0; j1 < 9; j1++) + addSecuredSlot(inventoryplayer, j1, 8 + j1 * 18, 181); + + } + + @Override + protected boolean isAcceptedItem(EntityPlayer player, ItemStack stack) { + return false; + } + + /* + * @Override public void onCraftGuiClosed(EntityPlayer entityplayer) { + * + * if (!Proxies.common.isSimulating(entityplayer.worldObj)) return; + * + * // Drop everything still in there. for (int i = 0; i < inventory.getSizeInventory(); i++) { ItemStack stack = inventory.getStackInSlot(i); if (stack == + * null) { continue; } + * + * Proxies.common.dropItemPlayer(entityplayer, stack); inventory.setInventorySlotContents(i, null); } + * + * } + */ + + public ICircuitLayout getLayout() { + return inventory.getLayout(); + } + + public void advanceSelection(int index, World world) { + PacketPayload payload = new PacketPayload(2, 0, 0); + payload.intPayload[0] = index; + payload.intPayload[1] = 0; + sendSelectionChange(payload); + } + + public void regressSelection(int index, World world) { + PacketPayload payload = new PacketPayload(2, 0, 0); + payload.intPayload[0] = index; + payload.intPayload[1] = 1; + sendSelectionChange(payload); + } + + private void sendSelectionChange(PacketPayload payload) { + PacketUpdate packet = new PacketUpdate(PacketIds.GUI_SELECTION_CHANGE, payload); + Proxies.net.sendToServer(packet); + } + + @Override + public void setSelection(PacketUpdate packet) { + inventory.setLayout(packet.payload.stringPayload[0]); + } + + @Override + public void handleSelectionChange(EntityPlayer player, PacketUpdate packet) { + + if (packet.payload.intPayload[1] == 0) { + if (packet.payload.intPayload[0] == 0) + inventory.advanceLayout(); + + } else if (packet.payload.intPayload[0] == 0) + inventory.regressLayout(); + + sendSelection(player); + } + + public void sendSelection(EntityPlayer player) { + PacketPayload payload = new PacketPayload(0, 0, 1); + payload.stringPayload[0] = inventory.getLayout().getUID(); + Proxies.net.sendToPlayer(new PacketUpdate(PacketIds.GUI_SELECTION, payload), player); + } + +} diff --git a/forestry_common/core/forestry/core/circuits/EnumCircuitBoardType.java b/forestry_common/core/forestry/core/circuits/EnumCircuitBoardType.java new file mode 100755 index 000000000..3f4768236 --- /dev/null +++ b/forestry_common/core/forestry/core/circuits/EnumCircuitBoardType.java @@ -0,0 +1,23 @@ +/******************************************************************************* + * Copyright 2011-2014 by SirSengir + * + * This work is licensed under a Creative Commons Attribution-NonCommercial-NoDerivs 3.0 Unported License. + * + * To view a copy of this license, visit http://creativecommons.org/licenses/by-nc-nd/3.0/. + ******************************************************************************/ +package forestry.core.circuits; + +public enum EnumCircuitBoardType { + BASIC((short) 1, 0x191919, 0x6dcff6), ENHANCED((short) 2, 0x191919, 0xcb7c32), REFINED((short) 3, 0x191919, 0xc9c9c9), INTRICATE((short) 4, 0x191919, + 0xe2cb6b); + + final short sockets; + final int primaryColor; + final int secondaryColor; + + private EnumCircuitBoardType(short sockets, int primaryColor, int secondaryColor) { + this.sockets = sockets; + this.primaryColor = primaryColor; + this.secondaryColor = secondaryColor; + } +} diff --git a/forestry_common/core/forestry/core/circuits/GuiSolderingIron.java b/forestry_common/core/forestry/core/circuits/GuiSolderingIron.java new file mode 100755 index 000000000..c574cd67f --- /dev/null +++ b/forestry_common/core/forestry/core/circuits/GuiSolderingIron.java @@ -0,0 +1,77 @@ +/******************************************************************************* + * Copyright 2011-2014 by SirSengir + * + * This work is licensed under a Creative Commons Attribution-NonCommercial-NoDerivs 3.0 Unported License. + * + * To view a copy of this license, visit http://creativecommons.org/licenses/by-nc-nd/3.0/. + ******************************************************************************/ +package forestry.core.circuits; + +import net.minecraft.client.gui.GuiButton; +import net.minecraft.entity.player.InventoryPlayer; +import net.minecraft.inventory.IInventory; + +import forestry.api.circuits.ICircuitLayout; +import forestry.core.circuits.ItemSolderingIron.CircuitRecipe; +import forestry.core.circuits.ItemSolderingIron.SolderingInventory; +import forestry.core.config.Defaults; +import forestry.core.gadgets.TileForestry; +import forestry.core.gui.GuiForestry; +import forestry.core.proxy.Proxies; +import forestry.core.utils.StringUtil; + +public class GuiSolderingIron extends GuiForestry { + + private final IInventory inventory; + + public GuiSolderingIron(InventoryPlayer inventoryplayer, SolderingInventory inventory) { + super(Defaults.TEXTURE_PATH_GUI + "/solder.png", new ContainerSolderingIron(inventoryplayer, inventory), inventory); + + this.inventory = inventory; + + xSize = 176; + ySize = 205; + } + + @Override + protected void drawGuiContainerBackgroundLayer(float var1, int mouseX, int mouseY) { + super.drawGuiContainerBackgroundLayer(var1, mouseX, mouseY); + + ICircuitLayout layout = ((ContainerSolderingIron) inventorySlots).getLayout(); + String title = layout.getName(); + fontRendererObj.drawString(title, guiLeft + 8 + getCenteredOffset(title, 138), guiTop + 16, fontColor.get("gui.screen")); + + for (int l = 2; l < inventory.getSizeInventory(); l++) { + String description; + CircuitRecipe recipe = ItemSolderingIron.SolderManager.getMatchingRecipe(layout, inventory.getStackInSlot(l)); + if (recipe == null) + description = "(" + StringUtil.localize("gui.noeffect") + ")"; + else + description = StringUtil.localize(recipe.circuit.getName()) + " (" + recipe.circuit.getLimit() + ")"; + + int row = (l - 2) * 20; + fontRendererObj.drawString(description, guiLeft + 32, guiTop + 36 + row, fontColor.get("gui.screen")); + } + } + + @SuppressWarnings("unchecked") + @Override + public void initGui() { + super.initGui(); + + buttonList.add(new GuiButton(1, guiLeft + 12, guiTop + 10, 12, 18, "<")); + buttonList.add(new GuiButton(2, guiLeft + 130, guiTop + 10, 12, 18, ">")); + + } + + @Override + protected void actionPerformed(GuiButton guibutton) { + super.actionPerformed(guibutton); + + if (guibutton.id == 1) + ((ContainerSolderingIron) inventorySlots).regressSelection(0, Proxies.common.getRenderWorld()); + else if (guibutton.id == 2) + ((ContainerSolderingIron) inventorySlots).advanceSelection(0, Proxies.common.getRenderWorld()); + } + +} diff --git a/forestry_common/core/forestry/core/circuits/ISolderingIron.java b/forestry_common/core/forestry/core/circuits/ISolderingIron.java new file mode 100755 index 000000000..9288ab59e --- /dev/null +++ b/forestry_common/core/forestry/core/circuits/ISolderingIron.java @@ -0,0 +1,12 @@ +/******************************************************************************* + * Copyright 2011-2014 by SirSengir + * + * This work is licensed under a Creative Commons Attribution-NonCommercial-NoDerivs 3.0 Unported License. + * + * To view a copy of this license, visit http://creativecommons.org/licenses/by-nc-nd/3.0/. + ******************************************************************************/ +package forestry.core.circuits; + +public interface ISolderingIron { + +} diff --git a/forestry_common/core/forestry/core/circuits/ItemCircuitBoard.java b/forestry_common/core/forestry/core/circuits/ItemCircuitBoard.java new file mode 100755 index 000000000..5bff9e87f --- /dev/null +++ b/forestry_common/core/forestry/core/circuits/ItemCircuitBoard.java @@ -0,0 +1,123 @@ +/******************************************************************************* + * Copyright 2011-2014 by SirSengir + * + * This work is licensed under a Creative Commons Attribution-NonCommercial-NoDerivs 3.0 Unported License. + * + * To view a copy of this license, visit http://creativecommons.org/licenses/by-nc-nd/3.0/. + ******************************************************************************/ +package forestry.core.circuits; + +import java.util.List; +import java.util.Locale; + +import net.minecraft.client.renderer.texture.IIconRegister; +import net.minecraft.creativetab.CreativeTabs; +import net.minecraft.entity.player.EntityPlayer; +import net.minecraft.item.Item; +import net.minecraft.item.ItemStack; +import net.minecraft.nbt.NBTTagCompound; +import net.minecraft.util.IIcon; + +import cpw.mods.fml.relauncher.Side; +import cpw.mods.fml.relauncher.SideOnly; + +import forestry.api.circuits.ChipsetManager; +import forestry.api.circuits.ICircuit; +import forestry.api.circuits.ICircuitBoard; +import forestry.api.circuits.ICircuitLayout; +import forestry.core.config.ForestryItem; +import forestry.core.items.ItemForestry; +import forestry.core.render.TextureManager; +import forestry.core.utils.StringUtil; + +public class ItemCircuitBoard extends ItemForestry { + + public ItemCircuitBoard() { + super(); + setHasSubtypes(true); + } + + @SuppressWarnings({ "unchecked", "rawtypes" }) + @Override + public void getSubItems(Item item, CreativeTabs par2CreativeTabs, List itemList) { + itemList.add(createCircuitboard(EnumCircuitBoardType.BASIC, null, new ICircuit[] {})); + itemList.add(createCircuitboard(EnumCircuitBoardType.ENHANCED, null, new ICircuit[] {})); + itemList.add(createCircuitboard(EnumCircuitBoardType.REFINED, null, new ICircuit[] {})); + itemList.add(createCircuitboard(EnumCircuitBoardType.INTRICATE, null, new ICircuit[] {})); + } + + /** + * @return true if the item's stackTagCompound needs to be synchronized over SMP. + */ + @Override + public boolean getShareTag() { + return true; + } + + /* ICONS */ + @SideOnly(Side.CLIENT) + private IIcon[] icons; + + @SideOnly(Side.CLIENT) + @Override + public void registerIcons(IIconRegister register) { + icons = new IIcon[2]; + icons[0] = TextureManager.getInstance().registerTex(register, getUnlocalizedName().replace("item.", "") + ".0"); + icons[1] = TextureManager.getInstance().registerTex(register, getUnlocalizedName().replace("item.", "") + ".1"); + } + + @SideOnly(Side.CLIENT) + @Override + public IIcon getIconFromDamageForRenderPass(int i, int j) { + if (j > 0) + return icons[0]; + else + return icons[1]; + } + + @Override + public boolean requiresMultipleRenderPasses() { + return true; + } + + @Override + public int getColorFromItemStack(ItemStack itemstack, int j) { + EnumCircuitBoardType type = EnumCircuitBoardType.values()[itemstack.getItemDamage()]; + if (j == 0) + return type.primaryColor; + else + return type.secondaryColor; + } + + @Override + public String getItemStackDisplayName(ItemStack itemstack) { + EnumCircuitBoardType type = EnumCircuitBoardType.values()[itemstack.getItemDamage()]; + return StringUtil.localize("item.circuitboard." + type.toString().toLowerCase(Locale.ENGLISH)); + } + + @SuppressWarnings({ "unchecked", "rawtypes" }) + @Override + public void addInformation(ItemStack itemstack, EntityPlayer player, List list, boolean flag) { + ICircuitBoard circuitboard = ChipsetManager.circuitRegistry.getCircuitboard(itemstack); + if (circuitboard != null) + circuitboard.addTooltip(list); + } + + public static ItemStack createCircuitboard(EnumCircuitBoardType type, ICircuitLayout layout, ICircuit[] circuits) { + ItemStack chipset = ForestryItem.circuitboards.getItemStack(1, type.ordinal()); + saveChipset(chipset, new CircuitBoard(type, layout, circuits)); + return chipset; + } + + public static void saveChipset(ItemStack itemstack, ICircuitBoard circuitboard) { + if (circuitboard == null) { + itemstack.setTagCompound(null); + return; + } + + NBTTagCompound nbttagcompound = new NBTTagCompound(); + circuitboard.writeToNBT(nbttagcompound); + itemstack.setTagCompound(nbttagcompound); + } + +} diff --git a/forestry_common/core/forestry/core/circuits/ItemSolderingIron.java b/forestry_common/core/forestry/core/circuits/ItemSolderingIron.java new file mode 100755 index 000000000..2157ef322 --- /dev/null +++ b/forestry_common/core/forestry/core/circuits/ItemSolderingIron.java @@ -0,0 +1,262 @@ +/******************************************************************************* + * Copyright 2011-2014 by SirSengir + * + * This work is licensed under a Creative Commons Attribution-NonCommercial-NoDerivs 3.0 Unported License. + * + * To view a copy of this license, visit http://creativecommons.org/licenses/by-nc-nd/3.0/. + ******************************************************************************/ +package forestry.core.circuits; + +import java.util.ArrayList; +import java.util.Collection; +import java.util.Iterator; +import java.util.Map.Entry; + +import net.minecraft.entity.player.EntityPlayer; +import net.minecraft.item.ItemStack; +import net.minecraft.nbt.NBTTagCompound; +import net.minecraft.world.World; + +import forestry.api.circuits.ChipsetManager; +import forestry.api.circuits.ICircuit; +import forestry.api.circuits.ICircuitLayout; +import forestry.api.circuits.ISolderManager; +import forestry.api.core.ForestryAPI; +import forestry.core.EnumErrorCode; +import forestry.core.interfaces.IErrorSource; +import forestry.core.items.ItemForestry; +import forestry.core.network.GuiId; +import forestry.core.proxy.Proxies; +import forestry.core.utils.ItemInventory; + +public class ItemSolderingIron extends ItemForestry implements ISolderingIron { + + public static class CircuitRecipe { + ICircuitLayout layout; + ItemStack resource; + ICircuit circuit; + + public CircuitRecipe(ICircuitLayout layout, ItemStack resource, ICircuit circuit) { + this.resource = resource; + this.layout = layout; + this.circuit = circuit; + } + + public boolean matches(ICircuitLayout layout, ItemStack itemstack) { + if (!this.layout.getUID().equals(layout.getUID())) + return false; + + return itemstack.isItemEqual(resource); + } + } + + public static class SolderManager implements ISolderManager { + public static ArrayList recipes = new ArrayList(); + + @Override + public void addRecipe(ICircuitLayout layout, ItemStack resource, ICircuit circuit) { + if (layout == null) + throw new IllegalArgumentException("layout may not be null"); + if (resource == null) + throw new IllegalArgumentException("resource may not be null"); + if (circuit == null) + throw new IllegalArgumentException("circuit may not be null"); + recipes.add(new CircuitRecipe(layout, resource, circuit)); + } + + public static CircuitRecipe getMatchingRecipe(ICircuitLayout layout, ItemStack resource) { + if (layout == null || resource == null) + return null; + + for (CircuitRecipe recipe : recipes) + if (recipe.matches(layout, resource)) + return recipe; + + return null; + } + } + + // / INVENTORY MANAGMENT + public static class SolderingInventory extends ItemInventory implements IErrorSource { + + ICircuitLayout layout; + EnumErrorCode errorState; + + short blankSlot = 0; + short finishedSlot = 1; + short ingredientSlot1 = 2; + + public SolderingInventory() { + super(ItemSolderingIron.class, 6); + layout = ChipsetManager.circuitRegistry.getDefaultLayout(); + } + + public SolderingInventory(ItemStack itemstack) { + super(ItemSolderingIron.class, 6, itemstack); + layout = ChipsetManager.circuitRegistry.getDefaultLayout(); + } + + public ICircuitLayout getLayout() { + return this.layout; + } + + public void setLayout(String uid) { + this.layout = ChipsetManager.circuitRegistry.getLayout(uid); + } + + public void advanceLayout() { + Iterator> it = ChipsetManager.circuitRegistry.getRegisteredLayouts().entrySet().iterator(); + while (it.hasNext()) { + Entry entry = it.next(); + if (entry.getKey().equals(layout.getUID())) { + + if (it.hasNext()) + layout = it.next().getValue(); + else + layout = ChipsetManager.circuitRegistry.getRegisteredLayouts().entrySet().iterator().next().getValue(); + + break; + } + } + } + + public void regressLayout() { + Iterator> it = ChipsetManager.circuitRegistry.getRegisteredLayouts().entrySet().iterator(); + + ICircuitLayout previous = null; + while (it.hasNext()) { + Entry entry = it.next(); + if (entry.getKey().equals(layout.getUID())) { + + if (previous != null) + layout = previous; + else + while (it.hasNext()) + layout = it.next().getValue(); + + break; + } + + previous = entry.getValue(); + } + } + + private Collection getCircuits(EnumCircuitBoardType type, boolean doConsume) { + + ArrayList circuits = new ArrayList(); + + for (short i = 0; i < type.sockets; i++) { + ItemStack ingredient = inventoryStacks[ingredientSlot1 + i]; + if (ingredient == null) + continue; + + CircuitRecipe recipe = SolderManager.getMatchingRecipe(layout, ingredient); + if (recipe == null) + continue; + + // / Make sure we don't exceed this circuits limit per chipset + if (getCount(recipe.circuit, circuits) >= recipe.circuit.getLimit()) + continue; + + if (doConsume) + decrStackSize(ingredientSlot1 + i, recipe.resource.stackSize); + circuits.add(recipe.circuit); + } + + return circuits; + } + + public void trySolder() { + + // Requires blank slot + if (inventoryStacks[blankSlot] == null) + return; + if (inventoryStacks[blankSlot].stackSize > 1) + return; + if (inventoryStacks[finishedSlot] != null) + return; + + ItemStack blank = inventoryStacks[blankSlot]; + // Need a chipset item + if (!ChipsetManager.circuitRegistry.isChipset(blank)) + return; + + // Illegal type + if (blank.getItemDamage() < 0 || blank.getItemDamage() >= EnumCircuitBoardType.values().length) + return; + + EnumCircuitBoardType type = EnumCircuitBoardType.values()[blank.getItemDamage()]; + Collection circuits = getCircuits(type, false); + + if (circuits.size() <= 0) + return; + else if (circuits.size() != type.sockets) { + errorState = EnumErrorCode.CIRCUITMISMATCH; + return; + } + + circuits = getCircuits(type, true); + inventoryStacks[finishedSlot] = ItemCircuitBoard.createCircuitboard(type, layout, circuits.toArray(new ICircuit[0])); + inventoryStacks[blankSlot] = null; + } + + public int getCount(ICircuit circuit, ArrayList circuits) { + int count = 0; + for (ICircuit other : circuits) + if (other.getUID().equals(circuit.getUID())) + count++; + return count; + } + + @Override + public void readFromNBT(NBTTagCompound nbttagcompound) { + } + + @Override + public void writeToNBT(NBTTagCompound nbttagcompound) { + } + + @Override + public void markDirty() { + errorState = EnumErrorCode.OK; + trySolder(); + } + + @Override + public boolean throwsErrors() { + return true; + } + + @Override + public EnumErrorCode getErrorState() { + if (inventoryStacks[blankSlot] == null) + return EnumErrorCode.NOCIRCUITBOARD; + if (inventoryStacks[blankSlot].stackSize > 1) + return EnumErrorCode.WRONGSTACKSIZE; + if (errorState != EnumErrorCode.OK) + return errorState; + + return EnumErrorCode.OK; + } + } + + public ItemSolderingIron() { + super(); + setMaxStackSize(1); + setMaxDamage(5); + } + + @Override + public boolean isFull3D() { + return true; + } + + @Override + public ItemStack onItemRightClick(ItemStack itemstack, World world, EntityPlayer entityplayer) { + if (Proxies.common.isSimulating(world)) + entityplayer.openGui(ForestryAPI.instance, GuiId.SolderingIronGUI.ordinal(), world, (int) entityplayer.posX, (int) entityplayer.posY, + (int) entityplayer.posZ); + + return itemstack; + } +} diff --git a/forestry_common/core/forestry/core/config/Config.java b/forestry_common/core/forestry/core/config/Config.java new file mode 100755 index 000000000..605c2b3ec --- /dev/null +++ b/forestry_common/core/forestry/core/config/Config.java @@ -0,0 +1,373 @@ +/******************************************************************************* + * Copyright 2011-2014 by SirSengir + * + * This work is licensed under a Creative Commons Attribution-NonCommercial-NoDerivs 3.0 Unported License. + * + * To view a copy of this license, visit http://creativecommons.org/licenses/by-nc-nd/3.0/. + ******************************************************************************/ +package forestry.core.config; + +import java.io.File; +import java.io.FileOutputStream; +import java.io.InputStream; +import java.io.OutputStream; +import java.util.ArrayList; +import java.util.Arrays; +import java.util.HashMap; +import java.util.HashSet; +import java.util.Locale; +import java.util.Properties; + +import net.minecraft.world.biome.BiomeGenBase; + +import net.minecraftforge.common.BiomeDictionary; + +import forestry.api.core.EnumHumidity; +import forestry.api.core.EnumTemperature; +import forestry.core.proxy.Proxies; +import forestry.core.triggers.ForestryTrigger; +import forestry.core.utils.Localization; + +public class Config { + + public static final String CATEGORY_COMMON = "common"; + + public static Configuration config; + + public static String gameMode; + + public static HashSet disabledStructures = new HashSet(); + + public static boolean isDebug = false; + + // Native Plugins + public static boolean disableApiculture = false; + public static boolean disableArboriculture = false; + public static boolean disableCultivation = false; + public static boolean disableEnergy = false; + public static boolean disableFactory = false; + public static boolean disableFarming = false; + public static boolean disableFood = false; + public static boolean disableMail = false; + public static boolean disableStorage = false; + + public static boolean disablePermissions = false; + public static boolean disableNags = false; + public static boolean disableVersionCheck = false; + + public static boolean invalidFingerprint = false; + + // Graphics + public static boolean enableParticleFX = true; + + // Bees + public static boolean clearInvalidChromosomes = false; + + // Dungeon loot + public static boolean dungeonLootRare = false; + + // World generation + public static boolean generateApatiteOre = true; + public static boolean generateCopperOre = true; + public static boolean generateTinOre = true; + public static boolean generateBeehives = true; + public static boolean generateBogEarth = false; + + // Performance + public static boolean enableBackpackResupply = true; + public static int planterThrottle; + public static int harvesterThrottle; + + // Customization + public static boolean tooltipLiquidAmount = true; + public static boolean planterSideSensitive = true; + /** + * True if the harvester should decide output to pipes according to side. + */ + public static boolean harvesterSideSensitive = true; + + /* GO AWAY GRED */ + private static boolean craftingBronzeEnabled = true; + + public static boolean getCraftingBronzeEnabled() { + return craftingBronzeEnabled; + } + + public static boolean craftingStampsEnabled = true; + public static ArrayList collectorStamps = new ArrayList(); + + public static boolean applePickup = true; + public static boolean squareFarms = false; + + // Mail + public static boolean mailAlertEnabled = true; + + public static String fakeUserLogin = "[Forestry]"; + public static boolean fakeUserAutoop = true; + + // Hints + public static boolean disableHints = false; + public static HashMap hints = new HashMap(); + public static boolean disableEnergyStat = false; + + @SuppressWarnings({ "all" }) + public static void load() { + + setDebugMode(); + + config = new Configuration(); + config.addPurge("buildcraft.blockid.engine"); + config.addPurge("buildcraft.blockid.pipe"); + config.addPurge("crafting.farms.enabled"); + config.addPurge("crafting.farms.uncrafting.enabled"); + config.addPurge("performance.planter"); + config.addPurge("performance.harvester"); + config.addPurge("buildcraft.ignore"); + config.addPurge("power.framework"); + + Property property = config.get("difficulty.gamemode", CATEGORY_COMMON, "EASY"); + property.Comment = "set to your preferred game mode. available modes are OP, EASY, NORMAL, HARD. mismatch with the server may cause visual glitches with recipes. setting an unavailable mode will create a new mode definition file."; + gameMode = property.Value; + + property = config.get("difficulty.recreate.definitions", CATEGORY_COMMON, true); + property.Comment = "set to true to force recreation of the game mode definitions in config/forestry/gamemodes"; + boolean recreate = Boolean.parseBoolean(property.Value); + + if (recreate) + Proxies.log.info("Recreating all gamemode definitions from the defaults. This may be caused by an upgrade"); + + // Make sure the default mode files are there. + File easyMode = config.getCategoryFile("gamemodes/EASY"); + if (recreate) + CopyFileToFS(easyMode, "/config/forestry/gamemodes/EASY.conf"); + + File opMode = config.getCategoryFile("gamemodes/OP"); + if (!opMode.exists() || recreate) + CopyFileToFS(opMode, "/config/forestry/gamemodes/OP.conf"); + + File normalMode = config.getCategoryFile("gamemodes/NORMAL"); + if (!normalMode.exists() || recreate) + CopyFileToFS(normalMode, "/config/forestry/gamemodes/NORMAL.conf"); + + File hardMode = config.getCategoryFile("gamemodes/HARD"); + if (!hardMode.exists() || recreate) + CopyFileToFS(hardMode, "/config/forestry/gamemodes/HARD.conf"); + + config.set("difficulty.recreate.definitions", CATEGORY_COMMON, false); + + Property particleFX = config.get("performance.particleFX.enabled", CATEGORY_COMMON, true); + particleFX.Comment = "set to false to disable particle fx on slower machines"; + enableParticleFX = Boolean.parseBoolean(particleFX.Value); + + Property genApatiteOre = config.get("world.generate.apatite", CATEGORY_COMMON, true); + genApatiteOre.Comment = "set to false to force forestry to skip generating own apatite ore blocks in the world"; + generateApatiteOre = Boolean.parseBoolean(genApatiteOre.Value); + + Property genBeehives = config.get("world.generate.beehives", CATEGORY_COMMON, true); + genBeehives.Comment = "set to false to force forestry to skip generating beehives in the world"; + generateBeehives = Boolean.parseBoolean(genBeehives.Value); + + Property genCopperOre = config.get("world.generate.copper", CATEGORY_COMMON, true); + genCopperOre.Comment = "set to false to force forestry to skip generating own copper ore blocks in the world"; + generateCopperOre = Boolean.parseBoolean(genCopperOre.Value); + + Property genTinOre = config.get("world.generate.tin", CATEGORY_COMMON, true); + genTinOre.Comment = "set to false to force forestry to skip generating own tin ore blocks in the world"; + generateTinOre = Boolean.parseBoolean(genTinOre.Value); + + Property planterSideSense = config.get("planters.sidesensitive", CATEGORY_COMMON, true); + planterSideSense.Comment = "set to false if farms should output all harvested products regardless of side a pipe is attached to"; + planterSideSensitive = Boolean.parseBoolean(planterSideSense.Value); + Property harvesterSideSense = config.get("harvesters.sidesensitive", CATEGORY_COMMON, true); + harvesterSideSense.Comment = "set to false if harvesters should output all harvested products regardless of side a pipe is attached to"; + harvesterSideSensitive = Boolean.parseBoolean(harvesterSideSense.Value); + + Property bronzeRecipe = config.get("crafting.bronze.enabled", CATEGORY_COMMON, true); + bronzeRecipe.Comment = "set to false to disable crafting recipe for bronze"; + craftingBronzeEnabled = Boolean.parseBoolean(bronzeRecipe.Value); + + property = config.get("crafting.stamps.enabled", CATEGORY_COMMON, true); + property.Comment = "set to false to disable crafting recipes for all types of stamps."; + craftingStampsEnabled = Boolean.parseBoolean(property.Value); + + String defaultCollectors = "20n;50n;100n;200n"; + property = config.get("crafting.stamps.collector", CATEGORY_COMMON, defaultCollectors); + property.Comment = "if crafting of stamps is generally allowed, these stamps are still excluded from crafting."; + try { + collectorStamps.addAll(Arrays.asList(parseStamps(property.Value))); + } catch(Exception ex) { + config.set("crafting.stamps.collector", CATEGORY_COMMON, defaultCollectors); + collectorStamps.addAll(Arrays.asList(parseStamps(defaultCollectors))); + } + + Property indicatorEnable = config.get("tweaks.mailalert.enabled", CATEGORY_COMMON, true); + indicatorEnable.Comment = "set to false to disable the mail alert box"; + mailAlertEnabled = Boolean.parseBoolean(indicatorEnable.Value); + + Property appleHarvest = config.get("tweaks.apple.pickup.enabled", CATEGORY_COMMON, true); + appleHarvest.Comment = "set to false to disable apple pickup by appropriate harvesters"; + applePickup = Boolean.parseBoolean(appleHarvest.Value); + + Property clearGenome = config.get("genetics.clear.invalid.chromosomes", CATEGORY_COMMON, clearInvalidChromosomes); + clearGenome.Comment = "NEW: set to true to clear chromosomes which contain invalid alleles. might rescue your save if it is crashing after removal of a bee addon."; + clearInvalidChromosomes = Boolean.parseBoolean(clearGenome.Value); + + Property dungeonLootRarity = config.get("difficulty.dungeonloot.rare", CATEGORY_COMMON, false); + dungeonLootRarity.Comment = "set to true to make dungeon loot generated by forestry rarer"; + dungeonLootRare = Boolean.parseBoolean(dungeonLootRarity.Value); + + Property resupplyEnable = config.get("performance.backpacks.resupply", CATEGORY_COMMON, true); + resupplyEnable.Comment = "leaving this enabled will cycle the list of active players PER INGAME TICK to check for resupply via backpack. you want to set this to false on busy servers."; + Config.enableBackpackResupply = Boolean.parseBoolean(resupplyEnable.Value); + + property = config.get("tweaks.hints.disabled", CATEGORY_COMMON, false); + property.Comment = "set to true to disable hints on machine and engine guis."; + Config.disableHints = Boolean.parseBoolean(property.Value); + property = config.get("tweaks.energystat.disabled", CATEGORY_COMMON, true); + property.Comment = "set to true to disable energy statistics on energy consumers."; + Config.disableEnergyStat = !isDebug && Boolean.parseBoolean(property.Value); + property = config.get("tweaks.tooltip.liquidamount.disabled", CATEGORY_COMMON, false); + property.Comment = "set to true to disable displaying liquid amounts in tank tooltips."; + Config.tooltipLiquidAmount = isDebug || !Boolean.parseBoolean(property.Value); + + property = config.get("tweaks.permissions.disabled", CATEGORY_COMMON, false); + property.Comment = "set to true to disable access restrictions on forestry machines."; + Config.disablePermissions = Boolean.parseBoolean(property.Value); + + property = config.get("tweaks.nags.disabled", CATEGORY_COMMON, false); + property.Comment = "set to true to disable some nagging and warnings (e.g. GregTech)."; + Config.disableNags = Boolean.parseBoolean(property.Value); + + property = config.get("tweaks.upgradenotice.disabled", CATEGORY_COMMON, false); + property.Comment = "set to true to disable update and version check notice."; + Config.disableVersionCheck = isDebug || Boolean.parseBoolean(property.Value); + + property = config.get("tweaks.farms.squared", CATEGORY_COMMON, false); + property.Comment = "set to true to have farms use a square layout instead of a diamond one."; + Config.squareFarms = Boolean.parseBoolean(property.Value); + + property = config.get("structures.schemata.disabled", CATEGORY_COMMON, ""); + property.Comment = "add schemata keys to disable them. current keys: alveary3x3;farm3x3;farm3x4;farm3x5;farm4x4;farm5x5"; + disabledStructures.addAll(Arrays.asList(parseStructureKeys(property.Value))); + for (String str : disabledStructures) + Proxies.log.finer("Disabled structure '%s'.", str); + + property = config.get("permissions.login", CATEGORY_COMMON, "[Forestry]"); + property.Comment = "set the default login used by Forestry."; + Config.fakeUserLogin = property.Value; + + property = config.get("permissions.autoop", CATEGORY_COMMON, true); + property.Comment = "set to false to prevent Forestry's user from autooping."; + Config.fakeUserAutoop = Boolean.parseBoolean(property.Value); + + registerClimates(); + ForestryTrigger.initialize(); + + config.save(); + + loadHints(); + } + + private static void setDebugMode() { + File debug = new File(Proxies.common.getForestryRoot(), "config/" + Defaults.MOD.toLowerCase(Locale.ENGLISH) + "/DEBUG.ON"); + isDebug = debug.exists(); + } + + private static void CopyFileToFS(File destination, String resourcePath) { + InputStream stream = Config.class.getResourceAsStream(resourcePath); + OutputStream outstream; + int readBytes; + byte[] buffer = new byte[4096]; + try { + + if (destination.getParentFile() != null) + destination.getParentFile().mkdirs(); + + if (!destination.exists() && !destination.createNewFile()) + return; + + outstream = new FileOutputStream(destination); + while ((readBytes = stream.read(buffer)) > 0) + outstream.write(buffer, 0, readBytes); + } catch (Exception ex) { + ex.printStackTrace(); + } + } + + private static void loadHints() { + + Properties prop = new Properties(); + + try { + InputStream hintStream = Localization.class.getResourceAsStream("/config/forestry/hints.properties"); + prop.load(hintStream); + } catch (Exception ex) { + ex.printStackTrace(); + } + + for (String key : prop.stringPropertyNames()) + hints.put(key, parseHints(prop.getProperty(key))); + } + + private static String[] parseHints(String list) { + if (list.isEmpty()) + return new String[0]; + else + return list.split("[;]+"); + } + + private static String[] parseStructureKeys(String list) { + if (list.isEmpty()) + return new String[0]; + else + return list.split("[;]+"); + + } + + private static String[] parseStamps(String list) { + if (list.isEmpty()) + return new String[0]; + else + return list.split("[;]+"); + } + + private static void registerClimates() { + + for (BiomeGenBase biome : BiomeGenBase.getBiomeGenArray()) { + if (biome == null) + continue; + + if (BiomeDictionary.isBiomeOfType(biome, BiomeDictionary.Type.NETHER)) + EnumTemperature.hellishBiomeIds.add(biome.biomeID); + else if (biome.temperature >= 2.0f) + EnumTemperature.hotBiomeIds.add(biome.biomeID); + else if (biome.temperature >= 1.2f) + EnumTemperature.warmBiomeIds.add(biome.biomeID); + else if (biome.temperature >= 0.2f) + EnumTemperature.normalBiomeIds.add(biome.biomeID); + else if (biome.temperature >= 0.15f) + EnumTemperature.coldBiomeIds.add(biome.biomeID); + else + EnumTemperature.icyBiomeIds.add(biome.biomeID); + } + + // / HUMIDITY + for (BiomeGenBase biome : BiomeGenBase.getBiomeGenArray()) { + if (biome == null) + continue; + + if (biome.rainfall >= 0.9f) + EnumHumidity.dampBiomeIds.add(biome.biomeID); + else if (biome.rainfall >= 0.3f) + EnumHumidity.normalBiomeIds.add(biome.biomeID); + else + EnumHumidity.aridBiomeIds.add(biome.biomeID); + } + + } + + public static boolean getOrCreateBooleanProperty(String key, String kind, boolean defaults) { + return Boolean.parseBoolean(config.get(key, kind, defaults).Value); + } + +} diff --git a/forestry_common/core/forestry/core/config/Configuration.java b/forestry_common/core/forestry/core/config/Configuration.java new file mode 100755 index 000000000..440392b3f --- /dev/null +++ b/forestry_common/core/forestry/core/config/Configuration.java @@ -0,0 +1,286 @@ +/******************************************************************************* + * Copyright 2011-2014 by SirSengir + * + * This work is licensed under a Creative Commons Attribution-NonCommercial-NoDerivs 3.0 Unported License. + * + * To view a copy of this license, visit http://creativecommons.org/licenses/by-nc-nd/3.0/. + ******************************************************************************/ +package forestry.core.config; + +import java.io.BufferedReader; +import java.io.BufferedWriter; +import java.io.File; +import java.io.FileInputStream; +import java.io.FileOutputStream; +import java.io.OutputStreamWriter; +import java.util.ArrayList; +import java.util.Iterator; +import java.util.Locale; +import java.util.Map; +import java.util.TreeMap; + +import net.minecraftforge.common.config.Configuration.UnicodeInputStreamReader; + +import forestry.core.proxy.Proxies; + +public class Configuration { + + private String newLine; + private ArrayList purge = new ArrayList(); + private TreeMap> categorized = new TreeMap>(); + + public Configuration() { + newLine = System.getProperty("line.separator"); + } + + public void addPurge(String key) { + purge.add(key); + } + + public Property get(String key, String category, boolean defaultVal) { + + Property existing = getExisting(key, category); + if (existing != null) + return existing; + + // Create new property since none exists yet. + Property property = new Property(key, new Boolean(defaultVal).toString()); + categorized.get(category).add(property); + return property; + } + + public Property get(String key, String category, int defaultVal) { + + Property existing = getExisting(key, category); + if (existing != null) + return existing; + + // Create new property since none exists yet. + Property property = new Property(key, new Integer(defaultVal).toString()); + categorized.get(category).add(property); + return property; + } + + public Property get(String key, String category, float defaultVal) { + + Property existing = getExisting(key, category); + if (existing != null) + return existing; + + // Create new property since none exists yet. + Property property = new Property(key, new Float(defaultVal).toString()); + categorized.get(category).add(property); + return property; + } + + public Property get(String key, String category, String defaultVal) { + + Property existing = getExisting(key, category); + if (existing != null) + return existing; + + // Create new property since none exists yet. + Property property = new Property(key, defaultVal); + categorized.get(category).add(property); + return property; + } + + public void set(String key, String category, boolean val) { + Property existing = getExisting(key, category); + if (existing != null) { + existing.Value = new Boolean(val).toString(); + return; + } + + // Create new property since none exists yet. + Property property = new Property(key, new Boolean(val).toString()); + categorized.get(category).add(property); + + } + + public void set(String key, String category, String val) { + Property existing = getExisting(key, category); + if (existing != null) { + existing.Value = val; + return; + } + + // Create new property since none exists yet. + Property property = new Property(key, val); + categorized.get(category).add(property); + + } + + public void set(String key, String category, int val) { + Property existing = getExisting(key, category); + if (existing != null) { + existing.Value = new Integer(val).toString(); + return; + } + + // Create new property since none exists yet. + Property property = new Property(key, new Integer(val).toString()); + categorized.get(category).add(property); + + } + + public void set(String key, String category, float val) { + Property existing = getExisting(key, category); + if (existing != null) { + existing.Value = new Float(val).toString(); + return; + } + + // Create new property since none exists yet. + Property property = new Property(key, new Float(val).toString()); + categorized.get(category).add(property); + + } + + public Property getExisting(String key, String category) { + if (!categorized.containsKey(category)) + loadCategory(category); + + for (Property property : categorized.get(category)) + if (property.Key.equals(key)) + return property; + + return null; + } + + public File getCategoryFile(String category) { + return new File(Proxies.common.getForestryRoot(), "config/" + Defaults.MOD.toLowerCase(Locale.ENGLISH) + "/" + category + ".conf"); + } + + public void loadCategory(String category) { + + File file = getCategoryFile(category); + + categorized.remove(category); + categorized.put(category, new ArrayList()); + + try { + + if (file.getParentFile() != null) + file.getParentFile().mkdirs(); + + if (!file.exists()) + return; + + if (!file.canRead()) + return; + + UnicodeInputStreamReader filein = new UnicodeInputStreamReader(new FileInputStream(file), "UTF-8"); + BufferedReader reader = new BufferedReader(filein); + + String lastComment = null; + String line; + + while (true) { + line = reader.readLine(); + + if (line == null) + break; + + if (line.startsWith("#")) { + if (line.length() > 3) + lastComment = line.substring(2, line.length() - 1); + continue; + } + + if (!line.contains("=")) + continue; + + String[] tokens = line.split("="); + Property property; + if (tokens.length > 1) + property = new Property(tokens[0], tokens[1].trim()); + else + property = new Property(tokens[0], ""); + + if (lastComment != null) { + property.Comment = lastComment; + lastComment = null; + } + categorized.get(category).add(property); + } + + reader.close(); + + } catch (Exception ex) { + ex.printStackTrace(); + } + } + + public void save() { + Iterator>> it = categorized.entrySet().iterator(); + while (it.hasNext()) { + Map.Entry> entry = it.next(); + saveFile(getCategoryFile(entry.getKey()), entry.getValue()); + } + } + + private void saveFile(File file, ArrayList properties) { + + try { + + if (file.getParentFile() != null) + file.getParentFile().mkdirs(); + + if (!file.exists() && !file.createNewFile()) + return; + + if (!file.canWrite()) + return; + + FileOutputStream fileout = new FileOutputStream(file); + BufferedWriter writer = new BufferedWriter(new OutputStreamWriter(fileout, "UTF-8")); + + writer.write("# " + Defaults.MOD + newLine + "# " + Version.getVersion() + newLine); + + writer.write("#" + newLine + "# Config files:" + newLine); + writer.write("# base.conf\t\t-\t Contains Forge configuration for block and item ids" + newLine); + writer.write("# common.conf\t\t-\t Contains all options common to Forestry" + newLine); + writer.write("# apiculture.conf\t-\t Contains all options for bee breeding" + newLine); + writer.write("# backpacks.conf\t-\t Contains custom configurations for backpacks" + newLine); + writer.write("# pipes.conf\t\t-\t Configures item id for the apiarist's pipe" + newLine); + writer.write("# gamemodes/\t\t-\t Configures available gamemodes"); + TreeMap> subsectioned = getSubsectioned(properties); + + Iterator>> it = subsectioned.entrySet().iterator(); + while (it.hasNext()) { + Map.Entry> entry = it.next(); + writer.write(newLine + newLine + "#####################" + newLine + "# " + entry.getKey().toUpperCase() + newLine + "#####################" + + newLine); + + for (Property property : entry.getValue()) { + if(purge.contains(property.Key)) + continue; + if (property.Comment != null) + writer.write("# " + property.Comment + newLine); + writer.write(property.Key + "=" + property.Value + newLine); + } + } + + writer.close(); + + } catch (Exception ex) { + ex.printStackTrace(); + } + + } + + private TreeMap> getSubsectioned(ArrayList properties) { + TreeMap> subsectioned = new TreeMap>(); + + for (Property property : properties) { + String subsection = property.Key.split("\\.")[0]; + if (!subsectioned.containsKey(subsection)) + subsectioned.put(subsection, new ArrayList()); + subsectioned.get(subsection).add(property); + } + + return subsectioned; + } + +} diff --git a/forestry_common/core/forestry/core/config/Defaults.java b/forestry_common/core/forestry/core/config/Defaults.java new file mode 100755 index 000000000..920053f00 --- /dev/null +++ b/forestry_common/core/forestry/core/config/Defaults.java @@ -0,0 +1,259 @@ +/******************************************************************************* + * Copyright 2011-2014 by SirSengir + * + * This work is licensed under a Creative Commons Attribution-NonCommercial-NoDerivs 3.0 Unported License. + * + * To view a copy of this license, visit http://creativecommons.org/licenses/by-nc-nd/3.0/. + ******************************************************************************/ +package forestry.core.config; + +import java.util.Locale; + +import net.minecraftforge.oredict.OreDictionary; + +public class Defaults { + // System + public static final String MOD = "Forestry"; + public static final String ID = MOD.toLowerCase(Locale.ENGLISH); + public static final String URL = "http://forestry.sengir.net/"; + + public static final int WILDCARD = OreDictionary.WILDCARD_VALUE; + + public static final int WORLD_HEIGHT = 256; + + public static final int FLAG_BLOCK_UPDATE = 1; + public static final int FLAG_BLOCK_SYNCH = 2; + + public static final int NET_MAX_UPDATE_DISTANCE = 50; + + public static final String DEFAULT_POWER_FRAMEWORK = "forestry.energy.BioPowerFramework"; + public static final int BUCKET_VOLUME = 1000; + + public static final int[] FACINGS = { 0, 1, 2, 3, 4, 5 }; + public static final int FACING_UP = 1; + public static final int FACING_DOWN = 0; + public static final int FACING_NORTH = 2; + public static final int FACING_SOUTH = 3; + public static final int FACING_WEST = 4; + public static final int FACING_EAST = 5; + public static final int[] FACING_SIDES = { FACING_NORTH, FACING_SOUTH, FACING_WEST, FACING_EAST }; + public static final int[] FACING_NORTHSOUTH = { FACING_NORTH, FACING_SOUTH }; + public static final int[] FACING_WESTEAST = { FACING_WEST, FACING_EAST }; + public static final int[] FACINGS_NONE = new int[0]; + + public static final String LIQUID_WATER = "water"; + public static final String LIQUID_LAVA = "lava"; + public static final String LIQUID_MILK = "milk"; + public static final String LIQUID_BIOMASS = "biomass"; + public static final String LIQUID_ETHANOL = "bioethanol"; + public static final String LIQUID_SEEDOIL = "seedoil"; + public static final String LIQUID_HONEY = "honey"; + public static final String LIQUID_JUICE = "juice"; + public static final String LIQUID_ICE = "ice"; + public static final String LIQUID_MEAD = "short.mead"; + public static final String LIQUID_GLASS = "glass"; + public static final String LIQUID_OIL = "oil"; + public static final String LIQUID_FUEL = "fuel"; + + // Textures + public static final String TEXTURE_PATH_GUI = "textures/gui"; + public static final String TEXTURE_PATH_BLOCKS = "textures/blocks"; + public static final String TEXTURE_PATH_ITEMS = "textures/items"; + public static final String TEXTURE_PATH_ENTITIES = "textures/entity"; + + public static final String TEXTURE_BLOCKS = TEXTURE_PATH_BLOCKS + "/blocks.png"; + public static final String TEXTURE_ARBORICULTURE = TEXTURE_PATH_BLOCKS + "/arboriculture.png"; + public static final String TEXTURE_PODS = TEXTURE_PATH_BLOCKS + "/pods.png"; + public static final String TEXTURE_FARM = TEXTURE_PATH_BLOCKS + "/farm.png"; + + public static final String TEXTURE_APIARIST_ARMOR_PRIMARY = TEXTURE_PATH_ITEMS + "/apiarist_armor_1.png"; + public static final String TEXTURE_APIARIST_ARMOR_SECONDARY = TEXTURE_PATH_ITEMS + "/apiarist_armor_2.png"; + public static final String TEXTURE_NATURALIST_ARMOR_PRIMARY = TEXTURE_PATH_ITEMS + "/naturalist_armor_1.png"; + public static final String TEXTURE_SKIN_BEEKPEEPER = TEXTURE_PATH_ENTITIES + "/beekeeper.png"; + public static final String TEXTURE_SKIN_LUMBERJACK = TEXTURE_PATH_ENTITIES + "/lumberjack.png"; + + public static final String TEXTURE_ICONS_MINECRAFT = "/gui/items.png"; + public static final String TEXTURE_BLOCKS_MINECRAFT = "/terrain.png"; + + // Villagers + public static final int ID_VILLAGER_BEEKEEPER = 80; + public static final int ID_VILLAGER_LUMBERJACK = 81; + + // Village Chest Gen hook + public static final String CHEST_GEN_HOOK_NATURALIST_CHEST = "naturalistChest"; + + // Definition IDs + public static final int DEFINITION_ANALYZER_META = 0; + public static final int DEFINITION_ESCRITOIRE_META = 1; + + public static final int DEFINITION_APIARY_META = 0; + public static final int DEFINITION_APIARISTCHEST_META = 1; + public static final int DEFINITION_BEEHOUSE_META = 2; + + public static final int DEFINITION_ENGINETIN_META = 0; + public static final int DEFINITION_ENGINECOPPER_META = 1; + public static final int DEFINITION_ENGINEBRONZE_META = 2; + public static final int DEFINITION_GENERATOR_META = 3; + public static final int DEFINITION_ENGINECLOCKWORK_META = 4; + + public static final int DEFINITION_MAILBOX_META = 0; + public static final int DEFINITION_TRADESTATION_META = 1; + public static final int DEFINITION_PHILATELIST_META = 2; + + public static final int DEFINITION_BOTTLER_META = 0; + public static final int DEFINITION_CARPENTER_META = 1; + public static final int DEFINITION_CENTRIFUGE_META = 2; + public static final int DEFINITION_FERMENTER_META = 3; + public static final int DEFINITION_MOISTENER_META = 4; + public static final int DEFINITION_SQUEEZER_META = 5; + public static final int DEFINITION_STILL_META = 6; + public static final int DEFINITION_RAINMAKER_META = 7; + + public static final int DEFINITION_FABRICATOR_META = 0; + public static final int DEFINITION_RAINTANK_META = 1; + public static final int DEFINITION_WORKTABLE_META = 2; + + public static final int DEFINITION_LEPICHEST_META = 0; + + public static final int DEFINITION_ARBCHEST_META = 0; + + // Package Ids + public static final int ID_PACKAGE_MACHINE_FERMENTER = 0; + public static final int ID_PACKAGE_MACHINE_STILL = 1; + public static final int ID_PACKAGE_MACHINE_BOTTLER = 2; + public static final int ID_PACKAGE_MACHINE_RAINTANK = 3; + public static final int ID_PACKAGE_MACHINE_CARPENTER = 5; + public static final int ID_PACKAGE_MACHINE_MOISTENER = 6; + public static final int ID_PACKAGE_MACHINE_APIARY = 7; + public static final int ID_PACKAGE_MACHINE_CENTRIFUGE = 8; + public static final int ID_PACKAGE_MACHINE_SQUEEZER = 9; + public static final int ID_PACKAGE_MACHINE_ALVEARY = 10; + public static final int ID_PACKAGE_MACHINE_FABRICATOR = 11; + + public static final int ID_PACKAGE_MILL_RAINMAKER = 1; + public static final int ID_PACKAGE_MILL_APIARIST_CHEST = 3; + public static final int ID_PACKAGE_MILL_ANALYZER = 4; + public static final int ID_PACKAGE_MILL_MAILBOX = 5; + public static final int ID_PACKAGE_MILL_TRADER = 6; + public static final int ID_PACKAGE_MILL_PHILATELIST = 7; + + // Item Ids + + public static final int SLOTS_BACKPACK_DEFAULT = 15; + public static final int SLOTS_BACKPACK_T2 = 45; + public static final int SLOTS_BACKPACK_APIARIST = 125; + + // Bee ids + public static final int ID_BEE_SPECIES_REDDENED = 31; + public static final int ID_BEE_SPECIES_DARKENED = 32; + public static final int ID_BEE_SPECIES_OMEGA = 33; + + // Food stuff + public static final int FOOD_AMBROSIA_HEAL = 8; + public static final int FOOD_JUICE_HEAL = 2; + public static final float FOOD_JUICE_SATURATION = 0.2f; + public static final int FOOD_HONEY_HEAL = 2; + public static final float FOOD_HONEY_SATURATION = 0.2f; + + // IndustrialCraft 2 + public static final int ID_IC2_FUELCAN_DAMAGE = 6480; + + // BuildCraft + public static final int BUILDCRAFT_BLOCKID_ENGINE = 161; + public static final int BUILDCRAFT_BLOCKID_PIPE = 166; + + public static final int APIARY_MIN_LEVEL_LIGHT = 11; + public static final int APIARY_BREEDING_TIME = 100; + + // Energy + public static final int ENGINE_TANK_CAPACITY = 10 * BUCKET_VOLUME; + public static final int ENGINE_CYCLE_DURATION_WATER = 1000; + public static final int ENGINE_CYCLE_DURATION_JUICE = 2500; + public static final int ENGINE_CYCLE_DURATION_HONEY = 2500; + public static final int ENGINE_CYCLE_DURATION_MILK = 10000; + public static final int ENGINE_CYCLE_DURATION_SEED_OIL = 2500; + public static final int ENGINE_CYCLE_DURATION_BIOMASS = 2500; + public static final int ENGINE_CYCLE_DURATION_ETHANOL = 15000; + public static final int ENGINE_FUEL_VALUE_WATER = 1; + public static final int ENGINE_FUEL_VALUE_JUICE = 1; + public static final int ENGINE_FUEL_VALUE_HONEY = 2; + public static final int ENGINE_FUEL_VALUE_MILK = 1; + public static final int ENGINE_FUEL_VALUE_SEED_OIL = 3; + public static final int ENGINE_FUEL_VALUE_BIOMASS = 5; + public static final int ENGINE_HEAT_VALUE_LAVA = 20; + + public static final float ENGINE_PISTON_SPEED_MAX = 0.08f; + + public static final int ENGINE_BRONZE_HEAT_MAX = 10000; + public static final int ENGINE_BRONZE_HEAT_LOSS_COOL = 2; + public static final int ENGINE_BRONZE_HEAT_LOSS_OPERATING = 1; + public static final int ENGINE_BRONZE_HEAT_LOSS_OVERHEATING = 5; + public static final int ENGINE_BRONZE_HEAT_GENERATION_ENERGY = 1; + + public static final int ENGINE_COPPER_CYCLE_DURATION_PEAT = 5000; + public static final int ENGINE_COPPER_FUEL_VALUE_PEAT = 1; + public static final int ENGINE_COPPER_CYCLE_DURATION_BITUMINOUS_PEAT = 6000; + public static final int ENGINE_COPPER_FUEL_VALUE_BITUMINOUS_PEAT = 2; + public static final int ENGINE_COPPER_HEAT_MAX = 10000; + public static final int ENGINE_COPPER_ASH_FOR_ITEM = 7500; + + public static final int ENGINE_TIN_HEAT_MAX = 3000; + public static final int ENGINE_TIN_EU_FOR_CYCLE = 6; + public static final int ENGINE_TIN_ENERGY_PER_CYCLE = 2; + public static final int ENGINE_TIN_MAX_EU_STORED = 2 * ENGINE_TIN_EU_FOR_CYCLE; + public static final int ENGINE_TIN_MAX_EU_BATTERY = 100; + + // Factory + public static final int PROCESSOR_TANK_CAPACITY = 10 * BUCKET_VOLUME; + + public static final int MACHINE_LATENCY = 1000; + public static final int MACHINE_MIN_ENERGY_RECEIVED = 5; + public static final int MACHINE_MAX_ENERGY_RECEIVED = 40; + public static final int MACHINE_MIN_ACTIVATION_ENERGY = 15; + public static final int MACHINE_MAX_ENERGY = 500; + + public static final int RAINMAKER_RAIN_DURATION_IODINE = 10000; + + public static final int STILL_DESTILLATION_DURATION = 100; + public static final int STILL_DESTILLATION_INPUT = 10; + public static final int STILL_DESTILLATION_OUTPUT = 3; + + public static final int BOTTLER_FILLING_TIME = 20; + public static final int BOTTLER_FUELCAN_VOLUME = 2000; + + // Storage + public static final int RAINTANK_TANK_CAPACITY = 30 * BUCKET_VOLUME; + public static final int RAINTANK_AMOUNT_PER_UPDATE = 10; + public static final int RAINTANK_FILLING_TIME = 12; + public static final int CARPENTER_CRATING_CYCLES = 5; + public static final int CARPENTER_UNCRATING_CYCLES = 5; + public static final int CARPENTER_CRATING_LIQUID_QUANTITY = 100; + + // SMP gui ids + public static final int ID_GUI_ARBORETUM = 90; + public static final int ID_GUI_BOTTLER = 91; + public static final int ID_GUI_ENGINE_BRONZE = 92; + public static final int ID_GUI_FARM = 93; + public static final int ID_GUI_FERMENTER = 94; + public static final int ID_GUI_FORESTER = 95; + public static final int ID_GUI_PLANTATION = 96; + public static final int ID_GUI_PUMPKIN_FARM = 97; + public static final int ID_GUI_PEAT_BOG = 98; + public static final int ID_GUI_STILL = 99; + public static final int ID_GUI_ENGINE_COPPER = 89; + public static final int ID_GUI_RAINTANK = 88; + public static final int ID_GUI_GENERATOR = 87; + public static final int ID_GUI_CARPENTER = 86; + public static final int ID_GUI_MOISTENER = 85; + public static final int ID_GUI_MUSHROOM_FARM = 84; + public static final int ID_GUI_APIARY = 83; + public static final int ID_GUI_CENTRIFUGE = 82; + public static final int ID_GUI_APIARIST_INVENTORY = 81; + public static final int ID_GUI_BACKPACK = 80; + public static final int ID_GUI_SQUEEZER = 79; + public static final int ID_GUI_NETHER_FARM = 78; + public static final int ID_GUI_BEEALYZER = 100; + public static final int ID_GUI_BACKPACK_T2 = 101; + public static final int ID_GUI_BIOME_FINDER = 102; + // ID 100 used by bucket filler. +} diff --git a/forestry_common/core/forestry/core/config/ForestryBlock.java b/forestry_common/core/forestry/core/config/ForestryBlock.java new file mode 100755 index 000000000..06fdeca9f --- /dev/null +++ b/forestry_common/core/forestry/core/config/ForestryBlock.java @@ -0,0 +1,81 @@ +/******************************************************************************* + * Copyright 2011-2014 by SirSengir + * + * This work is licensed under a Creative Commons Attribution-NonCommercial-NoDerivs 3.0 Unported License. + * + * To view a copy of this license, visit http://creativecommons.org/licenses/by-nc-nd/3.0/. + ******************************************************************************/ +package forestry.core.config; + +import net.minecraft.block.Block; + +import forestry.core.gadgets.BlockBase; + +/** + * Allows direct access to Forestry's blocks. Will be populated during BaseMod.load(). + * + * All of this stuff is metadata sensitive which is not reflected here! + * + * Make sure to only reference it in modsLoaded() or later. + * + * @author SirSengir + * + */ +public class ForestryBlock { + + /** + * 0 - Humus 1 - Bog Earth + */ + public static Block soil; + /** + * 0 - Apatite Ore 1 - Copper Ore 2 - Tin Ore + */ + public static Block resources; + /** + * 0 - Legacy 1 - Forest Hive 2 - Meadows Hive + */ + public static Block beehives; + + public static Block mushroom; + public static Block candle; + public static Block stump; + public static Block glass; + + public static Block planks1; + public static Block planks2; + public static Block slabs1; + public static Block slabs2; + public static Block slabs3; + public static Block slabs4; + public static Block log1; + public static Block log2; + public static Block log3; + public static Block log4; + public static Block log5; + public static Block log6; + public static Block log7; + public static Block log8; + + public static Block fences1; + public static Block fences2; + public static Block stairs; + + public static Block saplingGE; + public static Block leaves; + public static Block pods; + + public static BlockBase arboriculture; + + public static Block alveary; + public static Block farm; + + public static BlockBase core; + public static BlockBase apiculture; + public static BlockBase mail; + + public static BlockBase engine; + public static BlockBase factoryTESR; + public static BlockBase factoryPlain; + + public static BlockBase lepidopterology; +} diff --git a/forestry_common/core/forestry/core/config/ForestryItem.java b/forestry_common/core/forestry/core/config/ForestryItem.java new file mode 100755 index 000000000..376c02ff5 --- /dev/null +++ b/forestry_common/core/forestry/core/config/ForestryItem.java @@ -0,0 +1,275 @@ +/******************************************************************************* + * Copyright 2011-2014 by SirSengir + * + * This work is licensed under a Creative Commons Attribution-NonCommercial-NoDerivs 3.0 Unported License. + * + * To view a copy of this license, visit http://creativecommons.org/licenses/by-nc-nd/3.0/. + ******************************************************************************/ +package forestry.core.config; + +import net.minecraft.item.Item; +import net.minecraft.item.ItemStack; + +import forestry.core.proxy.Proxies; + +/** + * Allows direct access to Forestry's items. Will be populated during + * preInit and Init. + * + * Most items with the exception of bees do not care for damage values. + * + * Make sure to only reference it in postInit or later. + * + * @author SirSengir + * + */ +public enum ForestryItem { + + fertilizerBio, + fertilizerCompound, + apatite, + // Ingots + ingotCopper, + ingotTin, + ingotBronze, + // Tools + wrench, + pipette, + bucketBiomass, + vialEmpty, + vialCatalyst, + bucketBiofuel, + // Crafting + impregnatedCasing, + sturdyCasing, + hardenedCasing, + craftingMaterial, + // Rainmaker + iodineCharge, + // Gears + gearBronze, + gearCopper, + gearTin, + // Chipsets + circuitboards, + solderingIron, + tubes, + // Mail + stamps, + letters, + catalogue, + // mailIndicator, + + // Carpenter + stickImpregnated, + woodPulp, + carton, + crate, + // Tools + bronzePickaxe, + brokenBronzePickaxe, + kitPickaxe, + bronzeShovel, + brokenBronzeShovel, + kitShovel, + // Do not touch - contagious! + tent, + biomeFinder, + // Moistener + mouldyWheat, + decayingWheat, + mulch, + // Peat + peat, + bituminousPeat, + ash, + // Bees + beeQueenGE, + beeDroneGE, + beePrincessGE, + beeLarvaeGE, + beealyzer, + imprinter, + honeyDrop, + scoop, + beeswax, + pollen, + propolis, + honeydew, + royalJelly, + honeyedSlice, + ambrosia, + honeyPot, + phosphor, + refractoryWax, + waxCast, + frameUntreated, + frameImpregnated, + frameProven, + // Trees + sapling, + pollenFertile, + treealyzer, + grafter, + grafterProven, + // Butterflies + butterflyGE, + flutterlyzer, + serumGE, + caterpillarGE, + researchNote, + // Beverages + beverage, + infuser, + // Naturalist's Armor + naturalistHat, + // Apiarist's Armor + apiaristHat, + apiaristChest, + apiaristLegs, + apiaristBoots, + // Combs + beeComb, + // Fruits + fruits, + // Backpacks + apiaristBackpack, + lepidopteristBackpack, + minerBackpack, + diggerBackpack, + foresterBackpack, + hunterBackpack, + builderBackpack, + adventurerBackpack, + // T2 + minerBackpackT2, + diggerBackpackT2, + foresterBackpackT2, + hunterBackpackT2, + builderBackpackT2, + adventurerBackpackT2, + // Capsules + waxCapsule, + waxCapsuleWater, + waxCapsuleBiomass, + waxCapsuleBiofuel, + waxCapsuleOil, + waxCapsuleFuel, + waxCapsuleSeedOil, + waxCapsuleHoney, + waxCapsuleJuice, + waxCapsuleIce, + // Refractory Capsules + refractoryEmpty, + refractoryWater, + refractoryBiomass, + refractoryBiofuel, + refractoryOil, + refractoryFuel, + refractoryLava, + refractorySeedOil, + refractoryHoney, + refractoryJuice, + refractoryIce, + // Cans + canWater, + canEmpty, + canBiomass, + canBiofuel, + canOil, + canFuel, + canLava, + canSeedOil, + canHoney, + canJuice, + canIce, + // Crating + cratedWood, + cratedCobblestone, + cratedDirt, + cratedStone, + cratedBrick, + cratedCacti, + cratedSand, + cratedObsidian, + cratedNetherrack, + cratedSoulsand, + cratedSandstone, + cratedBogearth, + cratedHumus, + cratedNetherbrick, + cratedPeat, + cratedApatite, + cratedFertilizer, + cratedTin, + cratedCopper, + cratedBronze, + cratedWheat, + cratedMycelium, + cratedMulch, + cratedSilver, + cratedBrass, + cratedNikolite, + cratedCookies, + cratedHoneycombs, + cratedBeeswax, + cratedPollen, + cratedPropolis, + cratedHoneydew, + cratedRoyalJelly, + cratedCocoaComb, + cratedRedstone, + cratedLapis, + cratedReeds, + cratedClay, + cratedGlowstone, + cratedApples, + cratedNetherwart, + cratedResin, + cratedRubber, + cratedScrap, + cratedUUM, + cratedSimmeringCombs, + cratedStringyCombs, + cratedFrozenCombs, + cratedDrippingCombs, + cratedRefractoryWax, + cratedPhosphor, + cratedAsh, + cratedCharcoal, + cratedGravel, + cratedCoal, + cratedSeeds, + cratedSaplings; + private Item item; + + public void registerItem(Item item, String name) { + this.item = item; + item.setUnlocalizedName(name); + Proxies.common.registerItem(item); + } + + public boolean isItemEqual(ItemStack stack) { + return stack != null && this.item == stack.getItem(); + } + + public boolean isItemEqual(Item i) { + return i != null && this.item == i; + } + + public Item item() { + return item; + } + + public ItemStack getItemStack() { + return getItemStack(1, 0); + } + + public ItemStack getItemStack(int qty) { + return getItemStack(qty, 0); + } + + public ItemStack getItemStack(int qty, int meta) { + return new ItemStack(item, qty, meta); + } +} diff --git a/forestry_common/core/forestry/core/config/Property.java b/forestry_common/core/forestry/core/config/Property.java new file mode 100755 index 000000000..7fb68851f --- /dev/null +++ b/forestry_common/core/forestry/core/config/Property.java @@ -0,0 +1,19 @@ +/******************************************************************************* + * Copyright 2011-2014 by SirSengir + * + * This work is licensed under a Creative Commons Attribution-NonCommercial-NoDerivs 3.0 Unported License. + * + * To view a copy of this license, visit http://creativecommons.org/licenses/by-nc-nd/3.0/. + ******************************************************************************/ +package forestry.core.config; + +public class Property { + public String Key; + public String Value; + public String Comment; + + public Property(String key, String value) { + Key = key; + Value = value; + } +} diff --git a/forestry_common/core/forestry/core/config/SessionVars.java b/forestry_common/core/forestry/core/config/SessionVars.java new file mode 100755 index 000000000..4242db8a0 --- /dev/null +++ b/forestry_common/core/forestry/core/config/SessionVars.java @@ -0,0 +1,40 @@ +/******************************************************************************* + * Copyright 2011-2014 by SirSengir + * + * This work is licensed under a Creative Commons Attribution-NonCommercial-NoDerivs 3.0 Unported License. + * + * To view a copy of this license, visit http://creativecommons.org/licenses/by-nc-nd/3.0/. + ******************************************************************************/ +package forestry.core.config; + +import java.util.HashMap; + +public class SessionVars { + + private static HashMap stringVars = new HashMap(); + + private static Class openedLedger; + + public static void setOpenedLedger(Class ledgerClass) { + openedLedger = ledgerClass; + } + + public static Class getOpenedLedger() { + return openedLedger; + } + + public static void setStringVar(String ident, String val) { + stringVars.put(ident, val); + } + + public static String getStringVar(String ident) { + if(stringVars.containsKey(ident)) + return stringVars.get(ident); + + return null; + } + + public static void clearStringVar(String ident) { + stringVars.remove(ident); + } +} diff --git a/forestry_common/core/forestry/core/config/Version.java b/forestry_common/core/forestry/core/config/Version.java new file mode 100755 index 000000000..514ff179e --- /dev/null +++ b/forestry_common/core/forestry/core/config/Version.java @@ -0,0 +1,208 @@ +/******************************************************************************* + * Copyright 2011-2014 by SirSengir + * + * This work is licensed under a Creative Commons Attribution-NonCommercial-NoDerivs 3.0 Unported License. + * + * To view a copy of this license, visit http://creativecommons.org/licenses/by-nc-nd/3.0/. + ******************************************************************************/ +package forestry.core.config; + +import java.io.BufferedReader; +import java.io.InputStreamReader; +import java.net.HttpURLConnection; +import java.net.URL; +import java.util.ArrayList; + +import cpw.mods.fml.common.FMLCommonHandler; +import cpw.mods.fml.common.versioning.DefaultArtifactVersion; + +import forestry.Forestry; +import forestry.core.proxy.Proxies; + +/** + * With permission from pahimar. + * + * @author Pahimar + * + */ +public class Version { + + public enum EnumUpdateState { + + CURRENT, OUTDATED, CONNECTION_ERROR + } + public static final String VERSION = "@VERSION@"; + public static final String BUILD_NUMBER = "@BUILD_NUMBER@"; + public static final String[] FAILED_CHANGELOG = new String[] { String.format("Unable to retrieve changelog for %s", Defaults.MOD) }; + public static final String FINGERPRINT = "@FINGERPRINT@"; + public static final String FORGEPRINT = "de4cf8a3f3bc15635810044c39240bf96804ea7d"; + private static final String REMOTE_VERSION_FILE = "http://bit.ly/forestryver"; + private static final String REMOTE_CHANGELOG_ROOT = "https://dl.dropbox.com/u/44760587/forestry/changelog/"; + private static final String REMOTE_FINGERPRINT_ROOT = new String(new byte[] { 104, 116, 116, 112, 115, 58, 47, 47, 100, 108, 46, 100, 114, 111, 112, 98, + 111, 120, 46, 99, 111, 109, 47, 117, 47, 52, 52, 55, 54, 48, 53, 56, 55, 47, 102, 111, 114, 101, 115, 116, 114, 121, 47, 102, 105, 110, 103, 101, + 114, 112, 114, 105, 110, 116, 115, 47 }); + public static EnumUpdateState currentVersion = EnumUpdateState.CURRENT; + public static final String FORGE_VERSION = "@FORGE_VERSION@"; + public static String remoteFingerprint; + public static String remoteForgeprint; + private static String recommendedVersion; + private static String[] cachedChangelog = FAILED_CHANGELOG; + + public static String getVersion() { + return VERSION + " (" + BUILD_NUMBER + ")"; + } + + public static boolean isOutdated() { + return currentVersion == EnumUpdateState.OUTDATED; + } + + public static boolean needsUpdateNoticeAndMarkAsSeen() { + if (!isOutdated()) + return false; + + Property property = Config.config.get("vars.version.seen", Config.CATEGORY_COMMON, VERSION); + property.Comment = "indicates the last version the user has been informed about and will suppress further notices on it."; + String seenVersion = property.Value; + + if (recommendedVersion == null || recommendedVersion.equals(seenVersion)) + return false; + + property.Value = recommendedVersion; + Config.config.save(); + return true; + } + + public static String getRecommendedVersion() { + return recommendedVersion; + } + + public static void updateRemoteFingerprints() { + remoteFingerprint = retrieveRemoteString(REMOTE_FINGERPRINT_ROOT + new String(new byte[] { 102, 111, 114, 101, 115, 116, 114, 121, 46, 107, 101, 121 }) + + "1", FINGERPRINT); + remoteFingerprint = retrieveRemoteString(REMOTE_FINGERPRINT_ROOT + new String(new byte[] { 102, 111, 114, 103, 101, 46, 107, 101, 121 }) + "1", + FORGEPRINT); + } + + public static String retrieveRemoteString(String location, String defaultValue) { + try { + + HttpURLConnection conn = null; + while (location != null && !location.isEmpty()) { + URL url = new URL(location); + conn = (HttpURLConnection) url.openConnection(); + conn.setRequestProperty("User-Agent", + "Mozilla/5.0 (Windows; U; Windows NT 6.0; ru; rv:1.9.0.11) Gecko/2009060215 Firefox/3.0.11 (.NET CLR 3.5.30729)"); + conn.connect(); + location = conn.getHeaderField("Location"); + } + + BufferedReader reader = new BufferedReader(new InputStreamReader(conn.getInputStream())); + + String line = null; + if ((line = reader.readLine()) != null) + return line; + + } catch (Exception e) { + e.printStackTrace(); + Proxies.log.warning("Unable to read from remote fingerprint authority."); + } + + return defaultValue; + } + + private static class VersionChecker extends Thread { + + @Override + public void run() { + try { + String location = REMOTE_VERSION_FILE; + HttpURLConnection conn = null; + while (location != null && !location.isEmpty()) { + URL url = new URL(location); + conn = (HttpURLConnection) url.openConnection(); + conn.setRequestProperty("User-Agent", + "Mozilla/5.0 (Windows; U; Windows NT 6.0; ru; rv:1.9.0.11) Gecko/2009060215 Firefox/3.0.11 (.NET CLR 3.5.30729)"); + conn.connect(); + location = conn.getHeaderField("Location"); + } + + BufferedReader reader = new BufferedReader(new InputStreamReader(conn.getInputStream())); + + String line = null; + String mcVersion = Proxies.common.getMinecraftVersion(); + while ((line = reader.readLine()) != null) { + if (line.startsWith(mcVersion) && line.contains(Defaults.MOD)) { + String[] tokens = line.split(":"); + recommendedVersion = tokens[2]; + } + } + + if (recommendedVersion == null) + return; + + int result = FMLCommonHandler.instance().findContainerFor(Forestry.instance).getProcessedVersion().compareTo(new DefaultArtifactVersion(recommendedVersion)); + if (result >= 0) { + Proxies.log.finer("Using the latest version [" + VERSION + " (build:" + BUILD_NUMBER + ")] for Minecraft " + mcVersion); + currentVersion = EnumUpdateState.CURRENT; + return; + } + + cachedChangelog = grabChangelog(recommendedVersion); + + Proxies.log.warning("Using outdated version [" + VERSION + " (build:" + BUILD_NUMBER + ")] for Minecraft " + mcVersion + ". Consider updating."); + currentVersion = EnumUpdateState.OUTDATED; + + } catch (Exception e) { +// e.printStackTrace(); + Proxies.log.warning("Unable to read from remote version authority."); + currentVersion = EnumUpdateState.CONNECTION_ERROR; + } + } + } + + public static void versionCheck() { + new VersionChecker().start(); + } + + public static String[] getChangelog() { + return cachedChangelog; + } + + public static String[] grabChangelog(String version) { + + try { + + String location = REMOTE_CHANGELOG_ROOT + version; + HttpURLConnection conn = null; + while (location != null && !location.isEmpty()) { + URL url = new URL(location); + conn = (HttpURLConnection) url.openConnection(); + conn.setRequestProperty("User-Agent", + "Mozilla/5.0 (Windows; U; Windows NT 6.0; ru; rv:1.9.0.11) Gecko/2009060215 Firefox/3.0.11 (.NET CLR 3.5.30729)"); + conn.connect(); + location = conn.getHeaderField("Location"); + } + + BufferedReader reader = new BufferedReader(new InputStreamReader(conn.getInputStream())); + + String line = null; + ArrayList changelog = new ArrayList(); + while ((line = reader.readLine()) != null) { + if (line.startsWith("#")) + continue; + if (line.isEmpty()) + continue; + + changelog.add(line); + } + + return changelog.toArray(new String[0]); + + } catch (Exception ex) { +// ex.printStackTrace(); + Proxies.log.warning("Unable to read changelog from remote site."); + } + + return new String[] { String.format("Unable to retrieve changelog for %s %s", Defaults.MOD, version) }; + } +} diff --git a/forestry_common/core/forestry/core/gadgets/BlockBase.java b/forestry_common/core/forestry/core/gadgets/BlockBase.java new file mode 100755 index 000000000..72417a033 --- /dev/null +++ b/forestry_common/core/forestry/core/gadgets/BlockBase.java @@ -0,0 +1,253 @@ +/******************************************************************************* + * Copyright 2011-2014 by SirSengir + * + * This work is licensed under a Creative Commons Attribution-NonCommercial-NoDerivs 3.0 Unported License. + * + * To view a copy of this license, visit http://creativecommons.org/licenses/by-nc-nd/3.0/. + ******************************************************************************/ +package forestry.core.gadgets; + +import java.util.ArrayList; +import java.util.List; + +import net.minecraft.block.material.Material; +import net.minecraft.client.renderer.texture.IIconRegister; +import net.minecraft.creativetab.CreativeTabs; +import net.minecraft.entity.EntityLivingBase; +import net.minecraft.entity.player.EntityPlayer; +import net.minecraft.init.Items; +import net.minecraft.item.Item; +import net.minecraft.item.ItemStack; +import net.minecraft.tileentity.TileEntity; +import net.minecraft.util.ChatComponentText; +import net.minecraft.util.ChatComponentTranslation; +import net.minecraft.util.IIcon; +import net.minecraft.world.IBlockAccess; +import net.minecraft.world.World; + +import cpw.mods.fml.relauncher.Side; +import cpw.mods.fml.relauncher.SideOnly; + +import net.minecraftforge.common.util.ForgeDirection; +import net.minecraftforge.fluids.FluidContainerRegistry; +import net.minecraftforge.fluids.IFluidHandler; + +import forestry.core.interfaces.IOwnable; +import forestry.core.items.ItemNBTTile; +import forestry.core.proxy.Proxies; +import forestry.core.utils.LiquidHelper; + +public class BlockBase extends BlockForestry { + + private final List definitions = new ArrayList(); + private final boolean hasTESR; + + public BlockBase(Material material) { + this(material, false); + } + + public BlockBase(Material material, boolean hasTESR) { + super(material); + + this.hasTESR = hasTESR; + } + + public MachineDefinition addDefinition(MachineDefinition definition) { + definition.setBlock(this); + + while (definitions.size() <= definition.meta) definitions.add(null); + + definitions.set(definition.meta, definition); + + return definition; + } + + @Override + public boolean isOpaqueCube() { + return !hasTESR; + } + + @Override + public boolean renderAsNormalBlock() { + return !hasTESR; + } + + @Override + public int getRenderType() { + if (hasTESR) + return Proxies.common.getByBlockModelId(); + else + return 0; + } + + private MachineDefinition getDefinition(IBlockAccess world, int x, int y, int z) { + return getDefinition(world.getBlockMetadata(x, y, z)); + } + + private MachineDefinition getDefinition(int metadata) { + if (metadata >= definitions.size() || definitions.get(metadata) == null) + return definitions.get(0); + + return definitions.get(metadata); + } + + /* CREATIVE INVENTORY */ + @SuppressWarnings("rawtypes") + @SideOnly(Side.CLIENT) + @Override + public void getSubBlocks(Item item, CreativeTabs tab, List list) { + for (MachineDefinition definition : definitions) { + if (definition == null) + continue; + definition.getSubBlocks(item, tab, list); + } + } + + /* TILE ENTITY CREATION */ + @Override + public TileEntity createTileEntity(World world, int metadata) { + if (metadata >= definitions.size() || definitions.get(metadata) == null) + metadata = 0; + + return definitions.get(metadata).createMachine(); + } + + @Override + public TileEntity createNewTileEntity(World world, int meta) { + return createTileEntity(world, meta); // TODO: refactor to just use Block, not BlockContainer + } + + /* BLOCK DROPS */ + @Override + public ArrayList getDrops(World world, int x, int y, int z, int metadata, int fortune) { + if (getDefinition(metadata).handlesDrops()) + return getDefinition(metadata).getDrops(world, x, y, z, metadata, fortune); + else + return super.getDrops(world, x, y, z, metadata, fortune); + } + + /* INTERACTION */ + @Override + public boolean isSideSolid(IBlockAccess world, int x, int y, int z, ForgeDirection side) { + return getDefinition(world, x, y, z).isSolidOnSide(world, x, y, z, side.ordinal()); + } + + @Override + public void onBlockPlacedBy(World world, int x, int y, int z, EntityLivingBase entityliving, ItemStack stack) { + super.onBlockPlacedBy(world, x, y, z, entityliving, stack); + + TileForestry tile = (TileForestry) world.getTileEntity(x, y, z); + + if (stack.getItem() instanceof ItemNBTTile && stack.hasTagCompound()) { + tile.readFromNBT(stack.getTagCompound()); + tile.xCoord = x; + tile.yCoord = y; + tile.zCoord = z; + } + + tile.rotateAfterPlacement(world, x, y, z, entityliving, stack); + } + + @Override + public boolean onBlockActivated(World world, int x, int y, int z, EntityPlayer player, int side, float par7, float par8, float par9) { + if (getDefinition(world, x, y, z).onBlockActivated(world, x, y, z, player, side, par7, par8, par9)) + return true; + + if (player.isSneaking()) + return false; + + TileBase tile = (TileBase) world.getTileEntity(x, y, z); + if (!tile.isUseableByPlayer(player)) + return false; + + ItemStack current = player.getCurrentEquippedItem(); + if (current != null && current.getItem() != Items.bucket && tile instanceof IFluidHandler) { + if (Proxies.common.isSimulating(world)) { + if (LiquidHelper.handleRightClick((IFluidHandler) tile, ForgeDirection.getOrientation(side), player, true, tile.canDrainWithBucket())) { + return true; + } + } else { + if (FluidContainerRegistry.isContainer(current)) { + return true; + } + } + } + + if (!Proxies.common.isSimulating(world)) + return true; + + if (tile.allowsInteraction(player)) + tile.openGui(player, tile); + else + player.addChatMessage(new ChatComponentTranslation("\u00A7c%s %s", new ChatComponentText(tile.getOwnerName()), new ChatComponentTranslation("chat.accesslocked"))); + return true; + } + + @Override + public boolean rotateBlock(World world, int x, int y, int z, ForgeDirection axis) { + return getDefinition(world, x, y, z).rotateBlock(world, x, y, z, axis); + } + + @Override + public void onBlockAdded(World world, int x, int y, int z) { + super.onBlockAdded(world, x, y, z); + getDefinition(world, x, y, z).onBlockAdded(world, x, y, z); + } + + @Override + public boolean removedByPlayer(World world, EntityPlayer player, int x, int y, int z) { + + IOwnable tile = (IOwnable) world.getTileEntity(x, y, z); + if (tile.isOwnable() && !tile.allowsRemoval(player)) + return false; + + if (getDefinition(world, x, y, z).removedByPlayer(world, player, x, y, z)) + return world.setBlockToAir(x, y, z); + else + return false; + } + + @Override + public boolean canConnectRedstone(IBlockAccess world, int x, int y, int z, int side) { + int metadata = world.getBlockMetadata(x, y, z); + if (metadata >= definitions.size() || definitions.get(metadata) == null) + metadata = 0; + return definitions.get(metadata).canConnectRedstone(world, x, y, z, side); + } + + @Override + public int damageDropped(int metadata) { + return metadata; + } + + /* TEXTURES */ + @SideOnly(Side.CLIENT) + @Override + public void registerBlockIcons(IIconRegister register) { + for (MachineDefinition def : definitions) { + def.registerIcons(register); + } + } + + @SideOnly(Side.CLIENT) + @Override + public IIcon getIcon(int side, int metadata) { + if (metadata >= definitions.size() || definitions.get(metadata) == null) + metadata = 0; + return definitions.get(metadata).getBlockTextureFromSideAndMetadata(side, metadata); + } + + @SideOnly(Side.CLIENT) + @Override + public IIcon getIcon(IBlockAccess world, int x, int y, int z, int side) { + int metadata = world.getBlockMetadata(x, y, z); + if (metadata >= definitions.size() || definitions.get(metadata) == null) + metadata = 0; + return definitions.get(metadata).getIcon(world, x, y, z, side, metadata); + } + + @Override + public boolean getUseNeighborBrightness() { + return hasTESR; + } +} diff --git a/forestry_common/core/forestry/core/gadgets/BlockForestry.java b/forestry_common/core/forestry/core/gadgets/BlockForestry.java new file mode 100755 index 000000000..0f816218a --- /dev/null +++ b/forestry_common/core/forestry/core/gadgets/BlockForestry.java @@ -0,0 +1,72 @@ +/******************************************************************************* + * Copyright 2011-2014 by SirSengir + * + * This work is licensed under a Creative Commons Attribution-NonCommercial-NoDerivs 3.0 Unported License. + * + * To view a copy of this license, visit http://creativecommons.org/licenses/by-nc-nd/3.0/. + ******************************************************************************/ +package forestry.core.gadgets; + +import java.util.Random; + +import net.minecraft.block.Block; +import net.minecraft.block.BlockContainer; +import net.minecraft.block.material.Material; +import net.minecraft.entity.EntityLivingBase; +import net.minecraft.entity.player.EntityPlayer; +import net.minecraft.item.ItemStack; +import net.minecraft.tileentity.TileEntity; +import net.minecraft.world.World; + +import forestry.core.CreativeTabForestry; +import forestry.core.interfaces.IOwnable; +import forestry.core.proxy.Proxies; +import forestry.core.utils.Utils; + +public abstract class BlockForestry extends BlockContainer { + + protected static boolean keepInventory = false; + protected Random furnaceRand; + + public BlockForestry(Material material) { + super(material); + setHardness(1.5f); + furnaceRand = new Random(); + setCreativeTab(CreativeTabForestry.tabForestry); + } + + @Override + public boolean removedByPlayer(World world, EntityPlayer player, int x, int y, int z) { + IOwnable tile = (IOwnable) world.getTileEntity(x, y, z); + if (!tile.isOwnable() || tile.allowsRemoval(player)) + return super.removedByPlayer(world, player, x, y, z); + else + return false; + } + + @Override + public void breakBlock(World world, int x, int y, int z, Block block, int meta) { + + if (!Proxies.common.isSimulating(world)) + return; + + TileEntity tile = world.getTileEntity(x, y, z); + if (tile instanceof TileForestry) { + TileForestry tileForestry = (TileForestry) tile; + Utils.dropInventory(tileForestry, world, x, y, z); + tileForestry.onRemoval(); + } + super.breakBlock(world, x, y, z, block, meta); + } + + @Override + public void onBlockPlacedBy(World world, int i, int j, int k, EntityLivingBase entityliving, ItemStack itemstack) { + + if (!Proxies.common.isSimulating(world)) + return; + + TileForestry tile = (TileForestry) world.getTileEntity(i, j, k); + if (entityliving instanceof EntityPlayer) + tile.owner = ((EntityPlayer) entityliving).getGameProfile().getId(); + } +} diff --git a/forestry_common/core/forestry/core/gadgets/BlockResource.java b/forestry_common/core/forestry/core/gadgets/BlockResource.java new file mode 100755 index 000000000..9d8eae49b --- /dev/null +++ b/forestry_common/core/forestry/core/gadgets/BlockResource.java @@ -0,0 +1,105 @@ +/******************************************************************************* + * Copyright 2011-2014 by SirSengir + * + * This work is licensed under a Creative Commons Attribution-NonCommercial-NoDerivs 3.0 Unported License. + * + * To view a copy of this license, visit http://creativecommons.org/licenses/by-nc-nd/3.0/. + ******************************************************************************/ +package forestry.core.gadgets; + +import java.util.ArrayList; +import java.util.List; + +import net.minecraft.block.Block; +import net.minecraft.block.material.Material; +import net.minecraft.client.renderer.texture.IIconRegister; +import net.minecraft.creativetab.CreativeTabs; +import net.minecraft.item.Item; +import net.minecraft.item.ItemStack; +import net.minecraft.util.IIcon; +import net.minecraft.util.MathHelper; +import net.minecraft.world.World; + +import cpw.mods.fml.relauncher.Side; +import cpw.mods.fml.relauncher.SideOnly; + +import forestry.core.CreativeTabForestry; +import forestry.core.config.ForestryItem; +import forestry.core.render.TextureManager; + +public class BlockResource extends Block { + public BlockResource() { + super(Material.rock); + setHardness(3F); + setResistance(5F); + setCreativeTab(CreativeTabForestry.tabForestry); + } + + @Override + public void dropBlockAsItemWithChance(World world, int x, int y, int z, int metadata, float par6, int par7) { + super.dropBlockAsItemWithChance(world, x, y, z, metadata, par6, par7); + + if (metadata == 0) + this.dropXpOnBlockBreak(world, x, y, z, MathHelper.getRandomIntegerInRange(world.rand, 1, 4)); + } + + @Override + public ArrayList getDrops(World world, int x, int y, int z, int metadata, int fortune) { + ArrayList drops = new ArrayList(); + + if (metadata == 0) { + int fortmod = world.rand.nextInt(fortune + 2) - 1; + if (fortmod < 0) + fortmod = 0; + + int amount = (2 + world.rand.nextInt(5)) * (fortmod + 1); + if (amount > 0) + drops.add(ForestryItem.apatite.getItemStack(amount)); + } else + drops.add(new ItemStack(this, 1, metadata)); + + return drops; + } + + @Override + public int getDamageValue(World world, int x, int y, int z) { + return world.getBlockMetadata(x, y, z); + } + + // / CREATIVE INVENTORY + @SuppressWarnings({ "rawtypes", "unchecked" }) + @Override + public void getSubBlocks(Item item, CreativeTabs par2CreativeTabs, List itemList) { + itemList.add(new ItemStack(this, 1, 0)); + itemList.add(new ItemStack(this, 1, 1)); + itemList.add(new ItemStack(this, 1, 2)); + } + + /* ICONS */ + @SideOnly(Side.CLIENT) + private IIcon iconApatite; + @SideOnly(Side.CLIENT) + private IIcon iconCopper; + @SideOnly(Side.CLIENT) + private IIcon iconTin; + + @Override + @SideOnly(Side.CLIENT) + public void registerBlockIcons(IIconRegister register) { + iconApatite = TextureManager.getInstance().registerTex(register, "ores/apatite"); + iconCopper = TextureManager.getInstance().registerTex(register, "ores/copper"); + iconTin = TextureManager.getInstance().registerTex(register, "ores/tin"); + } + + @Override + @SideOnly(Side.CLIENT) + public IIcon getIcon(int i, int j) { + if (j == 0) + return iconApatite; + else if (j == 1) + return iconCopper; + else + return iconTin; + } + +} diff --git a/forestry_common/core/forestry/core/gadgets/BlockSoil.java b/forestry_common/core/forestry/core/gadgets/BlockSoil.java new file mode 100755 index 000000000..af8ca7fbd --- /dev/null +++ b/forestry_common/core/forestry/core/gadgets/BlockSoil.java @@ -0,0 +1,260 @@ +/******************************************************************************* + * Copyright 2011-2014 by SirSengir + * + * This work is licensed under a Creative Commons Attribution-NonCommercial-NoDerivs 3.0 Unported License. + * + * To view a copy of this license, visit http://creativecommons.org/licenses/by-nc-nd/3.0/. + ******************************************************************************/ +package forestry.core.gadgets; + +import java.util.ArrayList; +import java.util.List; +import java.util.Random; + +import net.minecraft.block.Block; +import net.minecraft.block.material.Material; +import net.minecraft.client.renderer.texture.IIconRegister; +import net.minecraft.creativetab.CreativeTabs; +import net.minecraft.init.Blocks; +import net.minecraft.item.Item; +import net.minecraft.item.ItemStack; +import net.minecraft.util.IIcon; +import net.minecraft.world.IBlockAccess; +import net.minecraft.world.World; + +import cpw.mods.fml.relauncher.Side; +import cpw.mods.fml.relauncher.SideOnly; + +import net.minecraftforge.common.EnumPlantType; +import net.minecraftforge.common.IPlantable; +import net.minecraftforge.common.util.ForgeDirection; + +import forestry.core.CreativeTabForestry; +import forestry.core.config.Defaults; +import forestry.core.config.ForestryBlock; +import forestry.core.config.ForestryItem; +import forestry.core.proxy.Proxies; +import forestry.core.render.TextureManager; + +/** + * Humus, bog earth, peat + * + * @author + * + */ +public class BlockSoil extends Block { + + private final int degradeDelimiter = 3; + + public BlockSoil() { + super(Material.sand); + setTickRandomly(true); + setHardness(0.5f); + setStepSound(soundTypeGrass); + setCreativeTab(CreativeTabForestry.tabForestry); + } + + @Override + public int tickRate(World world) { + return 500; + } + + @Override + public ArrayList getDrops(World world, int x, int y, int z, int metadata, int fortune) { + ArrayList ret = new ArrayList(); + + int type = (metadata & 0x03); + int maturity = metadata >> 2; + + if (maturity >= this.degradeDelimiter && type == 1) { + ret.add(ForestryItem.peat.getItemStack()); + ret.add(new ItemStack(Blocks.dirt)); + } else if (type == 0) + ret.add(new ItemStack(Blocks.dirt)); + else + ret.add(new ItemStack(this, 1, type)); + + return ret; + } + + @Override + public int getDamageValue(World world, int x, int y, int z) { + return (world.getBlockMetadata(x, y, z) & 0x03); + } + + @Override + public void updateTick(World world, int i, int j, int k, Random random) { + if (!Proxies.common.isSimulating(world)) + return; + + int meta = world.getBlockMetadata(i, j, k); + int type = (meta & 0x03); + + if (type == 0) + updateTickHumus(world, i, j, k, random); + else if (type == 1) + updateTickBogEarth(world, i, j, k, random); + else + Proxies.log.warning(this.getClass() + " with unknown type " + type + " encountered."); + } + + private void updateTickHumus(World world, int i, int j, int k, Random random) { + if (isEnrooted(world, i, j, k)) + degradeSoil(world, i, j, k); + } + + private void updateTickBogEarth(World world, int i, int j, int k, Random random) { + if (isMoistened(world, i, j, k)) + matureBog(world, i, j, k); + } + + /** + * + * @param world + * @param x + * @param y + * @param z + * @return + */ + private boolean isEnrooted(World world, int x, int y, int z) { + + for (int i = -1; i < 2; i++) + for (int j = -1; j < 2; j++) { + Block block = world.getBlock(x + i, y + 1, z + j); + if (block == Blocks.log || block == Blocks.sapling || block == ForestryBlock.saplingGE) + // We are not returning true if we are the base of a + // sapling. + if (i == 0 && j == 0) + return false; + else + return true; + } + + return false; + } + + /** + * If a tree or sapling is in the vicinity, there is a chance, that the soil will degrade. + * + * @param world + * @param i + * @param j + * @param k + */ + private void degradeSoil(World world, int i, int j, int k) { + + if (world.rand.nextInt(140) != 0) + return; + + int meta = world.getBlockMetadata(i, j, k); + + // Unpack first + int type = meta & 0x03; + int grade = meta >> 2; + + // Increment (de)gradation + grade++; + + // Repackage in format TTGG + meta = (grade << 2 | type); + + if (grade >= this.degradeDelimiter) + world.setBlock(i, j, k, Blocks.sand, 0, Defaults.FLAG_BLOCK_SYNCH); + else + world.setBlockMetadataWithNotify(i, j, k, meta, Defaults.FLAG_BLOCK_SYNCH); + world.markBlockForUpdate(i, j, k); + } + + public static boolean isMoistened(World world, int x, int y, int z) { + + for (int i = -2; i < 3; i++) + for (int j = -2; j < 3; j++) { + Block block = world.getBlock(x + i, y, z + j); + if (block == Blocks.water || block == Blocks.flowing_water) + return true; + } + + return false; + } + + private void matureBog(World world, int i, int j, int k) { + + if (world.rand.nextInt(13) != 0) + return; + + int meta = world.getBlockMetadata(i, j, k); + + // Unpack first + + int type = meta & 0x03; + int maturity = meta >> 2; + + if (maturity >= this.degradeDelimiter) + return; + + // Increment (de)gradation + maturity++; + + meta = (maturity << 2 | type); + world.setBlockMetadataWithNotify(i, j, k, meta, Defaults.FLAG_BLOCK_SYNCH); + world.markBlockForUpdate(i, j, k); + } + + @Override + public boolean canSustainPlant(IBlockAccess world, int x, int y, int z, ForgeDirection direction, IPlantable plant) { + EnumPlantType plantType = plant.getPlantType(world, x, y, z); + if (plantType != EnumPlantType.Crop && plantType != EnumPlantType.Plains) + return false; + + int meta = world.getBlockMetadata(x, y, z); + + return (meta & 0x03) == 0; + } + + @Override + protected boolean canSilkHarvest() { + return false; + } + + // / CREATIVE INVENTORY + @SuppressWarnings({ "rawtypes", "unchecked" }) + @Override + public void getSubBlocks(Item item, CreativeTabs par2CreativeTabs, List itemList) { + itemList.add(new ItemStack(this, 1, 0)); + itemList.add(new ItemStack(this, 1, 1)); + } + + /* ICONS */ + @SideOnly(Side.CLIENT) + private IIcon iconHumus; + @SideOnly(Side.CLIENT) + private IIcon iconBogEarth; + @SideOnly(Side.CLIENT) + private IIcon iconPeat; + + @Override + @SideOnly(Side.CLIENT) + public void registerBlockIcons(IIconRegister register) { + iconHumus = TextureManager.getInstance().registerTex(register, "soil/humus"); + iconBogEarth = TextureManager.getInstance().registerTex(register, "soil/bog"); + iconPeat = TextureManager.getInstance().registerTex(register, "soil/peat"); + } + + @Override + @SideOnly(Side.CLIENT) + public IIcon getIcon(int i, int j) { + + int meta = j; + int type = meta & 0x03; + int maturity = meta >> 2; + + if (type == 1) + if (maturity < this.degradeDelimiter) + return iconBogEarth; + else + return iconPeat; + else + return iconHumus; + } + +} diff --git a/forestry_common/core/forestry/core/gadgets/BlockStainedGlass.java b/forestry_common/core/forestry/core/gadgets/BlockStainedGlass.java new file mode 100755 index 000000000..0e9ed4bcb --- /dev/null +++ b/forestry_common/core/forestry/core/gadgets/BlockStainedGlass.java @@ -0,0 +1,93 @@ +/******************************************************************************* + * Copyright 2011-2014 by SirSengir + * + * This work is licensed under a Creative Commons Attribution-NonCommercial-NoDerivs 3.0 Unported License. + * + * To view a copy of this license, visit http://creativecommons.org/licenses/by-nc-nd/3.0/. + ******************************************************************************/ +package forestry.core.gadgets; + +import java.util.List; +import java.util.Random; + +import net.minecraft.block.BlockBreakable; +import net.minecraft.block.material.Material; +import net.minecraft.client.renderer.texture.IIconRegister; +import net.minecraft.creativetab.CreativeTabs; +import net.minecraft.item.Item; +import net.minecraft.item.ItemStack; +import net.minecraft.util.IIcon; +import net.minecraft.world.IBlockAccess; + +import cpw.mods.fml.relauncher.Side; +import cpw.mods.fml.relauncher.SideOnly; + +import forestry.core.CreativeTabForestry; +import forestry.core.render.TextureManager; + +public class BlockStainedGlass extends BlockBreakable { + + public BlockStainedGlass() { + super("", Material.glass, true); + setHardness(0.3F); + setStepSound(soundTypeGlass); + setCreativeTab(CreativeTabForestry.tabForestry); + } + + @SuppressWarnings({ "rawtypes", "unchecked" }) + @Override + public void getSubBlocks(Item item, CreativeTabs par2CreativeTabs, List itemList) { + for (int i = 0; i < 16; i++) + itemList.add(new ItemStack(this, 1, i)); + } + + /* ICONS */ + @SideOnly(Side.CLIENT) + private IIcon[] icons; + + @Override + @SideOnly(Side.CLIENT) + public void registerBlockIcons(IIconRegister register) { + icons = new IIcon[16]; + for (int i = 0; i < 16; i++) + icons[i] = TextureManager.getInstance().registerTex(register, "stained/" + i); + } + + @Override + @SideOnly(Side.CLIENT) + public IIcon getIcon(int side, int meta) { + return icons[15 - meta]; + } + + @Override + @SideOnly(Side.CLIENT) + public IIcon getIcon(IBlockAccess world, int x, int y, int z, int side) { + return this.getIcon(side, world.getBlockMetadata(x, y, z)); + } + + @Override + public int damageDropped(int meta) { + return meta; + } + + @Override + public int quantityDropped(Random rand) { + return 0; + } + + @Override + public int getRenderBlockPass() { + return 1; + } + + @Override + public boolean isOpaqueCube() { + return false; + } + + @Override + public boolean renderAsNormalBlock() { + return false; + } + +} diff --git a/forestry_common/core/forestry/core/gadgets/BlockStructure.java b/forestry_common/core/forestry/core/gadgets/BlockStructure.java new file mode 100755 index 000000000..0660e4c26 --- /dev/null +++ b/forestry_common/core/forestry/core/gadgets/BlockStructure.java @@ -0,0 +1,90 @@ +/******************************************************************************* + * Copyright 2011-2014 by SirSengir + * + * This work is licensed under a Creative Commons Attribution-NonCommercial-NoDerivs 3.0 Unported License. + * + * To view a copy of this license, visit http://creativecommons.org/licenses/by-nc-nd/3.0/. + ******************************************************************************/ +package forestry.core.gadgets; + +import net.minecraft.block.Block; +import net.minecraft.block.material.Material; +import net.minecraft.entity.player.EntityPlayer; +import net.minecraft.tileentity.TileEntity; +import net.minecraft.util.ChatComponentText; +import net.minecraft.util.ChatComponentTranslation; +import net.minecraft.world.World; + +import forestry.api.core.ITileStructure; +import forestry.core.proxy.Proxies; + +public abstract class BlockStructure extends BlockForestry { + + public enum EnumStructureState { + VALID, INVALID, INDETERMINATE + } + + public BlockStructure(Material material) { + super(material); + setHardness(1.0f); + } + + @Override + public boolean canSilkHarvest() { + return false; + } + + @Override + public void breakBlock(World world, int x, int y, int z, Block block, int meta) { + TileEntity tile = world.getTileEntity(x, y, z); + + super.breakBlock(world, x, y, z, block, meta); + + if (tile instanceof ITileStructure) { + ITileStructure structure = (ITileStructure) tile; + if (structure.isIntegratedIntoStructure() && !structure.isMaster()) { + ITileStructure central = structure.getCentralTE(); + if (central != null) + central.validateStructure(); + } + } + } + + @Override + public boolean onBlockActivated(World world, int x, int y, int z, EntityPlayer player, int par6, float par7, float par8, float par9) { + + if (player.isSneaking()) + return false; + + TileForestry tile = (TileForestry) world.getTileEntity(x, y, z); + if (!tile.isUseableByPlayer(player)) + return false; + + if (!Proxies.common.isSimulating(world)) + return player.getCurrentEquippedItem() == null || !(player.getCurrentEquippedItem().getItem() instanceof IStructureBlockItem); + + // GUIs can only be opened on integrated structure blocks. + if (tile instanceof ITileStructure) + if (!((ITileStructure) tile).isIntegratedIntoStructure()) + return false; + + if (tile.allowsInteraction(player)) + tile.openGui(player); + else + player.addChatMessage(new ChatComponentTranslation("\u00A7c%s %s", new ChatComponentText(tile.getOwnerName()), new ChatComponentTranslation("chat.accesslocked"))); + return true; + } + + @Override + public void onNeighborBlockChange(World world, int x, int y, int z, Block neighbor) { + + if (!Proxies.common.isSimulating(world)) + return; + + TileEntity tile = world.getTileEntity(x, y, z); + if (!(tile instanceof ITileStructure)) + return; + + ((ITileStructure) tile).validateStructure(); + } +} diff --git a/forestry_common/core/forestry/core/gadgets/Engine.java b/forestry_common/core/forestry/core/gadgets/Engine.java new file mode 100755 index 000000000..b6f861351 --- /dev/null +++ b/forestry_common/core/forestry/core/gadgets/Engine.java @@ -0,0 +1,432 @@ +/******************************************************************************* + * Copyright 2011-2014 by SirSengir + * + * This work is licensed under a Creative Commons Attribution-NonCommercial-NoDerivs 3.0 Unported License. + * + * To view a copy of this license, visit http://creativecommons.org/licenses/by-nc-nd/3.0/. + ******************************************************************************/ +package forestry.core.gadgets; + +import net.minecraft.entity.EntityLivingBase; +import net.minecraft.inventory.Container; +import net.minecraft.inventory.ICrafting; +import net.minecraft.item.ItemStack; +import net.minecraft.nbt.NBTTagCompound; +import net.minecraft.tileentity.TileEntity; +import net.minecraft.world.World; + +import net.minecraftforge.common.util.ForgeDirection; +import net.minecraftforge.fluids.FluidContainerRegistry.FluidContainerData; + +import buildcraft.api.core.Position; +import buildcraft.api.power.IPowerEmitter; +import buildcraft.api.power.IPowerReceptor; +import buildcraft.api.power.PowerHandler; +import buildcraft.api.power.PowerHandler.PowerReceiver; +import buildcraft.api.transport.IPipeConnection; +import buildcraft.api.transport.IPipeTile.PipeType; + +import forestry.core.TemperatureState; +import forestry.core.config.Defaults; +import forestry.core.interfaces.IPowerHandler; +import forestry.core.network.PacketPayload; +import forestry.core.proxy.Proxies; +import forestry.core.utils.BlockUtil; +import forestry.core.utils.ForestryTank; +import forestry.plugins.PluginBuildCraft; + +public abstract class Engine extends TileBase implements IPowerHandler, IPipeConnection, IPowerEmitter { + + @Override + public PacketPayload getPacketPayload() { + PacketPayload payload = new PacketPayload(3, 1, 0); + + if (this.isActive) + payload.intPayload[0] = 1; + else + payload.intPayload[0] = 0; + payload.intPayload[1] = (int) storedEnergy; + payload.intPayload[2] = heat; + + payload.floatPayload[0] = pistonSpeedServer; + + return payload; + } + + @Override + public void fromPacketPayload(PacketPayload payload) { + + if (payload.intPayload[0] > 0) + isActive = true; + else + isActive = false; + storedEnergy = payload.intPayload[1]; + heat = payload.intPayload[2]; + + pistonSpeedServer = payload.floatPayload[0]; + } + public boolean isActive = false; // Used for smp. + /** + * Indicates whether the piston is receding from or approaching the + * combustion chamber + */ + public int stagePiston = 0; + /** + * Piston speed as supplied by the server + */ + public float pistonSpeedServer = 0; + protected int currentOutput = 0; + public final int maxEnergy; + public final int maxEnergyExtracted; + public float storedEnergy; + public int heat; + protected final int maxHeat; + protected boolean forceCooldown = false; + public float progress; + private final PowerHandler powerProvider; + + public Engine(int maxHeat, int maxEnergy, int maxEnergyExtracted) { + this.maxHeat = maxHeat; + this.maxEnergy = maxEnergy; + this.maxEnergyExtracted = maxEnergyExtracted; + powerProvider = new PowerHandler(this, PowerHandler.Type.ENGINE); + powerProvider.configure(10, 200, 10, 100000); + } + + protected ItemStack replenishByContainer(ItemStack inventoryStack, FluidContainerData container, ForestryTank tank) { + if (container == null) + return inventoryStack; + + if (tank.fill(container.fluid, false) >= container.fluid.amount) { + tank.fill(container.fluid, true); + if (container.filledContainer != null && container.filledContainer.getItem().hasContainerItem(container.filledContainer)) + inventoryStack = container.emptyContainer.copy(); + else + inventoryStack.stackSize--; + } + + return inventoryStack; + } + + @Override + public void rotateAfterPlacement(World world, int x, int y, int z, EntityLivingBase entityliving, ItemStack itemstack) { + rotateEngine(); + } + + /** + * Adds energy + * + * @param addition + */ + public void addEnergy(float addition) { + storedEnergy += addition; + + if (storedEnergy > maxEnergy) + storedEnergy = maxEnergy; + } + + /** + * + * @param min Minimum energy to extract. Will return 0 if storedEnergy less + * than min. + * @param max Maximum energy to extract. + * @param doExtract Determines whether energy will actually be removed from + * the engine. + * + * @return + */ + public double extractEnergy(double min, double max, boolean doExtract) { + if (storedEnergy < min) + return 0; + + double ceiling = max > maxEnergyExtracted ? maxEnergyExtracted : max; + + double extracted; + + if (storedEnergy >= ceiling) { + extracted = ceiling; + if (doExtract) + storedEnergy -= ceiling; + } else { + extracted = storedEnergy; + if (doExtract) + storedEnergy = 0; + } + + return extracted; + } + + /** + * Adds heat + * + * @param i + */ + protected void addHeat(int i) { + heat += i; + + if (heat > maxHeat) + heat = maxHeat; + } + + public abstract int dissipateHeat(); + + public abstract int generateHeat(); + + public int maxEnergyReceived() { + return 200; + } + + public boolean mayBurn() { + return !forceCooldown; + } + + public abstract void burn(); + + @Override + public void updateClientSide() { + if (stagePiston != 0) { + progress += pistonSpeedServer; + + if (progress > 1) { + stagePiston = 0; + progress = 0; + } + } else if (this.isActive) + stagePiston = 1; + return; + } + + @Override + public void updateServerSide() { + TemperatureState energyState = getTemperatureState(); + if (energyState == TemperatureState.MELTING && heat > 0) + forceCooldown = true; + else if (forceCooldown && heat <= 0) + forceCooldown = false; + + // Determine targeted tile + Position posTarget = new Position(xCoord, yCoord, zCoord, this.getOrientation()); + posTarget.moveForwards(1.0); + TileEntity tile = worldObj.getTileEntity((int) posTarget.x, (int) posTarget.y, (int) posTarget.z); + + float newPistonSpeed = getPistonSpeed(); + if (newPistonSpeed != pistonSpeedServer) { + pistonSpeedServer = newPistonSpeed; + sendNetworkUpdate(); + } + + if (stagePiston != 0) { + + progress += pistonSpeedServer; + + if (progress > 0.5 && stagePiston == 1) { + stagePiston = 2; + + if (BlockUtil.isPoweredTile(getOrientation().getOpposite(), tile)) { + IPowerReceptor receptor = (IPowerReceptor) tile; + double extractedEnergy = extractEnergy(receptor.getPowerReceiver(getOrientation().getOpposite()).getMinEnergyReceived(), receptor.getPowerReceiver(getOrientation().getOpposite()).getMaxEnergyReceived(), + true); + if (extractedEnergy > 0) + PluginBuildCraft.instance.invokeReceiveEnergyMethod(PowerHandler.Type.ENGINE, receptor.getPowerReceiver(getOrientation().getOpposite()), extractedEnergy, getOrientation().getOpposite()); + // receptor.getPowerProvider().receiveEnergy(extractedEnergy); + } + + } else if (progress >= 1) { + progress = 0; + stagePiston = 0; + } + + } else if (canPowerTo(tile)) { // If we are not already running, check if + IPowerReceptor receptor = (IPowerReceptor) tile; + if (extractEnergy(receptor.getPowerReceiver(getOrientation().getOpposite()).getMinEnergyReceived(), receptor.getPowerReceiver(getOrientation().getOpposite()).getMaxEnergyReceived(), false) > 0) { + stagePiston = 1; // If we can transfer energy, start running + setActive(true); + } else + setActive(false); + } else + setActive(false); + + dissipateHeat(); + generateHeat(); + // Now let's fire up the engine: + if (mayBurn()) + burn(); + else + extractEnergy(0, 2, true); + + } + + private boolean canPowerTo(TileEntity tile) { + return isActivated() && BlockUtil.isPoweredTile(getOrientation().getOpposite(), tile); + } + + private void setActive(boolean isActive) { + if (this.isActive == isActive) + return; + + this.isActive = isActive; + sendNetworkUpdate(); + } + + /* INTERACTION */ + public void rotateEngine() { + + for (int i = getOrientation().ordinal() + 1; i <= getOrientation().ordinal() + 6; ++i) { + ForgeDirection orient = ForgeDirection.values()[i % 6]; + + Position pos = new Position(xCoord, yCoord, zCoord, orient); + pos.moveForwards(1.0F); + + TileEntity tile = worldObj.getTileEntity((int) pos.x, (int) pos.y, (int) pos.z); + + if (BlockUtil.isPoweredTile(getOrientation().getOpposite(), tile)) { + setOrientation(orient); + worldObj.notifyBlocksOfNeighborChange(xCoord, yCoord, zCoord, worldObj.getBlock(xCoord, yCoord, zCoord)); + worldObj.func_147479_m(xCoord, yCoord, zCoord); + break; + } + } + } + + // STATE INFORMATION + protected double getHeatLevel() { + return (double) heat / (double) maxHeat; + } + + public abstract boolean isBurning(); + + public int getBurnTimeRemainingScaled(int i) { + return 0; + } + + public boolean hasFuelMin(float percentage) { + return false; + } + + public int getCurrentOutput() { + if (isBurning() && isActivated()) + return currentOutput; + else + return 0; + } + + public float getEnergyStored() { + return storedEnergy; + } + + public int getHeat() { + return heat; + } + + /** + * Returns the current energy state of the engine + * + * @return + */ + public TemperatureState getTemperatureState() { + // double scaledStorage = (double)storedEnergy / (double)maxEnergy; + double scaledHeat = (double) heat / (double) maxHeat; + + if (scaledHeat < 0.20) + return TemperatureState.COOL; + else if (scaledHeat < 0.45) + return TemperatureState.WARMED_UP; + else if (scaledHeat < 0.65) + return TemperatureState.OPERATING_TEMPERATURE; + else if (scaledHeat < 0.85) + return TemperatureState.RUNNING_HOT; + else if (scaledHeat < 1.0) + return TemperatureState.OVERHEATING; + else + return TemperatureState.MELTING; + } + + /** + * Piston speed + * + * @return + */ + public float getPistonSpeed() { + switch (getTemperatureState()) { + case COOL: + return 0.03f; + case WARMED_UP: + return 0.04f; + case OPERATING_TEMPERATURE: + return 0.05f; + case RUNNING_HOT: + return 0.06f; + case OVERHEATING: + return 0.07f; + case MELTING: + return Defaults.ENGINE_PISTON_SPEED_MAX; + default: + return 0; + } + } + + /* SAVING & LOADING */ + @Override + public void readFromNBT(NBTTagCompound nbt) { + super.readFromNBT(nbt); + + heat = nbt.getInteger("EngineHeat"); + if (nbt.hasKey("EngineStoredEnergy")) + storedEnergy = nbt.getInteger("EngineStoredEnergy"); + else + storedEnergy = nbt.getFloat("EngineStored"); + + progress = nbt.getFloat("EngineProgress"); + forceCooldown = nbt.getBoolean("ForceCooldown"); + } + + @Override + public void writeToNBT(NBTTagCompound nbt) { + super.writeToNBT(nbt); + + nbt.setInteger("EngineHeat", heat); + nbt.setFloat("EngineStored", storedEnergy); + nbt.setFloat("EngineProgress", progress); + nbt.setBoolean("ForceCooldown", forceCooldown); + } + + /* SMP GUI */ + public abstract void getGUINetworkData(int i, int j); + + public abstract void sendGUINetworkData(Container containerEngine, ICrafting iCrafting); + + /* IPOWERRECEPTOR */ + @Override + public PowerReceiver getPowerReceiver(ForgeDirection side) { + return powerProvider.getPowerReceiver(); + } + + @Override + public PowerHandler getPowerHandler() { + return powerProvider; + } + + @Override + public void doWork(PowerHandler workProvider) { + if (!Proxies.common.isSimulating(worldObj)) + return; + + addEnergy((int) (PluginBuildCraft.instance.invokeUseEnergyMethod(workProvider, 1, maxEnergyReceived(), true) * 0.95F)); + } + + /* IPIPECONNECTION */ + @Override + public ConnectOverride overridePipeConnection(PipeType type, ForgeDirection with) { + if (type == PipeType.POWER) + return ConnectOverride.DEFAULT; + if (with == getOrientation()) + return ConnectOverride.DISCONNECT; + return ConnectOverride.DEFAULT; + } + + /* IPOWEREMITTER */ + @Override + public boolean canEmitPowerFrom(ForgeDirection side) { + return side == getOrientation(); + } +} diff --git a/forestry_common/core/forestry/core/gadgets/IStructureBlockItem.java b/forestry_common/core/forestry/core/gadgets/IStructureBlockItem.java new file mode 100755 index 000000000..391ca34c2 --- /dev/null +++ b/forestry_common/core/forestry/core/gadgets/IStructureBlockItem.java @@ -0,0 +1,16 @@ +/******************************************************************************* + * Copyright 2011-2014 by SirSengir + * + * This work is licensed under a Creative Commons Attribution-NonCommercial-NoDerivs 3.0 Unported License. + * + * To view a copy of this license, visit http://creativecommons.org/licenses/by-nc-nd/3.0/. + ******************************************************************************/ +package forestry.core.gadgets; + +/** + * + * @author CovertJaguar + */ +public interface IStructureBlockItem { + +} diff --git a/forestry_common/core/forestry/core/gadgets/MachineDefinition.java b/forestry_common/core/forestry/core/gadgets/MachineDefinition.java new file mode 100755 index 000000000..bab2d3ba6 --- /dev/null +++ b/forestry_common/core/forestry/core/gadgets/MachineDefinition.java @@ -0,0 +1,204 @@ +/******************************************************************************* + * Copyright 2011-2014 by SirSengir + * + * This work is licensed under a Creative Commons Attribution-NonCommercial-NoDerivs 3.0 Unported License. + * + * To view a copy of this license, visit http://creativecommons.org/licenses/by-nc-nd/3.0/. + ******************************************************************************/ +package forestry.core.gadgets; + +import java.util.ArrayList; +import java.util.List; +import java.util.Locale; + +import net.minecraft.block.Block; +import net.minecraft.client.renderer.texture.IIconRegister; +import net.minecraft.creativetab.CreativeTabs; +import net.minecraft.entity.player.EntityPlayer; +import net.minecraft.item.Item; +import net.minecraft.item.ItemStack; +import net.minecraft.item.crafting.CraftingManager; +import net.minecraft.item.crafting.IRecipe; +import net.minecraft.tileentity.TileEntity; +import net.minecraft.util.IIcon; +import net.minecraft.world.IBlockAccess; +import net.minecraft.world.World; + +import cpw.mods.fml.common.registry.GameRegistry; +import cpw.mods.fml.relauncher.Side; +import cpw.mods.fml.relauncher.SideOnly; + +import net.minecraftforge.common.util.ForgeDirection; + +import forestry.core.interfaces.IBlockRenderer; +import forestry.core.proxy.Proxies; +import forestry.core.render.TextureManager; + +/** + * This will replace the whole {@link Gadget}-nonsense at some point, using the proper Forge hook. Will hopefully sort out any issues with interfaces. + */ +public class MachineDefinition { + + public final Class teClass; + + public final String teIdent; + public Block block; + public final int meta; + + public final IBlockRenderer renderer; + + /* CRAFTING */ + public IRecipe[] recipes; + + public MachineDefinition(int meta, String teIdent, Class teClass, IRecipe... recipes) { + this(meta, teIdent, teClass, null, recipes); + } + + public MachineDefinition(int meta, String teIdent, Class teClass, IBlockRenderer renderer, IRecipe... recipes) { + this.meta = meta; + this.teIdent = teIdent; + this.teClass = teClass; + this.renderer = renderer; + + this.recipes = recipes; + + this.faceMap = new int[8]; + for (int i = 0; i < 8; i++) + faceMap[i] = 0; + + } + + public void setBlock(Block block) { + this.block = block; + } + + public void register() { + registerTileEntity(); + registerCrafting(); + if (renderer != null) + Proxies.render.registerTESR(this); + } + + @SuppressWarnings("unchecked") + private void registerCrafting() { + for (IRecipe recipe : recipes) + if(recipe != null) + CraftingManager.getInstance().getRecipeList().add(recipe); + } + + /** + * Registers the tile entity with MC. + */ + private void registerTileEntity() { + GameRegistry.registerTileEntity(teClass, teIdent); + } + + public TileEntity createMachine() { + try { + return teClass.getConstructor().newInstance(); + } catch (Exception ex) { + throw new RuntimeException("Failed to instantiate tile entity of class " + teClass.getName()); + } + } + + @SuppressWarnings({ "rawtypes", "unchecked" }) + public void getSubBlocks(Item item, CreativeTabs tab, List list) { + list.add(new ItemStack(item, 1, meta)); + } + + /* BLOCK DROPS */ + public boolean handlesDrops() { + return false; + } + + public ArrayList getDrops(World world, int x, int y, int z, int metadata, int fortune) { + return new ArrayList(); + } + + /* INTERACTION */ + public boolean isSolidOnSide(IBlockAccess world, int x, int y, int z, int side) { + return true; + } + + public boolean onBlockActivated(World world, int x, int y, int z, EntityPlayer player, int side, float fXplayerClick, float fY, float fZ) { + return false; + } + + public void onBlockAdded(World world, int x, int y, int z) { + } + + public boolean removedByPlayer(World world, EntityPlayer player, int x, int y, int z) { + return true; + } + + public boolean canConnectRedstone(IBlockAccess world, int x, int y, int z, int side) { + return false; + } + + public boolean rotateBlock(World world, int x, int y, int z, ForgeDirection axis) { + return false; + } + + /* TEXTURES */ + private final int[] faceMap; + + public MachineDefinition setFaces(int... faces) { + + if (faces.length > 6) + for (int i = 0; i < faces.length; i++) + faceMap[i] = faces[i]; + else { + for (int i = 0; i < 6; i++) + faceMap[i] = faces[i]; + faceMap[6] = faces[0]; + faceMap[7] = faces[1]; + } + + return this; + } + + @SideOnly(Side.CLIENT) + private IIcon[] icons; + + @SideOnly(Side.CLIENT) + public void registerIcons(IIconRegister register) { + icons = new IIcon[8]; + + for (int i = 0; i < 8; i++) + icons[i] = TextureManager.getInstance().registerTex(register, teIdent.replace("forestry.", "").toLowerCase(Locale.ENGLISH) + "." + faceMap[i]); + } + + @SideOnly(Side.CLIENT) + public IIcon getBlockTextureFromSideAndMetadata(int side, int metadata) { + return icons[side]; + } + + /** + * 0 - Bottom 1 - Top 2 - Back 3 - Front 4,5 - Sides, 7 - Reversed ?, 8 - Reversed ? + */ + @SideOnly(Side.CLIENT) + public IIcon getIcon(IBlockAccess world, int x, int y, int z, int side, int metadata) { + + TileEntity tile = world.getTileEntity(x, y, z); + if (!(tile instanceof TileForestry)) + return getBlockTextureFromSideAndMetadata(side, metadata); + + ForgeDirection dir = ((TileForestry) tile).getOrientation(); + switch (dir) { + case WEST: + side = side == 2 ? 4 : side == 3 ? 5 : side == 4 ? 3 : side == 5 ? 2 : side == 0 ? 6 : 7; + break; + case EAST: + side = side == 2 ? 5 : side == 3 ? 4 : side == 4 ? 2 : side == 5 ? 3 : side == 0 ? 6 : 7; + break; + case SOUTH: + break; + case NORTH: + side = side == 2 ? 3 : side == 3 ? 2 : side == 4 ? 5 : side == 5 ? 4 : side; + break; + default: + } + + return getBlockTextureFromSideAndMetadata(side, metadata); + } +} diff --git a/forestry_common/core/forestry/core/gadgets/MachineNBTDefinition.java b/forestry_common/core/forestry/core/gadgets/MachineNBTDefinition.java new file mode 100755 index 000000000..998cad07f --- /dev/null +++ b/forestry_common/core/forestry/core/gadgets/MachineNBTDefinition.java @@ -0,0 +1,56 @@ +/******************************************************************************* + * Copyright 2011-2014 by SirSengir + * + * This work is licensed under a Creative Commons Attribution-NonCommercial-NoDerivs 3.0 Unported License. + * + * To view a copy of this license, visit http://creativecommons.org/licenses/by-nc-nd/3.0/. + ******************************************************************************/ +package forestry.core.gadgets; + +import net.minecraft.entity.player.EntityPlayer; +import net.minecraft.item.ItemStack; +import net.minecraft.item.crafting.IRecipe; +import net.minecraft.nbt.NBTTagCompound; +import net.minecraft.tileentity.TileEntity; +import net.minecraft.world.World; + +import forestry.core.interfaces.IBlockRenderer; +import forestry.core.proxy.Proxies; +import forestry.core.utils.StackUtils; +import forestry.core.utils.Utils; + +public class MachineNBTDefinition extends MachineDefinition { + + public MachineNBTDefinition(int meta, String teIdent, Class teClass, IRecipe... recipes) { + super(meta, teIdent, teClass, recipes); + } + + public MachineNBTDefinition(int meta, String teIdent, Class teClass, IBlockRenderer renderer, IRecipe... recipes) { + super(meta, teIdent, teClass, renderer, recipes); + } + + /* BLOCK DROPS */ + @Override + public boolean handlesDrops() { + return true; + } + + /* INTERACTION */ + @Override + public boolean removedByPlayer(World world, EntityPlayer player, int x, int y, int z) { + int meta = world.getBlockMetadata(x, y, z); + if (Proxies.common.isSimulating(world) && block.canHarvestBlock(player, meta)) { + TileForestry tile = (TileForestry)world.getTileEntity(x, y, z); + Utils.dropInventory(tile, world, x, y, z); + + ItemStack stack = new ItemStack(block, 1, meta); + NBTTagCompound compound = new NBTTagCompound(); + tile.writeToNBT(compound); + stack.setTagCompound(compound); + StackUtils.dropItemStackAsEntity(stack, world, x, y, z); + } + + return world.setBlockToAir(x, y, z); + } + +} diff --git a/forestry_common/core/forestry/core/gadgets/Mill.java b/forestry_common/core/forestry/core/gadgets/Mill.java new file mode 100755 index 000000000..162960a34 --- /dev/null +++ b/forestry_common/core/forestry/core/gadgets/Mill.java @@ -0,0 +1,81 @@ +/******************************************************************************* + * Copyright 2011-2014 by SirSengir + * + * This work is licensed under a Creative Commons Attribution-NonCommercial-NoDerivs 3.0 Unported License. + * + * To view a copy of this license, visit http://creativecommons.org/licenses/by-nc-nd/3.0/. + ******************************************************************************/ +package forestry.core.gadgets; + +import forestry.core.network.EntityNetData; + +public abstract class Mill extends TilePowered { + + @EntityNetData + public int charge = 0; + @EntityNetData + public float speed; + @EntityNetData + public int stage = 0; + public float progress; + + public Mill() { + speed = 0.01F; + } + + @Override + public void updateClientSide() { + update(false); + } + + @Override + public void updateServerSide() { + update(true); + } + + private void update(boolean isSimulating) { + + // Stop gracefully if discharged. + if (charge <= 0) { + if (stage > 0) + progress += speed; + if (progress > 0.5) + stage = 2; + if (progress > 1) { + progress = 0; + stage = 0; + } + return; + } + + // Update blades + progress += speed; + if (stage <= 0) + stage = 1; + + if (progress > 0.5 && stage == 1) { + stage = 2; + if (charge < 7 && isSimulating) { + charge++; + sendNetworkUpdate(); + } + } + if (progress > 1) { + progress = 0; + stage = 0; + + // Fully charged! Do something! + if (charge >= 7) + activate(); + } + + } + + protected abstract void activate(); + + @Override + public boolean isWorking() { + return charge != 0; + } + +} diff --git a/forestry_common/core/forestry/core/gadgets/NaturalistGame.java b/forestry_common/core/forestry/core/gadgets/NaturalistGame.java new file mode 100755 index 000000000..7cfe97562 --- /dev/null +++ b/forestry_common/core/forestry/core/gadgets/NaturalistGame.java @@ -0,0 +1,411 @@ +/******************************************************************************* + * Copyright 2011-2014 by SirSengir + * + * This work is licensed under a Creative Commons Attribution-NonCommercial-NoDerivs 3.0 Unported License. + * + * To view a copy of this license, visit http://creativecommons.org/licenses/by-nc-nd/3.0/. + ******************************************************************************/ +package forestry.core.gadgets; + +import java.util.ArrayList; +import java.util.Collection; +import java.util.Random; + +import net.minecraft.inventory.IInventory; +import net.minecraft.item.ItemStack; +import net.minecraft.nbt.NBTTagCompound; +import net.minecraft.nbt.NBTTagList; + +import forestry.api.core.INBTTagable; +import forestry.api.genetics.AlleleManager; +import forestry.api.genetics.IIndividual; +import forestry.api.genetics.ISpeciesRoot; +import forestry.core.utils.StringUtil; +import forestry.core.utils.Utils; + +public class NaturalistGame implements INBTTagable { + + public static final int BOUNTY_MAX = 16; + + public static class GameToken implements INBTTagable { + + private static final String[] OVERLAY_NONE = new String[0]; + private static final String[] OVERLAY_FAILED = new String[] { "errors/errored" }; + + public ItemStack tokenStack; + + protected boolean isFailed = false; + protected boolean isProbed = false; + protected boolean isRevealed = false; + + public GameToken(ItemStack tokenStack) { + this.tokenStack = tokenStack; + } + + public GameToken(NBTTagCompound nbttagcompound) { + readFromNBT(nbttagcompound); + } + + @Override + public void readFromNBT(NBTTagCompound nbttagcompound) { + isFailed = nbttagcompound.getBoolean("isFailed"); + isProbed = nbttagcompound.getBoolean("isProbed"); + isRevealed = nbttagcompound.getBoolean("isRevealed"); + + if(nbttagcompound.hasKey("tokenStack")) { + tokenStack = ItemStack.loadItemStackFromNBT(nbttagcompound.getCompoundTag("tokenStack")); + } + } + + @Override + public void writeToNBT(NBTTagCompound nbttagcompound) { + nbttagcompound.setBoolean("isFailed", isFailed); + nbttagcompound.setBoolean("isProbed", isProbed); + nbttagcompound.setBoolean("isRevealed", isRevealed); + + if(tokenStack != null) { + NBTTagCompound stackcompound = new NBTTagCompound(); + tokenStack.writeToNBT(stackcompound); + nbttagcompound.setTag("tokenStack", stackcompound); + } + } + + public boolean isVisible() { + return isRevealed; + } + + public int getTokenColour() { + if(tokenStack == null || !isVisible()) + return 0xffffff; + + if(isProbed) + return Utils.multiplyRGBComponents(AlleleManager.alleleRegistry.getIndividual(tokenStack).getGenome().getPrimary().getIconColour(0), 0.7f); + else + return AlleleManager.alleleRegistry.getIndividual(tokenStack).getGenome().getPrimary().getIconColour(0); + } + + public String getTooltip() { + return tokenStack != null ? tokenStack.getDisplayName() : StringUtil.localize("gui.unknown"); + } + + public String[] getOverlayIcons() { + return isFailed ? OVERLAY_FAILED : OVERLAY_NONE; + } + + public boolean matches(GameToken other) { + return tokenStack.isItemEqual(other.tokenStack) && ItemStack.areItemStackTagsEqual(tokenStack, other.tokenStack); + } + } + + private final Random rand = new Random(); + private GameToken[] gameTokens; + private long lastUpdate; + + private boolean isEnded; + private int bountyLevel; + + public long getLastUpdate() { + return lastUpdate; + } + + /* SAVING & LOADING */ + @Override + public void writeToNBT(NBTTagCompound nbttagcompound) { + nbttagcompound.setBoolean("isEnded", isEnded); + nbttagcompound.setInteger("bountyLevel", bountyLevel); + nbttagcompound.setLong("lastUpdate", lastUpdate); + + if(gameTokens != null) { + nbttagcompound.setInteger("TokenCount", gameTokens.length); + NBTTagList nbttaglist = new NBTTagList(); + + for (int i = 0; i < gameTokens.length; i++) { + if(gameTokens[i] == null) + continue; + + NBTTagCompound nbttagcompound2 = new NBTTagCompound(); + nbttagcompound2.setByte("Slot", (byte) i); + gameTokens[i].writeToNBT(nbttagcompound2); + nbttaglist.appendTag(nbttagcompound2); + } + + nbttagcompound.setTag("GameTokens", nbttaglist); + } else + nbttagcompound.setInteger("TokenCount", 0); + + } + + @Override + public void readFromNBT(NBTTagCompound nbttagcompound) { + isEnded = nbttagcompound.getBoolean("isEnded"); + bountyLevel = nbttagcompound.getInteger("bountyLevel"); + lastUpdate = nbttagcompound.getLong("lastUpdate"); + + int tokenCount = nbttagcompound.getInteger("TokenCount"); + if(tokenCount > 0) { + gameTokens = new GameToken[tokenCount]; + NBTTagList nbttaglist = nbttagcompound.getTagList("GameTokens", 10); + + for (int j = 0; j < nbttaglist.tagCount(); ++j) { + NBTTagCompound nbttagcompound2 = nbttaglist.getCompoundTagAt(j); + int index = nbttagcompound2.getByte("Slot"); + gameTokens[index] = new GameToken(nbttagcompound2); + } + } + + lastUpdate = System.currentTimeMillis(); + } + + /* INTERACTION */ + public void initialize(ItemStack specimen) { + IIndividual individual = AlleleManager.alleleRegistry.getIndividual(specimen); + if(individual == null) { + return; + } + + int boardSize = individual.getGenome().getPrimary().getComplexity() + individual.getGenome().getSecondary().getComplexity(); + if(boardSize % 2 != 0) + boardSize = Math.round((float)boardSize / 2) * 2; + boardSize = boardSize <= 22 ? boardSize >= 6 ? boardSize : 6 : 22; + + isEnded = false; + bountyLevel = BOUNTY_MAX; + gameTokens = new GameToken[boardSize]; + + ISpeciesRoot root = individual.getGenome().getPrimary().getRoot(); + ArrayList pairs = new ArrayList(); + for(int i = 0; i < boardSize / 2; i++) { + IIndividual token = root.templateAsIndividual(root.getRandomTemplate(rand)); + pairs.add(root.getMemberStack(token, 0)); + } + + boolean first = true; + for(ItemStack pair : pairs) { + if(first) { + gameTokens[0] = new GameToken(pair.copy()); + first = false; + } else + gameTokens[getFreeTokenIndex()] = new GameToken(pair.copy()); + gameTokens[getFreeTokenIndex()] = new GameToken(pair.copy()); + } + + lastUpdate = System.currentTimeMillis(); + } + + private int getFreeTokenIndex() { + while(true) { + int probe = rand.nextInt(gameTokens.length); + if(gameTokens[probe] == null) + return probe; + } + } + + private int countUnrevealedTokens() { + int count = 0; + for(GameToken token : gameTokens) + if(!token.isRevealed) + count++; + + return count; + } + + private int[] getUnrevealedTokens(int count) { + ArrayList existing = new ArrayList(); + int remaining = countUnrevealedTokens(); + int[] unrevealed = new int[count < remaining ? count : remaining]; + + for(int i = 0; i < unrevealed.length; i++) { + + int found = -1; + while(found < 0) { + int probe = rand.nextInt(gameTokens.length); + if(gameTokens[probe].isRevealed) + continue; + + boolean taken = false; + for(int exist : existing) { + if(exist == probe) { + taken = true; + break; + } + } + if(!taken) { + existing.add(probe); + found = probe; + } + } + unrevealed[i] = found; + } + + return unrevealed; + } + + public void probe(ItemStack specimen, IInventory inventory, int startSlot, int slotCount) { + if(gameTokens == null) + return; + if(isEnded) + return; + IIndividual individual = AlleleManager.alleleRegistry.getIndividual(specimen); + if(individual == null) + return; + + hideProbedTokens(); + if(bountyLevel > 1) + bountyLevel--; + + int[] tokenIndices = getUnrevealedTokens(getSampleSize() <= slotCount ? getSampleSize() : slotCount); + int processedTokens = 0; + + for(int i = 0; i < slotCount; i++) { + ItemStack sample = inventory.getStackInSlot(startSlot + i); + if(sample == null || sample.stackSize <= 0) + continue; + + sample = inventory.decrStackSize(startSlot + i, 1); + if(rand.nextFloat() >= individual.getGenome().getPrimary().getResearchSuitability(sample)) { + continue; + } + + gameTokens[tokenIndices[processedTokens]].isProbed = true; + gameTokens[tokenIndices[processedTokens]].isRevealed = true; + + processedTokens++; + if(processedTokens >= tokenIndices.length) + break; + } + + lastUpdate = System.currentTimeMillis(); + } + + public void choose(int tokenIndex) { + if(isEnded) + return; + if(gameTokens == null || tokenIndex >= gameTokens.length) + return; + if(gameTokens[tokenIndex].isRevealed && !gameTokens[tokenIndex].isProbed) + return; + hideProbedTokens(); + + Collection singles = getRevealedSingles(gameTokens[tokenIndex]); + if(singles.size() > 0) { + boolean matched = false; + for(GameToken single : singles) { + if(single.matches(gameTokens[tokenIndex])) { + matched = true; + break; + } + } + if(!matched) { + gameTokens[tokenIndex].isFailed = true; + } + } + gameTokens[tokenIndex].isRevealed = true; + checkGameEnd(); + lastUpdate = System.currentTimeMillis(); + } + + public void reset() { + gameTokens = null; + lastUpdate = System.currentTimeMillis(); + } + + public boolean isInited() { + return gameTokens != null; + } + + public boolean isEnded() { + return isEnded; + } + + public int getBountyLevel() { + return bountyLevel; + } + + public boolean isWon() { + if(!isEnded) + return false; + + return !isLost(); + } + + private void checkGameEnd() { + if(isLost()) + isEnded = true; + if(isRevealed()) + isEnded = true; + } + + private boolean isRevealed() { + for(GameToken token : gameTokens) + if(!token.isRevealed) + return false; + + return true; + } + private boolean isLost() { + for(GameToken token : gameTokens) { + if(token.isFailed) + return true; + } + + return false; + } + + private void hideProbedTokens() { + for(GameToken token : gameTokens) { + if(token.isProbed) { + token.isRevealed = false; + token.isProbed = false; + } + } + } + + private Collection getRevealedSingles(GameToken exclude) { + ArrayList singles = new ArrayList(); + + for(GameToken token : gameTokens) { + if(!token.isRevealed) + continue; + if(token == exclude) + continue; + + GameToken matching = null; + for(GameToken single : singles) { + if(!single.matches(token)) + continue; + matching = single; + break; + } + + if(matching == null) + singles.add(token); + else + singles.remove(matching); + } + + return singles; + } + + /* RETRIEVAL */ + public int getBoardSize() { + return gameTokens != null ? gameTokens.length : 0; + } + + public int getSampleSize() { + if(gameTokens == null) + return 0; + + int samples = gameTokens.length / 4; + return samples >= 2 ? samples : 2; + } + + public GameToken getToken(int index) { + return gameTokens != null ? index < gameTokens.length ? gameTokens[index] : null : null; + } + + public void setToken(int index, NBTTagCompound nbttagcompound) { + if(gameTokens == null) + gameTokens = new GameToken[24]; + gameTokens[index] = new GameToken(nbttagcompound); + } +} diff --git a/forestry_common/core/forestry/core/gadgets/StructureLogic.java b/forestry_common/core/forestry/core/gadgets/StructureLogic.java new file mode 100755 index 000000000..fbbed1424 --- /dev/null +++ b/forestry_common/core/forestry/core/gadgets/StructureLogic.java @@ -0,0 +1,181 @@ +/******************************************************************************* + * Copyright 2011-2014 by SirSengir + * + * This work is licensed under a Creative Commons Attribution-NonCommercial-NoDerivs 3.0 Unported License. + * + * To view a copy of this license, visit http://creativecommons.org/licenses/by-nc-nd/3.0/. + ******************************************************************************/ +package forestry.core.gadgets; + +import java.util.HashMap; + +import net.minecraft.nbt.NBTTagCompound; +import net.minecraft.tileentity.TileEntity; + +import forestry.api.core.IStructureLogic; +import forestry.api.core.ITileStructure; +import forestry.core.config.Defaults; +import forestry.core.gadgets.BlockStructure.EnumStructureState; +import forestry.core.utils.Schemata; +import forestry.core.utils.Schemata.EnumStructureBlock; +import forestry.core.utils.Vect; + +public abstract class StructureLogic implements IStructureLogic { + + protected ITileStructure structure; + protected TileEntity structureTile; + + protected String uid; + protected Schemata[] schematas; + protected short activeSchemata = -1; + protected boolean isRotated = false; + protected HashMap metaOnValid = new HashMap(); + + public StructureLogic(String uid, ITileStructure structure) { + this.uid = uid; + this.structure = structure; + this.structureTile = (TileEntity) structure; + } + + @Override + public String getTypeUID() { + return uid; + } + + @Override + public void readFromNBT(NBTTagCompound nbttagcompound) { + if (nbttagcompound.hasKey("SchemataOrdinal")) + activeSchemata = nbttagcompound.getShort("SchemataOrdinal"); + isRotated = nbttagcompound.getBoolean("Rotated"); + } + + @Override + public void writeToNBT(NBTTagCompound nbttagcompound) { + if (activeSchemata >= 0) + nbttagcompound.setShort("SchemataOrdinal", activeSchemata); + nbttagcompound.setBoolean("Rotated", isRotated); + } + + @Override + public void validateStructure() { + + ITileStructure master = structure.getCentralTE(); + if (!structure.isMaster() && master != null) { + master.validateStructure(); + return; + } + + EnumStructureState state = EnumStructureState.INDETERMINATE; + + boolean rotate = false; + for (int i = 0; i < schematas.length; i++) { + if (!schematas[i].isEnabled()) + continue; + + state = determineMasterState(schematas[i], false); + rotate = false; + if (state == EnumStructureState.INVALID && schematas[i].getWidth() != schematas[i].getDepth()) { + state = determineMasterState(schematas[i], true); + rotate = true; + } + + if (state == EnumStructureState.VALID) { + activeSchemata = (short) i; + isRotated = rotate; + break; + } + + } + + // Structure state is indeterminate, possibly caused by chunkloading. Remain calm, do nothing. + if (state == EnumStructureState.INDETERMINATE) + return; + + if (state == EnumStructureState.VALID) { + // Structure is valid and this block is master, set all other blocks + // System.out.println(String.format("Structure is valid at %s/%s/%s", ((TileEntity)structure).xCoord, ((TileEntity)structure).yCoord, + // ((TileEntity)structure).zCoord)); + if (!structure.isMaster()) { + structure.makeMaster(); + markStructureBlocks(schematas[activeSchemata]); + } + + /* + * int offsetX = schematas[activeSchemata].getxOffset(); int offsetZ = schematas[activeSchemata].getzOffset(); if(isRotated) { offsetX = + * schematas[activeSchemata].getzOffset(); offsetZ = schematas[activeSchemata].getxOffset(); + * + * } + */ + // System.out.println(String.format("Offsets: %s and %s.", offsetX, offsetZ)); + + } else if (structure.isMaster()) + // Structure is invalid, break it up. + resetStructureBlocks(schematas[activeSchemata]); + } + + protected void resetStructureBlocks(Schemata schemata) { + + Vect dimensions = schemata.getDimensions(isRotated); + int offsetX = schemata.getxOffset(); + int offsetZ = schemata.getzOffset(); + if (isRotated) { + offsetX = schemata.getzOffset(); + offsetZ = schemata.getxOffset(); + } + + for (int i = 0; i < dimensions.x; i++) + for (int j = 0; j < schemata.getHeight(); j++) + for (int k = 0; k < dimensions.z; k++) { + int x = structureTile.xCoord + i + offsetX; + int y = structureTile.yCoord + j + schemata.getyOffset(); + int z = structureTile.zCoord + k + offsetZ; + + TileEntity tile = structureTile.getWorldObj().getTileEntity(x, y, z); + if (!(tile instanceof ITileStructure)) + continue; + + ITileStructure part = (ITileStructure) tile; + if (!part.getTypeUID().equals(getTypeUID())) + continue; + + part.onStructureReset(); + } + } + + protected void markStructureBlocks(Schemata schemata) { + + Vect dimensions = schemata.getDimensions(isRotated); + int offsetX = schemata.getxOffset(); + int offsetZ = schemata.getzOffset(); + if (isRotated) { + offsetX = schemata.getzOffset(); + offsetZ = schemata.getxOffset(); + } + + for (int i = 0; i < dimensions.x; i++) + for (int j = 0; j < schemata.getHeight(); j++) + for (int k = 0; k < dimensions.z; k++) { + int x = structureTile.xCoord + i + offsetX; + int y = structureTile.yCoord + j + schemata.getyOffset(); + int z = structureTile.zCoord + k + offsetZ; + + TileEntity tile = structureTile.getWorldObj().getTileEntity(x, y, z); + if (!(tile instanceof ITileStructure)) + continue; + + ITileStructure part = (ITileStructure) tile; + if (!part.getTypeUID().equals(getTypeUID())) + continue; + + part.setCentralTE((TileEntity) structure); + EnumStructureBlock type = schemata.getAt(i, j, k, isRotated); + if (metaOnValid.containsKey(type)) { + structureTile.getWorldObj().setBlockMetadataWithNotify(x, y, z, metaOnValid.get(type), Defaults.FLAG_BLOCK_SYNCH); + structureTile.getWorldObj().markBlockForUpdate(x, y, z); + } + } + } + + protected abstract EnumStructureState determineMasterState(Schemata schemata, boolean rotate); + +} diff --git a/forestry_common/core/forestry/core/gadgets/TileAnalyzer.java b/forestry_common/core/forestry/core/gadgets/TileAnalyzer.java new file mode 100755 index 000000000..f8aedcea1 --- /dev/null +++ b/forestry_common/core/forestry/core/gadgets/TileAnalyzer.java @@ -0,0 +1,453 @@ +/******************************************************************************* + * Copyright 2011-2014 by SirSengir + * + * This work is licensed under a Creative Commons Attribution-NonCommercial-NoDerivs 3.0 Unported License. + * + * To view a copy of this license, visit http://creativecommons.org/licenses/by-nc-nd/3.0/. + ******************************************************************************/ +package forestry.core.gadgets; + +import java.util.Stack; + +import net.minecraft.entity.player.EntityPlayer; +import net.minecraft.inventory.Container; +import net.minecraft.inventory.ICrafting; +import net.minecraft.inventory.ISidedInventory; +import net.minecraft.item.ItemStack; +import net.minecraft.nbt.NBTTagCompound; +import net.minecraft.nbt.NBTTagList; +import net.minecraft.network.Packet; + +import net.minecraftforge.common.util.ForgeDirection; +import net.minecraftforge.fluids.FluidContainerRegistry.FluidContainerData; +import net.minecraftforge.fluids.FluidRegistry; +import net.minecraftforge.fluids.FluidStack; + +import buildcraft.api.inventory.ISpecialInventory; + +import forestry.api.core.ForestryAPI; +import forestry.api.genetics.AlleleManager; +import forestry.api.genetics.IIndividual; +import forestry.core.EnumErrorCode; +import forestry.core.config.Defaults; +import forestry.core.interfaces.ILiquidTankContainer; +import forestry.core.network.EntityNetData; +import forestry.core.network.GuiId; +import forestry.core.network.PacketIds; +import forestry.core.network.PacketInventoryStack; +import forestry.core.proxy.Proxies; +import forestry.core.utils.ForestryTank; +import forestry.core.utils.InventoryAdapter; +import forestry.core.utils.LiquidHelper; +import forestry.core.utils.StackUtils; +import forestry.core.utils.StringUtil; + +public class TileAnalyzer extends TileBase implements ISpecialInventory, ISidedInventory, ILiquidTankContainer { + + /* CONSTANTS */ + public static final int TIME_TO_ANALYZE = 500; + public static final int HONEY_REQUIRED = 100; + + public static final short SLOT_ANALYZE = 0; + public static final short SLOT_CAN = 1; + public static final short SLOT_INPUT_1 = 2; + public static final short SLOT_OUTPUT_1 = 8; + + /* MEMBER */ + private final InventoryAdapter inventory = new InventoryAdapter(12, "Items"); + + private int analyzeTime; + + private final short analyzeSlot = 0; + private final short canSlot = 1; + private final short inputSlot1 = 2; + private final short outputSlot1 = 8; + + public FluidStack resource = FluidRegistry.getFluidStack(Defaults.LIQUID_HONEY, HONEY_REQUIRED); + @EntityNetData + public ForestryTank resourceTank = new ForestryTank(Defaults.PROCESSOR_TANK_CAPACITY); + private final Stack pendingProducts = new Stack(); + + /* CONSTRUCTOR */ + public TileAnalyzer() { + } + + @Override + public String getInventoryName() { + return StringUtil.localize("core.0"); + } + + /* GUI */ + @Override + public void openGui(EntityPlayer player, TileBase tile) { + player.openGui(ForestryAPI.instance, GuiId.AnalyzerGUI.ordinal(), player.worldObj, xCoord, yCoord, zCoord); + } + + /* SAVING & LOADING */ + @Override + public void writeToNBT(NBTTagCompound nbttagcompound) { + super.writeToNBT(nbttagcompound); + + nbttagcompound.setInteger("AnalyzeTime", analyzeTime); + + // / Resource tank + resourceTank.writeToNBT(nbttagcompound); + + // / Pending Products + NBTTagList nbttaglist = new NBTTagList(); + ItemStack[] pending = pendingProducts.toArray(new ItemStack[pendingProducts.size()]); + for (int i = 0; i < pending.length; i++) + if (pending[i] != null) { + NBTTagCompound nbttagcompound1 = new NBTTagCompound(); + nbttagcompound1.setByte("Slot", (byte) i); + pending[i].writeToNBT(nbttagcompound1); + nbttaglist.appendTag(nbttagcompound1); + } + nbttagcompound.setTag("PendingProducts", nbttaglist); + + // / Inventory + inventory.writeToNBT(nbttagcompound); + } + + @Override + public void readFromNBT(NBTTagCompound nbttagcompound) { + super.readFromNBT(nbttagcompound); + + analyzeTime = nbttagcompound.getInteger("AnalyzeTime"); + + // / Resource tank + resourceTank.readFromNBT(nbttagcompound); + + // / Pending Products + NBTTagList nbttaglist = nbttagcompound.getTagList("PendingProducts", 10); + for (int i = 0; i < nbttaglist.tagCount(); i++) { + NBTTagCompound nbttagcompound1 = nbttaglist.getCompoundTagAt(i); + pendingProducts.add(ItemStack.loadItemStackFromNBT(nbttagcompound1)); + } + + // / Inventory + inventory.readFromNBT(nbttagcompound); + } + + /* WORKING */ + @Override + public void updateServerSide() { + // If we add pending products, we skip to the next work cycle. + if (tryAddPending()) + return; + + if (!pendingProducts.isEmpty()) { + setErrorState(EnumErrorCode.NOSPACE); + return; + } + + // Check if we have suitable items waiting in the can slot + if (getStackInSlot(canSlot) != null) { + FluidContainerData container = LiquidHelper.getLiquidContainer(getStackInSlot(canSlot)); + if (container != null && resource.isFluidEqual(container.fluid)) { + + setInventorySlotContents(canSlot, StackUtils.replenishByContainer(this, getStackInSlot(canSlot), container, resourceTank)); + if (getStackInSlot(canSlot).stackSize <= 0) + setInventorySlotContents(canSlot, null); + } + } + + if (analyzeTime > 0 && getStackInSlot(analyzeSlot) != null && AlleleManager.alleleRegistry.isIndividual(getStackInSlot(analyzeSlot))) { + + analyzeTime--; + + // Still not done + if (analyzeTime > 0) { + setErrorState(EnumErrorCode.OK); + return; + } + + // Analyzation is done. + IIndividual individual = AlleleManager.alleleRegistry.getIndividual(getStackInSlot(analyzeSlot)); + // No bee, abort + if (individual == null) + return; + + individual.analyze(); + NBTTagCompound nbttagcompound = new NBTTagCompound(); + individual.writeToNBT(nbttagcompound); + getStackInSlot(analyzeSlot).setTagCompound(nbttagcompound); + + pendingProducts.push(getStackInSlot(analyzeSlot)); + setInventorySlotContents(analyzeSlot, null); + sendNetworkUpdate(); + + } else { + analyzeTime = 0; + + // Don't start if analyze slot already occupied + if (getStackInSlot(analyzeSlot) != null) + return; + + // We need our liquid honey + if (resourceTank.getFluidAmount() < resource.amount) { + setErrorState(EnumErrorCode.NORESOURCE); + return; + } + + // Look for bees in input slots. + for (int i = inputSlot1; i < outputSlot1; i++) { + if (getStackInSlot(i) == null || !AlleleManager.alleleRegistry.isIndividual(getStackInSlot(i))) + continue; + + // Analyzed bees in the input buffer are added to the output + // queue at once. + IIndividual individual = AlleleManager.alleleRegistry.getIndividual(getStackInSlot(i)); + if (individual.isAnalyzed()) { + pendingProducts.push(getStackInSlot(i)); + setInventorySlotContents(i, null); + continue; + } + + setInventorySlotContents(analyzeSlot, getStackInSlot(i)); + setInventorySlotContents(i, null); + resourceTank.drain(resource.amount, true); + analyzeTime = TIME_TO_ANALYZE; + sendNetworkUpdate(); + return; + } + + // Nothing to analyze + setErrorState(EnumErrorCode.NOTHINGANALYZE); + } + } + + private boolean tryAddPending() { + if (pendingProducts.isEmpty()) + return false; + + ItemStack next = pendingProducts.peek(); + if (inventory.tryAddStack(next, outputSlot1, inventory.getSizeInventory() - outputSlot1, true)) { + pendingProducts.pop(); + return true; + } + return false; + } + + /* STATE INFORMATION */ + // @Override + public boolean isWorking() { + return analyzeTime > 0; + } + + public int getProgressScaled(int i) { + return (analyzeTime * i) / TIME_TO_ANALYZE; + } + + public int getResourceScaled(int i) { + return (resourceTank.getFluidAmount() * i) / Defaults.PROCESSOR_TANK_CAPACITY; + } + + public ItemStack getIndividualOnDisplay() { + return getStackInSlot(analyzeSlot); + } + + /* SMP */ + public void getGUINetworkData(int i, int j) { + switch (i) { + case 0: + analyzeTime = j; + break; + } + } + + public void sendGUINetworkData(Container container, ICrafting iCrafting) { + iCrafting.sendProgressBarUpdate(container, 0, analyzeTime); + + } + + @Override + public void sendNetworkUpdate() { + Proxies.net.sendNetworkPacket(new PacketInventoryStack(PacketIds.IINVENTORY_STACK, xCoord, yCoord, zCoord, SLOT_ANALYZE, inventory.getStackInSlot(SLOT_ANALYZE)), + xCoord, yCoord, zCoord); + } + + @Override + public Packet getDescriptionPacket() { + return new PacketInventoryStack(PacketIds.IINVENTORY_STACK, xCoord, yCoord, zCoord, SLOT_ANALYZE, inventory.getStackInSlot(SLOT_ANALYZE)).getPacket(); + } + + /* ISIDEDINVENTORY */ + @Override + public InventoryAdapter getInternalInventory() { + return inventory; + } + + @Override + protected boolean canTakeStackFromSide(int slotIndex, ItemStack itemstack, int side) { + if(!super.canTakeStackFromSide(slotIndex, itemstack, side)) + return false; + + return slotIndex >= SLOT_OUTPUT_1 && slotIndex < SLOT_OUTPUT_1 + 4; + } + + @Override + protected boolean canPutStackFromSide(int slotIndex, ItemStack itemstack, int side) { + + if(!super.canPutStackFromSide(slotIndex, itemstack, side)) + return false; + + if(slotIndex >= SLOT_INPUT_1 && slotIndex < SLOT_INPUT_1 + 6) + return AlleleManager.alleleRegistry.isIndividual(itemstack); + + if(slotIndex == SLOT_CAN) { + FluidContainerData container = LiquidHelper.getLiquidContainer(itemstack); + return container != null && LiquidHelper.isLiquid(Defaults.LIQUID_HONEY, container.fluid); + } + + return false; + } + + @Override public int getSizeInventory() { return inventory.getSizeInventory(); } + @Override public ItemStack getStackInSlot(int i) { return inventory.getStackInSlot(i); } + @Override public ItemStack decrStackSize(int i, int j) { return inventory.decrStackSize(i, j); } + @Override public void setInventorySlotContents(int i, ItemStack itemstack) { inventory.setInventorySlotContents(i, itemstack); } + @Override public int getInventoryStackLimit() { return inventory.getInventoryStackLimit(); } + @Override public ItemStack getStackInSlotOnClosing(int slot) { return inventory.getStackInSlotOnClosing(slot); } + @Override public void openInventory() {} + @Override public void closeInventory() {} + + /** + * TODO: just a specialsource workaround + */ + @Override + public boolean isUseableByPlayer(EntityPlayer player) { + return super.isUseableByPlayer(player); + } + + /** + * TODO: just a specialsource workaround + */ + @Override + public boolean hasCustomInventoryName() { + return super.hasCustomInventoryName(); + } + + /** + * TODO: just a specialsource workaround + */ + @Override + public boolean isItemValidForSlot(int slotIndex, ItemStack itemstack) { + return super.isItemValidForSlot(slotIndex, itemstack); + } + + /** + * TODO: just a specialsource workaround + */ + @Override + public boolean canInsertItem(int i, ItemStack itemstack, int j) { + return super.canInsertItem(i, itemstack, j); + } + + /** + * TODO: just a specialsource workaround + */ + @Override + public boolean canExtractItem(int i, ItemStack itemstack, int j) { + return super.canExtractItem(i, itemstack, j); + } + + /** + * TODO: just a specialsource workaround + */ + @Override + public int[] getAccessibleSlotsFromSide(int side) { + return super.getAccessibleSlotsFromSide(side); + } + + /* ISPECIALINVENTORY */ + @Override + public ItemStack[] extractItem(boolean doRemove, ForgeDirection from, int maxItemCount) { + + ItemStack product = null; + + for (int i = outputSlot1; i < inventory.getSizeInventory(); i++) { + if (inventory.getStackInSlot(i) == null) + continue; + + product = getStackInSlot(i).copy(); + if (doRemove) { + getStackInSlot(i).stackSize = 0; + setInventorySlotContents(i, null); + } + break; + } + return new ItemStack[] { product }; + } + + @Override + public int addItem(ItemStack stack, boolean doAdd, ForgeDirection from) { + + if (!AlleleManager.alleleRegistry.isIndividual(stack)) { + + FluidContainerData container = LiquidHelper.getLiquidContainer(stack); + if (container == null || !container.fluid.isFluidEqual(resource)) + return 0; + + if (getStackInSlot(canSlot) == null) { + if (doAdd) + setInventorySlotContents(canSlot, stack.copy()); + + return stack.stackSize; + } + + int space = getStackInSlot(canSlot).getMaxStackSize() - getStackInSlot(canSlot).stackSize; + if (space <= 0) + return 0; + + if (doAdd) { + getStackInSlot(canSlot).stackSize += stack.stackSize; + if (getStackInSlot(canSlot).stackSize > getStackInSlot(canSlot).getMaxStackSize()) + getStackInSlot(canSlot).stackSize = getStackInSlot(canSlot).getMaxStackSize(); + } + + return space; + } + + for (int i = inputSlot1; i < outputSlot1; i++) + if (getStackInSlot(i) == null) { + if (doAdd) + setInventorySlotContents(i, stack.copy()); + + return stack.stackSize; + } + + return 0; + } + + /* ILIQUIDCONTAINER */ + @Override + public int fill(ForgeDirection from, FluidStack resource, boolean doFill) { + + // We only accept what is already in the tank or valid ingredients + if (resourceTank.getFluidAmount() > 0 && !resourceTank.getFluid().isFluidEqual(resource)) + return 0; + else if (!LiquidHelper.isLiquid(Defaults.LIQUID_HONEY, resource)) + return 0; + + int used = resourceTank.fill(resource, doFill); + + if (doFill && used > 0) + sendNetworkUpdate(); + + return used; + } + + @Override + public ForestryTank[] getTanks() { + return new ForestryTank[] { resourceTank }; + } + + /* + @Override + public ILiquidTank getTank(ForgeDirection direction, LiquidStack type) { + return resourceTank; + } + */ + +} diff --git a/forestry_common/core/forestry/core/gadgets/TileBase.java b/forestry_common/core/forestry/core/gadgets/TileBase.java new file mode 100755 index 000000000..a4181ec18 --- /dev/null +++ b/forestry_common/core/forestry/core/gadgets/TileBase.java @@ -0,0 +1,118 @@ +/******************************************************************************* + * Copyright 2011-2014 by SirSengir + * + * This work is licensed under a Creative Commons Attribution-NonCommercial-NoDerivs 3.0 Unported License. + * + * To view a copy of this license, visit http://creativecommons.org/licenses/by-nc-nd/3.0/. + ******************************************************************************/ +package forestry.core.gadgets; + +import net.minecraft.entity.player.EntityPlayer; + +import forestry.core.interfaces.IHintSource; +import forestry.core.network.ClassMap; +import forestry.core.network.IndexInPayload; +import forestry.core.network.PacketPayload; +import forestry.core.proxy.Proxies; +import forestry.core.utils.Utils; + +public abstract class TileBase extends TileForestry implements IHintSource { + + @Override + public String getInventoryName() { + return null; + } + + @Override + public boolean isOwnable() { + return true; + } + + /* UPDATING */ + @Override + public void initialize() { + } + + @Override + public void updateEntity() { + + super.updateEntity(); + + if (!Proxies.common.isSimulating(worldObj)) + updateClientSide(); + else + updateServerSide(); + } + + protected void updateClientSide() { + } + + protected void updateServerSide() { + } + + /* NETWORK */ + @Override + public PacketPayload getPacketPayload() { + if (!ClassMap.classMappers.containsKey(this.getClass())) + ClassMap.classMappers.put(this.getClass(), new ClassMap(this.getClass())); + + ClassMap classmap = ClassMap.classMappers.get(this.getClass()); + PacketPayload payload = new PacketPayload(classmap.intSize, classmap.floatSize, classmap.stringSize); + + try { + classmap.setData(this, payload.intPayload, payload.floatPayload, payload.stringPayload, new IndexInPayload(0, 0, 0)); + } catch (Exception ex) { + ex.printStackTrace(); + } + + return payload; + } + + @Override + public void fromPacketPayload(PacketPayload payload) { + + if (payload.isEmpty()) + return; + + if (!ClassMap.classMappers.containsKey(this.getClass())) + ClassMap.classMappers.put(this.getClass(), new ClassMap(this.getClass())); + + ClassMap classmap = ClassMap.classMappers.get(this.getClass()); + + try { + classmap.fromData(this, payload.intPayload, payload.floatPayload, payload.stringPayload, new IndexInPayload(0, 0, 0)); + } catch (Exception ex) { + ex.printStackTrace(); + } + } + + /* INTERACTION */ + public void openGui(EntityPlayer player, TileBase tile) { + } + + @Override + public boolean isUseableByPlayer(EntityPlayer player) { + return Utils.isUseableByPlayer(player, this, worldObj, xCoord, yCoord, zCoord); + } + + public boolean canDrainWithBucket() { + return false; + } + + /* IHINTSOURCE */ + private String[] hints; + + public void setHints(String[] hints) { + this.hints = hints; + } + + @Override + public boolean hasHints() { + return hints != null && hints.length > 0; + } + + @Override + public String[] getHints() { + return hints; + } +} diff --git a/forestry_common/core/forestry/core/gadgets/TileEngine.java b/forestry_common/core/forestry/core/gadgets/TileEngine.java new file mode 100755 index 000000000..267651ca4 --- /dev/null +++ b/forestry_common/core/forestry/core/gadgets/TileEngine.java @@ -0,0 +1,11 @@ +/******************************************************************************* + * Copyright 2011-2014 by SirSengir + * + * This work is licensed under a Creative Commons Attribution-NonCommercial-NoDerivs 3.0 Unported License. + * + * To view a copy of this license, visit http://creativecommons.org/licenses/by-nc-nd/3.0/. + ******************************************************************************/ +package forestry.core.gadgets; + +public class TileEngine extends TileMachine { +} diff --git a/forestry_common/core/forestry/core/gadgets/TileEscritoire.java b/forestry_common/core/forestry/core/gadgets/TileEscritoire.java new file mode 100755 index 000000000..ed0662cb5 --- /dev/null +++ b/forestry_common/core/forestry/core/gadgets/TileEscritoire.java @@ -0,0 +1,246 @@ +/******************************************************************************* + * Copyright 2011-2014 by SirSengir + * + * This work is licensed under a Creative Commons Attribution-NonCommercial-NoDerivs 3.0 Unported License. + * + * To view a copy of this license, visit http://creativecommons.org/licenses/by-nc-nd/3.0/. + ******************************************************************************/ +package forestry.core.gadgets; + +import net.minecraft.entity.player.EntityPlayer; +import net.minecraft.inventory.ISidedInventory; +import net.minecraft.item.ItemStack; +import net.minecraft.nbt.NBTTagCompound; + +import forestry.api.core.ForestryAPI; +import forestry.api.genetics.AlleleManager; +import forestry.api.genetics.IIndividual; +import forestry.core.interfaces.ICrafter; +import forestry.core.interfaces.IRenderableMachine; +import forestry.core.network.ForestryPacket; +import forestry.core.network.GuiId; +import forestry.core.network.PacketIds; +import forestry.core.network.PacketTileNBT; +import forestry.core.network.PacketTileUpdate; +import forestry.core.proxy.Proxies; +import forestry.core.utils.EnumTankLevel; +import forestry.core.utils.InventoryAdapter; +import forestry.core.utils.StringUtil; +import forestry.core.utils.TileInventoryAdapter; +import forestry.core.utils.Utils; + +public class TileEscritoire extends TileBase implements ISidedInventory, IRenderableMachine, ICrafter { + + public static final short SLOT_ANALYZE = 0; + public static final short SLOT_RESULTS_1 = 1; + public static final short SLOTS_RESULTS_COUNT = 6; + public static final short SLOT_INPUT_1 = 7; + public static final short SLOTS_INPUT_COUNT = 5; + + /* MEMBER */ + private final NaturalistGame game = new NaturalistGame(); + private final InventoryAdapter inventory; + @Override + public String getInventoryName() { + return StringUtil.localize("core.1"); + } + + public TileEscritoire() { + inventory = new TileInventoryAdapter(this, 12, "Items"); + } + + /* GUI */ + @Override + public void openGui(EntityPlayer player, TileBase tile) { + player.openGui(ForestryAPI.instance, GuiId.NaturalistBenchGUI.ordinal(), player.worldObj, xCoord, yCoord, zCoord); + } + + /* SAVING & LOADING */ + @Override + public void writeToNBT(NBTTagCompound nbttagcompound) { + super.writeToNBT(nbttagcompound); + + game.writeToNBT(nbttagcompound); + inventory.writeToNBT(nbttagcompound); + } + + @Override + public void readFromNBT(NBTTagCompound nbttagcompound) { + super.readFromNBT(nbttagcompound); + + game.readFromNBT(nbttagcompound); + inventory.readFromNBT(nbttagcompound); + } + + /* GAME */ + public NaturalistGame getGame() { + return game; + } + + public void processTurnResult(String researcher) { + if(!game.isWon()) + return; + + IIndividual individual = AlleleManager.alleleRegistry.getIndividual(inventory.getStackInSlot(SLOT_ANALYZE)); + if(individual == null) + return; + + for(ItemStack itemstack : individual.getGenome().getPrimary().getResearchBounty(worldObj, researcher, individual, game.getBountyLevel())) + inventory.addStack(itemstack, SLOT_RESULTS_1, SLOTS_RESULTS_COUNT, false, true); + } + + private boolean areProbeSlotsFilled() { + int filledSlots = 0; + int required = game.getSampleSize() < SLOTS_INPUT_COUNT ? game.getSampleSize() : SLOTS_INPUT_COUNT; + for(int i = SLOT_INPUT_1; i < SLOT_INPUT_1 + required; i++) + if(inventory.getStackInSlot(i) != null) + filledSlots++; + + return filledSlots >= required; + } + + public void probe() { + if (!worldObj.isRemote && inventory.getStackInSlot(SLOT_ANALYZE) != null && areProbeSlotsFilled()) { + game.probe(inventory.getStackInSlot(SLOT_ANALYZE), this, SLOT_INPUT_1, SLOTS_INPUT_COUNT); + } + } + + /* NETWORK */ + @Override + public void fromPacket(ForestryPacket packetRaw) { + if(packetRaw instanceof PacketTileUpdate) { + super.fromPacket(packetRaw); + return; + } + + PacketTileNBT packet = (PacketTileNBT)packetRaw; + readFromNBT(packet.getTagCompound()); + } + + public void sendBoard(EntityPlayer player) { + Proxies.net.sendToPlayer(new PacketTileNBT(PacketIds.TILE_NBT, this), player); + } + + /* ISIDEDINVENTORY */ + @Override + public InventoryAdapter getInternalInventory() { + return inventory; + } + + @Override + public boolean isItemValidForSlot(int slotIndex, ItemStack itemstack) { + if(slotIndex >= SLOT_INPUT_1 && slotIndex < SLOT_INPUT_1 + SLOTS_INPUT_COUNT) + return slotIndex < SLOT_INPUT_1 + game.getSampleSize(); + + return true; + } + + @Override + protected boolean canTakeStackFromSide(int slotIndex, ItemStack itemstack, int side) { + if(!super.canTakeStackFromSide(slotIndex, itemstack, side)) + return false; + + return slotIndex >= SLOT_RESULTS_1 && slotIndex < SLOT_RESULTS_1 + SLOTS_RESULTS_COUNT; + } + + @Override + protected boolean canPutStackFromSide(int slotIndex, ItemStack itemstack, int side) { + + if(!super.canPutStackFromSide(slotIndex, itemstack, side)) + return false; + + int samples = game.getSampleSize(); + return slotIndex >= SLOT_INPUT_1 && slotIndex < SLOT_INPUT_1 + (samples < SLOTS_INPUT_COUNT ? samples : SLOTS_INPUT_COUNT); + } + + @Override + public void setInventorySlotContents(int slotIndex, ItemStack itemstack) { + inventory.setInventorySlotContents(slotIndex, itemstack); + if(slotIndex == SLOT_ANALYZE && Proxies.common.isSimulating(worldObj)) { + if(!AlleleManager.alleleRegistry.isIndividual(inventory.getStackInSlot(SLOT_ANALYZE)) + && inventory.getStackInSlot(SLOT_ANALYZE) != null) { + ItemStack ersatz = Utils.convertSaplingToGeneticEquivalent(inventory.getStackInSlot(SLOT_ANALYZE)); + if(ersatz != null) + inventory.setInventorySlotContents(SLOT_ANALYZE, ersatz); + } + game.initialize(inventory.getStackInSlot(SLOT_ANALYZE)); + } + } + + @Override public int getSizeInventory() { return inventory.getSizeInventory(); } + @Override public ItemStack getStackInSlot(int i) { return inventory.getStackInSlot(i); } + @Override public ItemStack decrStackSize(int i, int j) { return inventory.decrStackSize(i, j); } + @Override public int getInventoryStackLimit() { return inventory.getInventoryStackLimit(); } + @Override public ItemStack getStackInSlotOnClosing(int slot) { return inventory.getStackInSlotOnClosing(slot); } + @Override public void openInventory() {} + @Override public void closeInventory() {} + + /** + * TODO: just a specialsource workaround + */ + @Override + public boolean isUseableByPlayer(EntityPlayer player) { + return super.isUseableByPlayer(player); + } + + /** + * TODO: just a specialsource workaround + */ + @Override + public boolean hasCustomInventoryName() { + return super.hasCustomInventoryName(); + } + + /** + * TODO: just a specialsource workaround + */ + @Override + public boolean canInsertItem(int i, ItemStack itemstack, int j) { + return super.canInsertItem(i, itemstack, j); + } + + /** + * TODO: just a specialsource workaround + */ + @Override + public boolean canExtractItem(int i, ItemStack itemstack, int j) { + return super.canExtractItem(i, itemstack, j); + } + + /** + * TODO: just a specialsource workaround + */ + @Override + public int[] getAccessibleSlotsFromSide(int side) { + return super.getAccessibleSlotsFromSide(side); + } + + @Override + public EnumTankLevel getPrimaryLevel() { + return EnumTankLevel.EMPTY; + } + + @Override + public EnumTankLevel getSecondaryLevel() { + return EnumTankLevel.EMPTY; + } + + @Override + public ItemStack takenFromSlot(int slotIndex, boolean consumeRecipe, EntityPlayer player) { + if(slotIndex == SLOT_ANALYZE) + game.reset(); + return null; + } + + @Override + public ItemStack getResult() { + return null; + } + + @Override + public boolean canTakeStack(int slotIndex) { + return true; + } + + +} diff --git a/forestry_common/core/forestry/core/gadgets/TileForestry.java b/forestry_common/core/forestry/core/gadgets/TileForestry.java new file mode 100755 index 000000000..2df1d64f6 --- /dev/null +++ b/forestry_common/core/forestry/core/gadgets/TileForestry.java @@ -0,0 +1,371 @@ +/******************************************************************************* + * Copyright 2011-2014 by SirSengir + * + * This work is licensed under a Creative Commons Attribution-NonCommercial-NoDerivs 3.0 Unported License. + * + * To view a copy of this license, visit http://creativecommons.org/licenses/by-nc-nd/3.0/. + ******************************************************************************/ +package forestry.core.gadgets; + +import java.util.LinkedList; + +import net.minecraft.entity.EntityLivingBase; +import net.minecraft.entity.player.EntityPlayer; +import net.minecraft.item.ItemStack; +import net.minecraft.nbt.NBTTagCompound; +import net.minecraft.network.Packet; +import net.minecraft.tileentity.TileEntity; +import net.minecraft.util.MathHelper; +import net.minecraft.world.World; + +import net.minecraftforge.common.util.ForgeDirection; +import net.minecraftforge.fluids.Fluid; +import net.minecraftforge.fluids.FluidStack; +import net.minecraftforge.fluids.FluidTankInfo; + +import buildcraft.api.gates.ITrigger; + +import forestry.core.EnumErrorCode; +import forestry.core.config.Config; +import forestry.core.config.Defaults; +import forestry.core.interfaces.IErrorSource; +import forestry.core.interfaces.ILiquidTankContainer; +import forestry.core.interfaces.IOwnable; +import forestry.core.interfaces.IPowerHandler; +import forestry.core.network.ForestryPacket; +import forestry.core.network.INetworkedEntity; +import forestry.core.network.PacketPayload; +import forestry.core.network.PacketTileUpdate; +import forestry.core.proxy.Proxies; +import forestry.core.utils.EnumAccess; +import forestry.core.utils.ForestryTank; +import forestry.core.utils.InventoryAdapter; +import forestry.core.utils.Vect; + +public abstract class TileForestry extends TileEntity implements INetworkedEntity, IOwnable, IErrorSource { + + protected boolean isInited = false; + protected int energyConsumed; + protected int energyLast; + protected int energyReceived; + + public Vect Coords() { + return new Vect(xCoord, yCoord, zCoord); + } + + public World getWorld() { + return this.getWorldObj(); + } + + public void openGui(EntityPlayer player) { + } + + public void rotateAfterPlacement(World world, int x, int y, int z, EntityLivingBase entityliving, ItemStack stack) { + + int l = MathHelper.floor_double(((entityliving.rotationYaw * 4F) / 360F) + 0.5D) & 3; + if (l == 0) + setOrientation(ForgeDirection.NORTH); + if (l == 1) + setOrientation(ForgeDirection.EAST); + if (l == 2) + setOrientation(ForgeDirection.SOUTH); + if (l == 3) + setOrientation(ForgeDirection.WEST); + + } + + // / UPDATING + @Override + public void updateEntity() { + if (!isInited) { + initialize(); + isInited = true; + } + + if (!Proxies.common.isSimulating(worldObj)) + return; + + if (this instanceof IPowerHandler) { + IPowerHandler receptor = (IPowerHandler) this; + if (receptor.getPowerHandler() != null) { + receptor.getPowerHandler().update(); + } + } + } + + public abstract void initialize(); + + // / SAVING & LOADING + @Override + public void readFromNBT(NBTTagCompound nbttagcompound) { + super.readFromNBT(nbttagcompound); + + if (nbttagcompound.hasKey("Access")) + access = EnumAccess.values()[nbttagcompound.getInteger("Access")]; + else + access = EnumAccess.SHARED; + if (nbttagcompound.hasKey("Owner")) + owner = nbttagcompound.getString("Owner"); + + if (nbttagcompound.hasKey("Orientation")) + orientation = ForgeDirection.values()[nbttagcompound.getInteger("Orientation")]; + else + orientation = ForgeDirection.WEST; + + } + + @Override + public void writeToNBT(NBTTagCompound nbttagcompound) { + super.writeToNBT(nbttagcompound); + nbttagcompound.setInteger("Access", access.ordinal()); + if (owner != null) + nbttagcompound.setString("Owner", owner); + if (orientation != null) + nbttagcompound.setInteger("Orientation", orientation.ordinal()); + } + + // / SMP + @Override + public void sendNetworkUpdate() { + PacketTileUpdate packet = new PacketTileUpdate(this); + Proxies.net.sendNetworkPacket(packet, xCoord, yCoord, zCoord); + } + + @Override + public Packet getDescriptionPacket() { + PacketTileUpdate packet = new PacketTileUpdate(this); + return packet.getPacket(); + } + + public abstract PacketPayload getPacketPayload(); + + public abstract void fromPacketPayload(PacketPayload payload); + + @Override + public void fromPacket(ForestryPacket packetRaw) { + PacketTileUpdate packet = (PacketTileUpdate) packetRaw; + if (orientation != packet.getOrientation()) { + orientation = packet.getOrientation(); + worldObj.markBlockForUpdate(xCoord, yCoord, zCoord); + } + errorState = packet.getErrorState(); + owner = packet.getOwner(); + access = packet.getAccess(); + fromPacketPayload(packet.payload); + } + + public LinkedList getCustomTriggers() { + return null; + } + + public void onRemoval() { + } + + // / REDSTONE INFO + /** + * @return true if tile is activated by redstone current. + */ + public boolean isActivated() { + return worldObj.isBlockIndirectlyGettingPowered(xCoord, yCoord, zCoord); + } + // / ORIENTATION + private ForgeDirection orientation = ForgeDirection.WEST; + + public ForgeDirection getOrientation() { + return this.orientation; + } + + public void setOrientation(ForgeDirection orientation) { + if (this.orientation == orientation) + return; + this.orientation = orientation; + this.sendNetworkUpdate(); + } + // / ERROR HANDLING + public EnumErrorCode errorState = EnumErrorCode.OK; + + public void setErrorState(EnumErrorCode state) { + if (this.errorState == state) + return; + this.errorState = state; + this.sendNetworkUpdate(); + } + + @Override + public boolean throwsErrors() { + return true; + } + + @Override + public EnumErrorCode getErrorState() { + return errorState; + } + // / OWNERSHIP + public String owner = null; + private EnumAccess access = EnumAccess.SHARED; + + @Override + public boolean allowsRemoval(EntityPlayer player) { + if (!isOwnable()) + return true; + if (!isOwned()) + return true; + if (isOwner(player)) + return true; + if (Proxies.common.isOp(player)) + return true; + + return getAccess() == EnumAccess.SHARED; + } + + @Override + public boolean allowsInteraction(EntityPlayer player) { + if (Config.disablePermissions) + return true; + if (!isOwnable()) + return true; + if (!isOwned()) + return true; + if (isOwner(player)) + return true; + if (Proxies.common.isOp(player)) + return true; + + return getAccess() == EnumAccess.SHARED || getAccess() == EnumAccess.VIEWABLE; + } + + @Override + public EnumAccess getAccess() { + return access; + } + + @Override + public boolean isOwnable() { + return false; + } + + @Override + public boolean isOwned() { + return owner != null && !owner.isEmpty(); + } + + @Override + public String getOwnerName() { + return owner; + } + + public EntityPlayer getOwnerEntity() { + if (owner != null) + return worldObj.getPlayerEntityByName(owner); + else + return null; + } + + @Override + public void setOwner(EntityPlayer player) { + this.owner = player.getGameProfile().getId(); + } + + @Override + public boolean isOwner(EntityPlayer player) { + if (owner != null) + return owner.equals(player.getGameProfile().getId()); + else + return false; + } + + @Override + public boolean switchAccessRule(EntityPlayer player) { + if (owner != null && !owner.isEmpty() && !owner.equals(player.getGameProfile().getId())) + return false; + + if (access.ordinal() < EnumAccess.values().length - 1) + access = EnumAccess.values()[access.ordinal() + 1]; + else + access = EnumAccess.values()[0]; + + return true; + } + + /* NAME */ + public abstract String getInventoryName(); + + public boolean hasCustomInventoryName() { + return true; + } + + /* ACCESS */ + public abstract boolean isUseableByPlayer(EntityPlayer player); + + /* INVENTORY BASICS */ + public InventoryAdapter getInternalInventory() { + return null; + } + + public boolean isItemValidForSlot(int slotIndex, ItemStack itemstack) { + return true; + } + + public boolean canInsertItem(int i, ItemStack itemstack, int j) { + return canPutStackFromSide(i, itemstack, j); + } + + protected boolean canTakeStackFromSide(int slotIndex, ItemStack itemstack, int side) { + if (getAccess() == EnumAccess.PRIVATE) + return false; + + return true; + } + + public boolean canExtractItem(int i, ItemStack itemstack, int j) { + return canTakeStackFromSide(i, itemstack, j); + } + + protected boolean canPutStackFromSide(int slotIndex, ItemStack itemstack, int side) { + if (getAccess() == EnumAccess.PRIVATE) + return false; + + return true; + } + + public int[] getAccessibleSlotsFromSide(int side) { + if (getInternalInventory() == null) + return Defaults.FACINGS_NONE; + else + return getInternalInventory().getSizeInventorySide(side); + + } + + /* IFLUIDHANDLER BASICS */ + public FluidTankInfo[] getTankInfo(ForgeDirection from) { + if (this instanceof ILiquidTankContainer) { + ForestryTank[] tanks = ((ILiquidTankContainer) this).getTanks(); + FluidTankInfo[] info = new FluidTankInfo[tanks.length]; + for (int i = 0; i < info.length; i++) { + info[i] = tanks[i].getInfo(); + } + return info; + } + return ForestryTank.DUMMY_TANKINFO_ARRAY; + } + + public int fill(ForgeDirection from, FluidStack resource, boolean doFill) { + return 0; + } + + public FluidStack drain(ForgeDirection from, int maxDrain, boolean doDrain) { + return null; + } + + public FluidStack drain(ForgeDirection from, FluidStack resource, boolean doDrain) { + return resource != null ? drain(from, resource.amount, doDrain) : null; + } + + public boolean canFill(ForgeDirection from, Fluid fluid) { + return true; + } + + public boolean canDrain(ForgeDirection from, Fluid fluid) { + return true; + } +} diff --git a/forestry_common/core/forestry/core/gadgets/TileMachine.java b/forestry_common/core/forestry/core/gadgets/TileMachine.java new file mode 100755 index 000000000..139b809d7 --- /dev/null +++ b/forestry_common/core/forestry/core/gadgets/TileMachine.java @@ -0,0 +1,388 @@ +/******************************************************************************* + * Copyright 2011-2014 by SirSengir + * + * This work is licensed under a Creative Commons Attribution-NonCommercial-NoDerivs 3.0 Unported License. + * + * To view a copy of this license, visit http://creativecommons.org/licenses/by-nc-nd/3.0/. + ******************************************************************************/ +package forestry.core.gadgets; + +import java.util.HashMap; +import java.util.LinkedList; + +import net.minecraft.block.Block; +import net.minecraft.entity.player.EntityPlayer; +import net.minecraft.item.ItemStack; +import net.minecraft.nbt.NBTTagCompound; +import net.minecraft.tileentity.TileEntity; +import net.minecraft.world.IBlockAccess; + +import net.minecraftforge.common.util.ForgeDirection; + +import buildcraft.api.gates.ITrigger; +import buildcraft.api.inventory.ISpecialInventory; + +import forestry.api.core.EnumHumidity; +import forestry.api.core.EnumTemperature; +import forestry.core.config.Defaults; +import forestry.core.config.ForestryBlock; +import forestry.core.interfaces.IClimatised; +import forestry.core.interfaces.IHintSource; +import forestry.core.network.PacketPayload; +import forestry.core.proxy.Proxies; +import forestry.core.utils.EnumAccess; +import forestry.core.utils.EnumTankLevel; +import forestry.core.utils.Utils; +import forestry.plugins.PluginApiculture; +import forestry.plugins.PluginCore; +import forestry.plugins.PluginEnergy; +import forestry.plugins.PluginFactory; +import forestry.plugins.PluginMail; + +public class TileMachine extends TileForestry implements ISpecialInventory, IClimatised, IHintSource { + + public TileMachine() { + } + + // / IERRORSOURCE + @Override + public boolean throwsErrors() { + return false; + } + + // / IHINTSOURCE + @Override + public boolean hasHints() { + return false; + } + + @Override + public String[] getHints() { + return null; + } + + // / ICLIMATISED + @Override + public boolean isClimatized() { + return false; + } + + @Override + public EnumTemperature getTemperature() { + return EnumTemperature.NORMAL; + } + + @Override + public EnumHumidity getHumidity() { + return EnumHumidity.NORMAL; + } + + @Override + public float getExactTemperature() { + return 0; + } + + @Override + public float getExactHumidity() { + return 0; + } + + // / IOWNABLE + @Override + public boolean isOwnable() { + return true; + } + + protected void createMachine() { + } + + int oldkind; + NBTTagCompound olddata; + + @Override + public void initialize() { + + if (!Proxies.common.isSimulating(worldObj)) + return; + + if (olddata != null) + legacyConversion(oldkind, olddata); + + } + + @Override + public void updateEntity() { + + super.updateEntity(); + } + + @Override + public void onRemoval() { + } + + /** + * Read saved data + */ + @Override + public void readFromNBT(NBTTagCompound nbttagcompound) { + + super.readFromNBT(nbttagcompound); + + int kind = nbttagcompound.getInteger("Kind"); + oldkind = kind; + olddata = nbttagcompound; + + } + + private HashMap> definitionMap; + + private void createDefinitionMap() { + definitionMap = new HashMap>(); + + HashMap machineMap = new HashMap(); + machineMap.put(Defaults.ID_PACKAGE_MACHINE_BOTTLER, PluginFactory.definitionBottler); + machineMap.put(Defaults.ID_PACKAGE_MACHINE_CARPENTER, PluginFactory.definitionCarpenter); + machineMap.put(Defaults.ID_PACKAGE_MACHINE_CENTRIFUGE, PluginFactory.definitionCentrifuge); + machineMap.put(Defaults.ID_PACKAGE_MACHINE_FABRICATOR, PluginFactory.definitionFabricator); + machineMap.put(Defaults.ID_PACKAGE_MACHINE_FERMENTER, PluginFactory.definitionFermenter); + machineMap.put(Defaults.ID_PACKAGE_MACHINE_MOISTENER, PluginFactory.definitionMoistener); + machineMap.put(Defaults.ID_PACKAGE_MACHINE_RAINTANK, PluginFactory.definitionRaintank); + machineMap.put(Defaults.ID_PACKAGE_MACHINE_SQUEEZER, PluginFactory.definitionSqueezer); + machineMap.put(Defaults.ID_PACKAGE_MACHINE_STILL, PluginFactory.definitionStill); + machineMap.put(Defaults.ID_PACKAGE_MACHINE_APIARY, PluginApiculture.definitionApiary); + machineMap.put(4, PluginEnergy.definitionGenerator); + definitionMap.put(ForestryBlock.factoryTESR, machineMap); + + HashMap millMap = new HashMap(); + millMap.put(Defaults.ID_PACKAGE_MILL_MAILBOX, PluginMail.definitionMailbox); + millMap.put(Defaults.ID_PACKAGE_MILL_TRADER, PluginMail.definitionTradestation); + millMap.put(Defaults.ID_PACKAGE_MILL_PHILATELIST, PluginMail.definitionPhilatelist); + millMap.put(Defaults.ID_PACKAGE_MILL_APIARIST_CHEST, PluginApiculture.definitionChest); + millMap.put(Defaults.ID_PACKAGE_MILL_ANALYZER, PluginCore.definitionAnalyzer); + millMap.put(Defaults.ID_PACKAGE_MILL_RAINMAKER, PluginFactory.definitionRainmaker); + definitionMap.put(ForestryBlock.factoryPlain, millMap); + + HashMap engineMap = new HashMap(); + engineMap.put(0, PluginEnergy.definitionEngineBronze); + engineMap.put(1, PluginEnergy.definitionEngineCopper); + engineMap.put(2, PluginEnergy.definitionEngineTin); + definitionMap.put(ForestryBlock.engine, engineMap); + + } + + private void legacyConversion(int kind, NBTTagCompound nbttagcompound) { + if (definitionMap == null) + createDefinitionMap(); + + Block block = worldObj.getBlock(xCoord, yCoord, zCoord); + if (!definitionMap.containsKey(block) || !definitionMap.get(block).containsKey(kind)) { + commitSeppuku(block, kind); + return; + } + + MachineDefinition definition = definitionMap.get(block).get(kind); + Proxies.log.info("Converting obsolete gadget %s-%s to new '%s' %s-%s", block.getUnlocalizedName(), kind, definition.teIdent, definition.block.getUnlocalizedName(), definition.meta); + + Proxies.log.info("Removing old tile entity..."); + worldObj.removeTileEntity(xCoord, yCoord, zCoord); + worldObj.setBlockToAir(xCoord, yCoord, zCoord); + Proxies.log.info("Setting to new block id..."); + worldObj.setBlock(xCoord, yCoord, zCoord, definition.block, definition.meta, Defaults.FLAG_BLOCK_SYNCH); + TileEntity tile = worldObj.getTileEntity(xCoord, yCoord, zCoord); + if (tile == null) + throw new RuntimeException("Failed to set new block tile entity!"); + else if (tile.getClass() != definition.teClass) + throw new RuntimeException(String.format("Converted tile entity was '%s' instead of expected '%s'", tile.getClass(), definition.teClass)); + Proxies.log.info("Refreshing converted tile entity %s with nbt data...", tile.getClass()); + if (nbttagcompound.hasKey("Machine")) + tile.readFromNBT(complementNBT(nbttagcompound, nbttagcompound.getCompoundTag("Machine"), definition)); + else + tile.readFromNBT(nbttagcompound); + } + + private NBTTagCompound complementNBT(NBTTagCompound parent, NBTTagCompound inner, MachineDefinition definition) { + + inner.setString("id", definition.teIdent); + inner.setInteger("x", this.xCoord); + inner.setInteger("y", this.yCoord); + inner.setInteger("z", this.zCoord); + + inner.setInteger("Access", parent.getInteger("Access")); + if (parent.hasKey("Owner")) + inner.setString("Owner", parent.getString("Owner")); + if (parent.hasKey("Orientation")) + inner.setInteger("Orientation", parent.getInteger("Orientation")); + + return inner; + } + + private void commitSeppuku(Block block, int meta) { + Proxies.log.info("Obsolete gadget %s-%s has no replacement defined. Committing sepukku.", block.getUnlocalizedName(), meta); + worldObj.removeTileEntity(xCoord, yCoord, zCoord); + worldObj.setBlockToAir(xCoord, yCoord, zCoord); + } + + /** + * Write save data + */ + @Override + public void writeToNBT(NBTTagCompound nbttagcompound) { + + super.writeToNBT(nbttagcompound); + + // Legacy for old fermenter with strange meta data + int kind = worldObj.getBlockMetadata(xCoord, yCoord, zCoord); + nbttagcompound.setInteger("Kind", kind); + + /* + * if (machine != null) { NBTTagCompound NBTmachine = new NBTTagCompound(); machine.writeToNBT(NBTmachine); nbttagcompound.setTag("Machine", + * NBTmachine); } else { Proxies.log.warning("Saved a " + getClass() + " without machine."); } + */ + } + + @Override + public void validate() { + super.validate(); + } + + public boolean isWorking() { + return false; + } + + public int getChargeReceivedScaled(int i) { + return 0; + } + + public static EnumTankLevel rateTankLevel(int scaled) { + + if (scaled < 5) + return EnumTankLevel.EMPTY; + else if (scaled < 30) + return EnumTankLevel.LOW; + else if (scaled < 60) + return EnumTankLevel.MEDIUM; + else if (scaled < 90) + return EnumTankLevel.HIGH; + else + return EnumTankLevel.MAXIMUM; + } + + // / REDSTONE SIGNALS + public boolean isIndirectlyPoweringTo(IBlockAccess world, int i, int j, int k, int l) { + return false; + } + + public boolean isPoweringTo(IBlockAccess iblockaccess, int i, int j, int k, int l) { + return false; + } + + // IINVENTORY IMPLEMENTATION + @Override + public int getSizeInventory() { + return 0; + } + + @Override + public ItemStack getStackInSlot(int i) { + return null; + } + + @Override + public ItemStack decrStackSize(int i, int j) { + return null; + } + + @Override + public void setInventorySlotContents(int i, ItemStack itemstack) { + } + + @Override + public String getInventoryName() { + return "[Unknown]"; + } + + @Override + public int getInventoryStackLimit() { + return 64; + } + + @Override + public ItemStack getStackInSlotOnClosing(int slot) { + return null; + } + + @Override + public void openInventory() { + } + + @Override + public void closeInventory() { + } + + @Override + public boolean isUseableByPlayer(EntityPlayer player) { + return Utils.isUseableByPlayer(player, this, worldObj, xCoord, yCoord, zCoord); + } + + /** + * TODO: just a specialsource workaround + */ + @Override + public boolean hasCustomInventoryName() { + return super.hasCustomInventoryName(); + } + + /** + * TODO: just a specialsource workaround + */ + @Override + public boolean isItemValidForSlot(int slotIndex, ItemStack itemstack) { + return super.isItemValidForSlot(slotIndex, itemstack); + } + + // IPARTICULARINVENTORY IMPLEMENTATION + @Override + public int addItem(ItemStack stack, boolean doAdd, ForgeDirection from) { + if (getAccess() == EnumAccess.PRIVATE) + return 0; + + return 0; + } + + // @Override + // public boolean canAccess(String username) { + // return isOwned() && getOwnerName().equals(username); + // } + + @Override + public ItemStack[] extractItem(boolean doRemove, ForgeDirection from, int maxItemCount) { + if (getAccess() == EnumAccess.PRIVATE) + return new ItemStack[0]; + + return new ItemStack[0]; + } + + // INETWORKEDTILE IMPLEMENTATION + @Override + public PacketPayload getPacketPayload() { + + PacketPayload payload = null; + + return payload; + } + + @Override + public void fromPacketPayload(PacketPayload payload) { + } + + // NEIGHBOUR CHANGE + public void onNeighborBlockChange() { + } + + // ITRIGGERPROVIDER + @Override + public LinkedList getCustomTriggers() { + return null; + } + +} diff --git a/forestry_common/core/forestry/core/gadgets/TileMill.java b/forestry_common/core/forestry/core/gadgets/TileMill.java new file mode 100755 index 000000000..51f937b50 --- /dev/null +++ b/forestry_common/core/forestry/core/gadgets/TileMill.java @@ -0,0 +1,11 @@ +/******************************************************************************* + * Copyright 2011-2014 by SirSengir + * + * This work is licensed under a Creative Commons Attribution-NonCommercial-NoDerivs 3.0 Unported License. + * + * To view a copy of this license, visit http://creativecommons.org/licenses/by-nc-nd/3.0/. + ******************************************************************************/ +package forestry.core.gadgets; + +public class TileMill extends TileMachine { +} diff --git a/forestry_common/core/forestry/core/gadgets/TileNaturalistChest.java b/forestry_common/core/forestry/core/gadgets/TileNaturalistChest.java new file mode 100755 index 000000000..47c371f94 --- /dev/null +++ b/forestry_common/core/forestry/core/gadgets/TileNaturalistChest.java @@ -0,0 +1,172 @@ +/******************************************************************************* + * Copyright 2011-2014 by SirSengir + * + * This work is licensed under a Creative Commons Attribution-NonCommercial-NoDerivs 3.0 Unported License. + * + * To view a copy of this license, visit http://creativecommons.org/licenses/by-nc-nd/3.0/. + ******************************************************************************/ +package forestry.core.gadgets; + +import net.minecraft.entity.player.EntityPlayer; +import net.minecraft.inventory.IInventory; +import net.minecraft.item.ItemStack; +import net.minecraft.nbt.NBTTagCompound; +import net.minecraft.nbt.NBTTagList; + +import forestry.api.core.ForestryAPI; +import forestry.api.genetics.ISpeciesRoot; +import forestry.core.GuiHandler; +import forestry.core.config.Config; +import forestry.core.gui.IPagedInventory; +import forestry.core.utils.StringUtil; + +public abstract class TileNaturalistChest extends TileBase implements IInventory, IPagedInventory { + + private ItemStack[] inventoryStacks = new ItemStack[125]; + private final ISpeciesRoot speciesRoot; + private final int guiID; + + public TileNaturalistChest(ISpeciesRoot speciesRoot, int guiId) { + setHints(Config.hints.get("apiarist.chest")); + this.speciesRoot = speciesRoot; + this.guiID = guiId; + } + + @Override + public String getInventoryName() { + return StringUtil.localize("tile.mill.3"); + } + + @Override + public void openGui(EntityPlayer player, TileBase tile) { + player.openGui(ForestryAPI.instance, guiID, player.worldObj, xCoord, yCoord, zCoord); + } + + @Override + public void flipPage(EntityPlayer player, int page) { + player.openGui(ForestryAPI.instance, GuiHandler.encodeGuiData(guiID, page), player.worldObj, xCoord, yCoord, zCoord); + } + + /* SAVING & LOADING */ + @Override + public void writeToNBT(NBTTagCompound nbttagcompound) { + super.writeToNBT(nbttagcompound); + + NBTTagList nbttaglist = new NBTTagList(); + for (int i = 0; i < inventoryStacks.length; i++) { + if (inventoryStacks[i] != null) { + NBTTagCompound nbttagcompound1 = new NBTTagCompound(); + nbttagcompound1.setByte("Slot", (byte) i); + inventoryStacks[i].writeToNBT(nbttagcompound1); + nbttaglist.appendTag(nbttagcompound1); + } + } + nbttagcompound.setTag("Items", nbttaglist); + } + + @Override + public void readFromNBT(NBTTagCompound nbttagcompound) { + super.readFromNBT(nbttagcompound); + + NBTTagList nbttaglist = nbttagcompound.getTagList("Items", 10); + inventoryStacks = new ItemStack[getSizeInventory()]; + for (int i = 0; i < nbttaglist.tagCount(); i++) { + + NBTTagCompound nbttagcompound1 = nbttaglist.getCompoundTagAt(i); + byte byte0 = nbttagcompound1.getByte("Slot"); + if (byte0 >= 0 && byte0 < inventoryStacks.length) + inventoryStacks[byte0] = ItemStack.loadItemStackFromNBT(nbttagcompound1); + } + } + + /* UPDATING */ + @Override + public void updateServerSide() { + } + + /* ERROR HANDLING */ + @Override + public boolean throwsErrors() { + return false; + } + + /* IINVENTORY */ + @Override + public boolean isItemValidForSlot(int slotIndex, ItemStack itemstack) { + return itemstack == null || speciesRoot.isMember(itemstack); + } + + @Override + public int getSizeInventory() { + return inventoryStacks.length; + } + + @Override + public ItemStack getStackInSlot(int i) { + return inventoryStacks[i]; + } + + @Override + public ItemStack decrStackSize(int i, int j) { + if (inventoryStacks[i] == null) + return null; + + ItemStack product; + if (inventoryStacks[i].stackSize <= j) { + product = inventoryStacks[i]; + inventoryStacks[i] = null; + return product; + } else { + product = inventoryStacks[i].splitStack(j); + if (inventoryStacks[i].stackSize == 0) + inventoryStacks[i] = null; + + return product; + } + } + + @Override + public void setInventorySlotContents(int i, ItemStack itemstack) { + inventoryStacks[i] = itemstack; + if (itemstack != null && itemstack.stackSize > getInventoryStackLimit()) + itemstack.stackSize = getInventoryStackLimit(); + } + + @Override + public ItemStack getStackInSlotOnClosing(int slot) { + if (inventoryStacks[slot] == null) + return null; + ItemStack toReturn = inventoryStacks[slot]; + inventoryStacks[slot] = null; + return toReturn; + } + + @Override + public int getInventoryStackLimit() { + return 64; + } + + @Override + public void openInventory() { + } + + @Override + public void closeInventory() { + } + + /** + * TODO: just a specialsource workaround + */ + @Override + public boolean isUseableByPlayer(EntityPlayer player) { + return super.isUseableByPlayer(player); + } + + /** + * TODO: just a specialsource workaround + */ + @Override + public boolean hasCustomInventoryName() { + return super.hasCustomInventoryName(); + } +} diff --git a/forestry_common/core/forestry/core/gadgets/TilePowered.java b/forestry_common/core/forestry/core/gadgets/TilePowered.java new file mode 100755 index 000000000..4ff2a374b --- /dev/null +++ b/forestry_common/core/forestry/core/gadgets/TilePowered.java @@ -0,0 +1,210 @@ +/******************************************************************************* + * Copyright 2011-2014 by SirSengir + * + * This work is licensed under a Creative Commons Attribution-NonCommercial-NoDerivs 3.0 Unported License. + * + * To view a copy of this license, visit http://creativecommons.org/licenses/by-nc-nd/3.0/. + ******************************************************************************/ +package forestry.core.gadgets; + +import net.minecraft.item.ItemStack; +import net.minecraft.nbt.NBTTagCompound; + +import net.minecraftforge.common.util.ForgeDirection; +import net.minecraftforge.fluids.FluidContainerRegistry.FluidContainerData; + +import buildcraft.api.power.PowerHandler; +import buildcraft.api.power.PowerHandler.PowerReceiver; +import buildcraft.api.power.PowerHandler.Type; + +import forestry.core.GameMode; +import forestry.core.config.Defaults; +import forestry.core.interfaces.IPowerHandler; +import forestry.core.interfaces.IRenderableMachine; +import forestry.core.network.ClassMap; +import forestry.core.network.IndexInPayload; +import forestry.core.network.PacketPayload; +import forestry.core.proxy.Proxies; +import forestry.core.utils.EnumTankLevel; +import forestry.core.utils.ForestryTank; + +public abstract class TilePowered extends TileBase implements IPowerHandler, IRenderableMachine { + + public static int WORK_CYCLES = 4; + + @Override + public PacketPayload getPacketPayload() { + if (!ClassMap.classMappers.containsKey(this.getClass())) + ClassMap.classMappers.put(this.getClass(), new ClassMap(this.getClass())); + + ClassMap classmap = ClassMap.classMappers.get(this.getClass()); + PacketPayload payload = new PacketPayload(classmap.intSize, classmap.floatSize, classmap.stringSize); + + try { + classmap.setData(this, payload.intPayload, payload.floatPayload, payload.stringPayload, new IndexInPayload(0, 0, 0)); + } catch (Exception ex) { + ex.printStackTrace(); + } + + return payload; + } + + @Override + public void fromPacketPayload(PacketPayload payload) { + + if (payload.isEmpty()) + return; + + if (!ClassMap.classMappers.containsKey(this.getClass())) + ClassMap.classMappers.put(this.getClass(), new ClassMap(this.getClass())); + + ClassMap classmap = ClassMap.classMappers.get(this.getClass()); + + try { + classmap.fromData(this, payload.intPayload, payload.floatPayload, payload.stringPayload, new IndexInPayload(0, 0, 0)); + } catch (Exception ex) { + ex.printStackTrace(); + } + } + private final PowerHandler powerHandler; + + public TilePowered() { + powerHandler = new PowerHandler(this, Type.MACHINE); + configurePowerProvider(powerHandler); + adjustPowerProvider(powerHandler); + } + + protected void configurePowerProvider(PowerHandler provider) { + provider.configure(Defaults.MACHINE_MIN_ENERGY_RECEIVED, Defaults.MACHINE_MAX_ENERGY_RECEIVED, + Defaults.MACHINE_MIN_ACTIVATION_ENERGY, Defaults.MACHINE_MAX_ENERGY); + } + + private void adjustPowerProvider(PowerHandler provider) { + provider.configure( + provider.getMinEnergyReceived(), + Math.round(provider.getMaxEnergyReceived() * GameMode.getGameMode().getFloatSetting("energy.demand.modifier")), + Math.round(provider.getActivationEnergy() * GameMode.getGameMode().getFloatSetting("energy.demand.modifier")), + Math.round(provider.getMaxEnergyStored() * GameMode.getGameMode().getFloatSetting("energy.demand.modifier"))); + } + + /* STATE INFORMATION */ + public abstract boolean isWorking(); + + public boolean hasResourcesMin(float percentage) { + return false; + } + + public boolean hasFuelMin(float percentage) { + return false; + } + + public boolean hasWork() { + return false; + } + + /* IPOWERRECEPTOR */ + @Override + public PowerHandler getPowerHandler() { + return powerHandler; + } + private int workCounter; + + @Override + public void updateEntity() { + super.updateEntity(); + if (worldObj.isRemote) + return; + + if (workCounter >= WORK_CYCLES && worldObj.getTotalWorldTime() % 5 == 0) { + if (workCycle()) + workCounter = 0; + } + } + + @Override + public void doWork(PowerHandler workProvider) { + + if (!Proxies.common.isSimulating(worldObj)) + return; + + // Hard limit to 4 cycles / second. + if (workCounter < WORK_CYCLES) { + powerHandler.useEnergy(powerHandler.getActivationEnergy(), powerHandler.getActivationEnergy(), true); + workCounter++; + } + + /* + // Hard limit to 4 cycles / second. + if (worldObj.getTotalWorldTime() % 5 * 10 != 0) + return; + + PluginBuildCraft.instance.invokeUseEnergyMethod(powerHandler, powerHandler.getActivationEnergy(), powerHandler.getActivationEnergy(), false); + + // Do not consume energy if the boiler didn't do any work. + if (!workCycle()) + return; + + // Use up energy since we did some work. + PluginBuildCraft.instance.invokeUseEnergyMethod(powerHandler, powerHandler.getActivationEnergy(), powerHandler.getActivationEnergy(), true); + */ + } + + public abstract boolean workCycle(); + + @Override + public PowerReceiver getPowerReceiver(ForgeDirection side) { + return powerHandler.getPowerReceiver(); + } + + @Override + public void writeToNBT(NBTTagCompound nbt) { + super.writeToNBT(nbt); + powerHandler.writeToNBT(nbt); + } + + @Override + public void readFromNBT(NBTTagCompound nbt) { + super.readFromNBT(nbt); + powerHandler.readFromNBT(nbt); + } + + /* + @Override + public int powerRequest(ForgeDirection direction) { + float needed = powerProvider.getMaxEnergyStored() - powerProvider.getEnergyStored(); + return (int) Math.ceil(Math.min(powerProvider.getMaxEnergyReceived(), needed)); + } */ + + /* LIQUID CONTAINER HANDLING */ + protected ItemStack bottleIntoContainer(ItemStack canStack, ItemStack outputStack, FluidContainerData container, ForestryTank tank) { + if (tank.getFluidAmount() < container.fluid.amount) + return outputStack; + if (canStack.stackSize <= 0) + return outputStack; + if (outputStack != null && !outputStack.isItemEqual(container.filledContainer)) + return outputStack; + if (outputStack != null && outputStack.stackSize >= outputStack.getMaxStackSize()) + return outputStack; + + tank.drain(container.fluid.amount, true); + canStack.stackSize--; + + if (outputStack == null) + outputStack = container.filledContainer.copy(); + else + outputStack.stackSize++; + + return outputStack; + } + + // / ADDITIONAL LIQUID HANDLING + @Override + public EnumTankLevel getPrimaryLevel() { + return EnumTankLevel.EMPTY; + } + + @Override + public EnumTankLevel getSecondaryLevel() { + return EnumTankLevel.EMPTY; + } +} diff --git a/forestry_common/core/forestry/core/genetics/Allele.java b/forestry_common/core/forestry/core/genetics/Allele.java new file mode 100755 index 000000000..1ed39f080 --- /dev/null +++ b/forestry_common/core/forestry/core/genetics/Allele.java @@ -0,0 +1,693 @@ +/******************************************************************************* + * Copyright 2011-2014 by SirSengir + * + * This work is licensed under a Creative Commons Attribution-NonCommercial-NoDerivs 3.0 Unported License. + * + * To view a copy of this license, visit http://creativecommons.org/licenses/by-nc-nd/3.0/. + ******************************************************************************/ +package forestry.core.genetics; + +import java.util.EnumSet; + +import net.minecraftforge.common.EnumPlantType; + +import forestry.api.genetics.AlleleManager; +import forestry.api.genetics.EnumTolerance; +import forestry.api.genetics.IAllele; +import forestry.api.genetics.ILegacyHandler; +import forestry.core.config.Defaults; +import forestry.core.utils.StringUtil; + +public class Allele implements IAllele { + + protected String uid; + boolean isDominant; + protected String name; + + public Allele(String uid, boolean isDominant) { + this(uid, isDominant, false); + } + + protected Allele(String uid, boolean isDominant, boolean skipRegister) { + this.uid = uid; + this.isDominant = isDominant; + this.name = "allele."+uid; + + if (!skipRegister) + AlleleManager.alleleRegistry.registerAllele(this); + } + + @Override + public String getUID() { + return "forestry." + this.uid; + } + + @Override + public boolean isDominant() { + return isDominant; + } + + // / BEES // SPECIES + // Common Branch + public static AlleleSpecies speciesForest; + public static AlleleSpecies speciesMeadows; + public static AlleleSpecies speciesCommon; + public static AlleleSpecies speciesCultivated; + + // Noble Branch + public static AlleleSpecies speciesNoble; + public static AlleleSpecies speciesMajestic; + public static AlleleSpecies speciesImperial; + + // Industrious Branch + public static AlleleSpecies speciesDiligent; + public static AlleleSpecies speciesUnweary; + public static AlleleSpecies speciesIndustrious; + + // Heroic Branch + public static AlleleSpecies speciesSteadfast; + public static AlleleSpecies speciesValiant; + public static AlleleSpecies speciesHeroic; + + // Infernal Branch + public static AlleleSpecies speciesSinister; + public static AlleleSpecies speciesFiendish; + public static AlleleSpecies speciesDemonic; + + // Austere Branch + public static AlleleSpecies speciesModest; + public static AlleleSpecies speciesFrugal; + public static AlleleSpecies speciesAustere; + + // / Tropical Branch + public static AlleleSpecies speciesTropical; + public static AlleleSpecies speciesExotic; + public static AlleleSpecies speciesEdenic; + + // End Branch + public static AlleleSpecies speciesEnded; + public static AlleleSpecies speciesSpectral; + public static AlleleSpecies speciesPhantasmal; + + // Frozen Branch + public static AlleleSpecies speciesWintry; + public static AlleleSpecies speciesIcy; + public static AlleleSpecies speciesGlacial; + + // Vengeful Branch + public static AlleleSpecies speciesVindictive; + public static AlleleSpecies speciesVengeful; + public static AlleleSpecies speciesAvenging; + + // Reddened Branch (EE) + public static AlleleSpecies speciesDarkened; + public static AlleleSpecies speciesReddened; + public static AlleleSpecies speciesOmega; + + // Festive branch + public static AlleleSpecies speciesLeporine; // Easter + public static AlleleSpecies speciesMerry; // Christmas + public static AlleleSpecies speciesTipsy; // New Year + // 35 Solstice + public static AlleleSpecies speciesTricky; // Halloween + // 37 Thanksgiving + // 39 New Year + + // Agrarian branch + public static AlleleSpecies speciesRural; + // 41 Farmerly + // 42 Agrarian + + // Boggy branch + public static AlleleSpecies speciesMarshy; + // 44 speciesMiry + // 45 speciesBoggy + + // Monastic branch + public static AlleleSpecies speciesMonastic; + public static AlleleSpecies speciesSecluded; + public static AlleleSpecies speciesHermitic; + + // / TREES // SPECIES 512 - 1023 + public static AlleleSpecies treeOak; + public static AlleleSpecies treeBirch; + public static AlleleSpecies treeSpruce; + public static AlleleSpecies treePine; + public static AlleleSpecies treeJungle; + + public static AlleleSpecies treeLarch; + public static AlleleSpecies treeTeak; + public static AlleleSpecies treeAcacia; + public static AlleleSpecies treeLime; + public static AlleleSpecies treeChestnut; + public static AlleleSpecies treeWenge; + public static AlleleSpecies treeBaobab; + public static AlleleSpecies treeSequioa; + public static AlleleSpecies treeGiganteum; + + public static AlleleSpecies treeKapok; + public static AlleleSpecies treeEbony; + public static AlleleSpecies treeMahogany; + public static AlleleSpecies treeBalsa; + public static AlleleSpecies treePapaya; + public static AlleleSpecies treeWalnut; + public static AlleleSpecies treeDate; + public static AlleleSpecies treeCherry; + + public static AlleleSpecies treeWillow; + public static AlleleSpecies treeSipiri; + + public static AlleleSpecies treeMahoe; + public static AlleleSpecies treePoplar; + + public static AlleleSpecies treeLemon; + public static AlleleSpecies treePlum; + + public static AlleleSpecies treeMaple; + + /// BUTTERFLIES // SPECIES + // Moths + public static AlleleSpecies mothBrimstone; + public static AlleleSpecies mothLatticedHeath; + public static AlleleSpecies mothAtlas; + + // Butterflies + public static AlleleSpecies lepiCabbageWhite; + public static AlleleSpecies lepiGlasswing; + public static AlleleSpecies lepiEmeraldPeacock; + public static AlleleSpecies lepiThoasSwallow; + public static AlleleSpecies lepiCitrusSwallow; + public static AlleleSpecies lepiZebraSwallow; + public static AlleleSpecies lepiBlackSwallow; + public static AlleleSpecies lepiDianaFrit; + + public static AlleleSpecies lepiSpeckledWood; + public static AlleleSpecies lepiMadeiranSpeckledWood; + public static AlleleSpecies lepiCanarySpeckledWood; + + public static AlleleSpecies lepiMenelausBlueMorpho; + public static AlleleSpecies lepiPeleidesBlueMorpho; + public static AlleleSpecies lepiRhetenorBlueMorpho; + + public static AlleleSpecies lepiBrimstone; + public static AlleleSpecies lepiAurora; + public static AlleleSpecies lepiPostillion; + public static AlleleSpecies lepiPalaenoSulphur; + public static AlleleSpecies lepiReseda; + public static AlleleSpecies lepiSpringAzure; + public static AlleleSpecies lepiGozoraAzure; + public static AlleleSpecies lepiComma; + public static AlleleSpecies lepiBatesia; + public static AlleleSpecies lepiBlueWing; + + public static AlleleSpecies lepiMonarch; + public static AlleleSpecies lepiBlueDuke; + public static AlleleSpecies lepiGlassyTiger; + public static AlleleSpecies lepiPostman; + public static AlleleSpecies lepiSpicebush; + public static AlleleSpecies lepiMalachite; + public static AlleleSpecies lepiLLacewing; + + // / ALL // GENERIC + public static Allele boolFalse; + public static Allele boolTrue; + + public static Allele int1; + public static Allele int2; + public static Allele int3; + public static Allele int4; + public static Allele int5; + public static Allele int6; + public static Allele int7; + public static Allele int8; + public static Allele int9; + public static Allele int10; + + // / BEES // SPEED 1100 - 1199 + public static Allele speedSlowest; + public static Allele speedSlower; + public static Allele speedSlow; + public static Allele speedNorm; + public static Allele speedFast; + public static Allele speedFaster; + public static Allele speedFastest; + + // / BEES // LIFESPAN 1200 - 1299 + public static Allele lifespanShortest; + public static Allele lifespanShorter; + public static Allele lifespanShort; + public static Allele lifespanShortened; + public static Allele lifespanNormal; + public static Allele lifespanElongated; + public static Allele lifespanLong; + public static Allele lifespanLonger; + public static Allele lifespanLongest; + + // / BEES // FERTILITY 1300 - 1349 + public static Allele fertilityLow; + public static Allele fertilityNormal; + public static Allele fertilityHigh; + public static Allele fertilityMaximum; + + // / TREES // GROWTH PROVIDER 1350 - 1399 + public static Allele growthLightlevel; + public static Allele growthAcacia; + public static Allele growthTropical; + + // TREES FRUIT PROVIDERS + public static Allele fruitNone; + public static Allele fruitApple; + public static Allele fruitCocoa; + public static Allele fruitChestnut; + public static Allele fruitCoconut; + public static Allele fruitWalnut; + public static Allele fruitCherry; + public static Allele fruitDates; + public static Allele fruitPapaya; + public static Allele fruitLemon; + public static Allele fruitPlum; + public static Allele fruitJujube; + + // / TREES // HEIGHT 1400 - 1449 + public static Allele heightSmallest; + public static Allele heightSmaller; + public static Allele heightSmall; + public static Allele heightAverage; + public static Allele heightLarge; + public static Allele heightLarger; + public static Allele heightLargest; + public static Allele heightGigantic; + + /// BUTTERFLIES // SIZE + public static Allele sizeSmallest; + public static Allele sizeSmaller; + public static Allele sizeSmall; + public static Allele sizeAverage; + public static Allele sizeLarge; + public static Allele sizeLarger; + public static Allele sizeLargest; + + // / BOTH // TOLERANCE 1450 - 1499 + public static Allele toleranceNone; + public static Allele toleranceBoth1; + public static Allele toleranceBoth2; + public static Allele toleranceBoth3; + public static Allele toleranceBoth4; + public static Allele toleranceBoth5; + public static Allele toleranceUp1; + public static Allele toleranceUp2; + public static Allele toleranceUp3; + public static Allele toleranceUp4; + public static Allele toleranceUp5; + public static Allele toleranceDown1; + public static Allele toleranceDown2; + public static Allele toleranceDown3; + public static Allele toleranceDown4; + public static Allele toleranceDown5; + + // / BEES // FLOWER PROVIDERS 1500 - 1599 + public static Allele flowersVanilla; + public static Allele flowersNether; + public static Allele flowersCacti; + public static Allele flowersMushrooms; + public static Allele flowersEnd; + public static Allele flowersJungle; + public static Allele flowersSnow; + public static Allele flowersWheat; + public static Allele flowersGourd; + + // / TREES // FERTILITY 1600 - 1649 + public static Allele saplingsLowest; + public static Allele saplingsLower; + public static Allele saplingsLow; + public static Allele saplingsAverage; + public static Allele saplingsHigh; + public static Allele saplingsHigher; + public static Allele saplingsHighest; + + // / TREES // YIELD 1650 - 1699 + public static Allele yieldLowest; + public static Allele yieldLower; + public static Allele yieldLow; + public static Allele yieldAverage; + public static Allele yieldHigh; + public static Allele yieldHigher; + public static Allele yieldHighest; + + // TREES // SAPPINESS + public static Allele sappinessLowest; + public static Allele sappinessLower; + public static Allele sappinessLow; + public static Allele sappinessAverage; + public static Allele sappinessHigh; + public static Allele sappinessHigher; + public static Allele sappinessHighest; + + // TREES // MATURATION TIME + public static Allele maturationSlowest; + public static Allele maturationSlower; + public static Allele maturationSlow; + public static Allele maturationAverage; + public static Allele maturationFast; + public static Allele maturationFaster; + public static Allele maturationFastest; + + // / BEES // FLOWER GROWTH 1700 - 1749 + public static Allele floweringSlowest; + public static Allele floweringSlower; + public static Allele floweringSlow; + public static Allele floweringAverage; + public static Allele floweringFast; + public static Allele floweringFaster; + public static Allele floweringFastest; + public static Allele floweringMaximum; + + // / BOTH // TERRITORY 1750 - 1799 + public static Allele territoryDefault; + public static Allele territoryLarge; + public static Allele territoryLarger; + public static Allele territoryLargest; + + // / BEES // EFFECTS 1800 - 1899 + public static Allele effectNone; + public static Allele effectAggressive; + public static Allele effectHeroic; + public static Allele effectBeatific; + public static Allele effectMiasmic; + public static Allele effectMisanthrope; + public static Allele effectGlacial; + public static Allele effectRadioactive; + public static Allele effectCreeper; + public static Allele effectIgnition; + public static Allele effectExploration; + public static Allele effectFestiveEaster; + public static Allele effectSnowing; + public static Allele effectDrunkard; + public static Allele effectReanimation; + public static Allele effectResurrection; + public static Allele effectRepulsion; + + // / TREES // EFFECTS + public static Allele leavesNone; + + // / BUTTERFLIES // EFFECTS + public static Allele butterflyNone; + + // These are "secondary" plant attributes, i.e. the tree can double as one. + public static Allele plantTypeNone; + public static Allele plantTypePlains; + public static Allele plantTypeDesert; + public static Allele plantTypeBeach; + public static Allele plantTypeCave; + public static Allele plantTypeWater; + public static Allele plantTypeNether; + public static Allele plantTypeCrop; + + public static void initialize() { + // ALL // GENERIC + boolFalse = new AlleleBoolean("boolFalse", false); + boolTrue = new AlleleBoolean("boolTrue", true); + + int1 = new AlleleInteger("i1d", 1, true); + int2 = new AlleleInteger("i2d", 2, true); + int3 = new AlleleInteger("i3d", 3, true); + int4 = new AlleleInteger("i4d", 4, true); + int5 = new AlleleInteger("i5d", 5, true); + int6 = new AlleleInteger("i6d", 6, true); + int7 = new AlleleInteger("i7d", 7, true); + int8 = new AlleleInteger("i8d", 8, true); + int9 = new AlleleInteger("i9d", 9, true); + int10 = new AlleleInteger("i10d", 10, true); + + // BEES // SPEED + speedSlowest = new AlleleFloat("speedSlowest", 0.3f, true).setName("gui.slowest"); + speedSlower = new AlleleFloat("speedSlower", 0.6f, true).setName("gui.slower"); + speedSlow = new AlleleFloat("speedSlow", 0.8f, true).setName("gui.slow"); + speedNorm = new AlleleFloat("speedNorm", 1.0f).setName("gui.normal"); + speedFast = new AlleleFloat("speedFast", 1.2f, true).setName("gui.fast"); + speedFaster = new AlleleFloat("speedFaster", 1.4f).setName("gui.faster"); + speedFastest = new AlleleFloat("speedFastest", 1.7f).setName("gui.fastest"); + + // BEES // LIFESPAN + lifespanShortest = new AlleleInteger("lifespanShortest", 10, false).setName("gui.shortestlife"); + lifespanShorter = new AlleleInteger("lifespanShorter", 20, true).setName("gui.shorterlife"); + lifespanShort = new AlleleInteger("lifespanShort", 30, true).setName("gui.shortlife"); + lifespanShortened = new AlleleInteger("lifespanShortened", 35, true).setName("gui.shortenedlife"); + lifespanNormal = new AlleleInteger("lifespanNormal", 40).setName("gui.normallife"); + lifespanElongated = new AlleleInteger("lifespanElongated", 45, true).setName("gui.elongatedlife"); + lifespanLong = new AlleleInteger("lifespanLong", 50).setName("gui.longlife"); + lifespanLonger = new AlleleInteger("lifespanLonger", 60).setName("gui.longerlife"); + lifespanLongest = new AlleleInteger("lifespanLongest", 70).setName("gui.longestlife"); + + // BEES // FERTILITY + fertilityLow = new AlleleInteger("fertilityLow", 1, true); + fertilityNormal = new AlleleInteger("fertilityNormal", 2, true); + fertilityHigh = new AlleleInteger("fertilityHigh", 3); + fertilityMaximum = new AlleleInteger("fertilityMaximum", 4); + + // TREES // HEIGHT + heightSmallest = new AlleleFloat("heightSmallest", 0.25f).setName("gui.smallest"); + heightSmaller = new AlleleFloat("heightSmaller", 0.5f).setName("gui.smaller"); + heightSmall = new AlleleFloat("heightSmall", 0.75f).setName("gui.small"); + heightAverage = new AlleleFloat("heightMax10", 1.0f).setName("gui.average"); + heightLarge = new AlleleFloat("heightLarge", 1.25f).setName("gui.large"); + heightLarger = new AlleleFloat("heightLarger", 1.5f).setName("gui.larger"); + heightLargest = new AlleleFloat("heightLargest", 1.75f).setName("gui.largest"); + heightGigantic = new AlleleFloat("heightGigantic", 2.0f).setName("gui.gigantic"); + + // BUTTERFLIES // SIZE + sizeSmallest = new AlleleFloat("sizeSmallest", 0.3f).setName("gui.smallest"); + sizeSmaller = new AlleleFloat("sizeSmaller", 0.4f).setName("gui.smaller"); + sizeSmall = new AlleleFloat("sizeSmall", 0.5f).setName("gui.small"); + sizeAverage = new AlleleFloat("sizeAverage", 0.6f).setName("gui.average"); + sizeLarge = new AlleleFloat("sizeLarge", 0.75f).setName("gui.large"); + sizeLarger = new AlleleFloat("sizeLarger", 0.9f).setName("gui.larger"); + sizeLargest = new AlleleFloat("sizeLargest", 1.0f).setName("gui.largest"); + + // BEES // TOLERANCE + toleranceNone = new AlleleTolerance("toleranceNone", EnumTolerance.NONE); + toleranceBoth1 = new AlleleTolerance("toleranceBoth1", EnumTolerance.BOTH_1, true); + toleranceBoth2 = new AlleleTolerance("toleranceBoth2", EnumTolerance.BOTH_2); + toleranceBoth3 = new AlleleTolerance("toleranceBoth3", EnumTolerance.BOTH_3); + toleranceBoth4 = new AlleleTolerance("toleranceBoth4", EnumTolerance.BOTH_4); + toleranceBoth5 = new AlleleTolerance("toleranceBoth5", EnumTolerance.BOTH_5); + toleranceUp1 = new AlleleTolerance("toleranceUp1", EnumTolerance.UP_1, true); + toleranceUp2 = new AlleleTolerance("toleranceUp2", EnumTolerance.UP_2); + toleranceUp3 = new AlleleTolerance("toleranceUp3", EnumTolerance.UP_3); + toleranceUp4 = new AlleleTolerance("toleranceUp4", EnumTolerance.UP_4); + toleranceUp5 = new AlleleTolerance("toleranceUp5", EnumTolerance.UP_5); + toleranceDown1 = new AlleleTolerance("toleranceDown1", EnumTolerance.DOWN_1, true); + toleranceDown2 = new AlleleTolerance("toleranceDown2", EnumTolerance.DOWN_2); + toleranceDown3 = new AlleleTolerance("toleranceDown3", EnumTolerance.DOWN_3); + toleranceDown4 = new AlleleTolerance("toleranceDown4", EnumTolerance.DOWN_4); + toleranceDown5 = new AlleleTolerance("toleranceDown5", EnumTolerance.DOWN_5); + + // TREES // FERTILITY + saplingsLowest = new AlleleFloat("saplingsLowest", 0.01f, true).setName("gui.lowest"); + saplingsLower = new AlleleFloat("saplingsLower", 0.025f, true).setName("gui.lower"); + saplingsLow = new AlleleFloat("saplingsLow", 0.035f, true).setName("gui.low"); + saplingsAverage = new AlleleFloat("saplingsDefault", 0.05f, true).setName("gui.average"); + saplingsHigh = new AlleleFloat("saplingsDouble", 0.1f, true).setName("gui.high"); + saplingsHigher = new AlleleFloat("saplingsTriple", 0.2f, true).setName("gui.higher"); + saplingsHighest = new AlleleFloat("saplingsHighest", 0.3f, true).setName("gui.highest"); + + // TREES // YIELD + yieldLowest = new AlleleFloat("yieldLowest", 0.025f, true).setName("gui.lowest"); + yieldLower = new AlleleFloat("yieldLower", 0.05f, true).setName("gui.lower"); + yieldLow = new AlleleFloat("yieldLow", 0.1f, true).setName("gui.low"); + yieldAverage = new AlleleFloat("yieldDefault", 0.2f, true).setName("gui.average"); + yieldHigh = new AlleleFloat("yieldHigh", 0.3f, false).setName("gui.high"); + yieldHigher = new AlleleFloat("yieldHigher", 0.35f, false).setName("gui.higher"); + yieldHighest = new AlleleFloat("yieldHighest", 0.4f, false).setName("gui.highest"); + + // TREES // SAPPINESS + sappinessLowest = new AlleleFloat("sappinessLowest", 0.1f, true).setName("gui.lowest"); + sappinessLower = new AlleleFloat("sappinessLower", 0.2f, true).setName("gui.lower"); + sappinessLow = new AlleleFloat("sappinessLow", 0.3f, true).setName("gui.low"); + sappinessAverage = new AlleleFloat("sappinessAverage", 0.4f, true).setName("gui.average"); + sappinessHigh = new AlleleFloat("sappinessHigh", 0.6f, true).setName("gui.high"); + sappinessHigher = new AlleleFloat("sappinessHigher", 0.8f, false).setName("gui.higher"); + sappinessHighest = new AlleleFloat("sappinessHighest", 1.0f, false).setName("gui.highest"); + + // TREES // MATURATION TIME + maturationSlowest = new AlleleInteger("maturationSlowest", 10, true).setName("gui.slowest"); + maturationSlower = new AlleleInteger("maturationSlower", 7).setName("gui.slower"); + maturationSlow = new AlleleInteger("maturationSlow", 5, true).setName("gui.slow"); + maturationAverage = new AlleleInteger("maturationAverage", 4).setName("gui.average"); + maturationFast = new AlleleInteger("maturationFast", 3).setName("gui.fast"); + maturationFaster = new AlleleInteger("maturationFaster", 2).setName("gui.faster"); + maturationFastest = new AlleleInteger("maturationFastest", 1).setName("gui.fastest"); + + // BEES // FLOWER GROWTH + floweringSlowest = new AlleleInteger("floweringSlowest", 5, true).setName("gui.slowest"); + floweringSlower = new AlleleInteger("floweringSlower", 10).setName("gui.slower"); + floweringSlow = new AlleleInteger("floweringSlow", 15).setName("gui.slow"); + floweringAverage = new AlleleInteger("floweringAverage", 20).setName("gui.average"); + floweringFast = new AlleleInteger("floweringFast", 25).setName("gui.fast"); + floweringFaster = new AlleleInteger("floweringFaster", 30).setName("gui.faster"); + floweringFastest = new AlleleInteger("floweringFastest", 35).setName("gui.fastest"); + floweringMaximum = new AlleleInteger("floweringMaximum", 99, true).setName("gui.maximum"); + + // BOTH // TERRITORY + territoryDefault = new AlleleArea("territoryDefault", new int[] {9, 6, 9}).setName("gui.average"); + territoryLarge = new AlleleArea("territoryLarge", new int[] {11, 8, 11}).setName("gui.large"); + territoryLarger = new AlleleArea("territoryLarger", new int[] {13, 12, 13}).setName("gui.larger"); + territoryLargest = new AlleleArea("territoryLargest", new int[] {15, 13, 15}).setName("gui.largest"); + + // TREES // PLANTS + plantTypeNone = new AllelePlantType("plantTypeNone", EnumSet.noneOf(EnumPlantType.class), true); + plantTypePlains = new AllelePlantType("plantTypePlains", EnumPlantType.Plains); + ; + plantTypeDesert = new AllelePlantType("plantTypeDesert", EnumPlantType.Desert); + plantTypeBeach = new AllelePlantType("plantTypeBeach", EnumPlantType.Beach); + plantTypeCave = new AllelePlantType("plantTypeCave", EnumPlantType.Cave); + plantTypeWater = new AllelePlantType("plantTypeWater", EnumPlantType.Water); + plantTypeNether = new AllelePlantType("plantTypeNether", EnumPlantType.Nether); + plantTypeCrop = new AllelePlantType("plantTypeCrop", EnumPlantType.Crop); + + // LEGACY MAPPINGS + ILegacyHandler legacy = (ILegacyHandler) AlleleManager.alleleRegistry; + + legacy.registerLegacyMapping(0, "forestry.speciesForest"); + legacy.registerLegacyMapping(1, "forestry.speciesMeadows"); + legacy.registerLegacyMapping(2, "forestry.speciesCommon"); + legacy.registerLegacyMapping(3, "forestry.speciesCultivated"); + + legacy.registerLegacyMapping(4, "forestry.speciesNoble"); + legacy.registerLegacyMapping(5, "forestry.speciesMajestic"); + legacy.registerLegacyMapping(6, "forestry.speciesImperial"); + + legacy.registerLegacyMapping(7, "forestry.speciesDiligent"); + legacy.registerLegacyMapping(8, "forestry.speciesUnweary"); + legacy.registerLegacyMapping(9, "forestry.speciesIndustrious"); + + legacy.registerLegacyMapping(10, "forestry.speciesSteadfast"); + legacy.registerLegacyMapping(11, "forestry.speciesValiant"); + legacy.registerLegacyMapping(12, "forestry.speciesHeroic"); + + legacy.registerLegacyMapping(13, "forestry.speciesSinister"); + legacy.registerLegacyMapping(14, "forestry.speciesFiendish"); + legacy.registerLegacyMapping(15, "forestry.speciesDemonic"); + + legacy.registerLegacyMapping(16, "forestry.speciesModest"); + legacy.registerLegacyMapping(17, "forestry.speciesFrugal"); + legacy.registerLegacyMapping(18, "forestry.speciesAustere"); + + legacy.registerLegacyMapping(19, "forestry.speciesTropical"); + legacy.registerLegacyMapping(20, "forestry.speciesExotic"); + legacy.registerLegacyMapping(21, "forestry.speciesEdenic"); + + legacy.registerLegacyMapping(22, "forestry.speciesEnded"); + + legacy.registerLegacyMapping(25, "forestry.speciesWintry"); + + legacy.registerLegacyMapping(28, "forestry.speciesVindictive"); + legacy.registerLegacyMapping(29, "forestry.speciesVengeful"); + legacy.registerLegacyMapping(30, "forestry.speciesAvenging"); + + legacy.registerLegacyMapping(Defaults.ID_BEE_SPECIES_DARKENED, "forestry.speciesDarkened"); + legacy.registerLegacyMapping(Defaults.ID_BEE_SPECIES_REDDENED, "forestry.speciesReddened"); + legacy.registerLegacyMapping(Defaults.ID_BEE_SPECIES_OMEGA, "forestry.speciesOmega"); + + legacy.registerLegacyMapping(34, "forestry.speciesLeporine"); + + legacy.registerLegacyMapping(40, "forestry.speciesRural"); + + legacy.registerLegacyMapping(43, "forestry.speciesMarshy"); + + // Flowers + legacy.registerLegacyMapping(1500, "forestry.flowersVanilla"); + legacy.registerLegacyMapping(1501, "forestry.flowersNether"); + legacy.registerLegacyMapping(1502, "forestry.flowersCacti"); + legacy.registerLegacyMapping(1503, "forestry.flowersMushrooms"); + legacy.registerLegacyMapping(1504, "forestry.flowersEnd"); + legacy.registerLegacyMapping(1505, "forestry.flowersJungle"); + legacy.registerLegacyMapping(1506, "forestry.flowersSnow"); + legacy.registerLegacyMapping(1507, "forestry.flowersWheat"); + + // Effects + legacy.registerLegacyMapping(1800, "forestry.effectNone"); + legacy.registerLegacyMapping(1801, "forestry.effectAggressive"); + legacy.registerLegacyMapping(1802, "forestry.effectHeroic"); + legacy.registerLegacyMapping(1803, "forestry.effectBeatific"); + legacy.registerLegacyMapping(1804, "forestry.effectMiasmic"); + legacy.registerLegacyMapping(1805, "forestry.effectMisanthrope"); + legacy.registerLegacyMapping(1806, "forestry.effectGlacial"); + legacy.registerLegacyMapping(1807, "forestry.effectRadioactive"); + legacy.registerLegacyMapping(1808, "forestry.effectCreeper"); + legacy.registerLegacyMapping(1809, "forestry.effectIgnition"); + legacy.registerLegacyMapping(1810, "forestry.effectExploration"); + legacy.registerLegacyMapping(1811, "forestry.effectFestiveEaster"); + + // Generic + legacy.registerLegacyMapping(1024, "forestry.boolFalse"); + legacy.registerLegacyMapping(1025, "forestry.boolTrue"); + + // Speed + legacy.registerLegacyMapping(1100, "forestry.speedSlowest"); + legacy.registerLegacyMapping(1101, "forestry.speedSlower"); + legacy.registerLegacyMapping(1102, "forestry.speedSlow"); + legacy.registerLegacyMapping(1103, "forestry.speedNorm"); + legacy.registerLegacyMapping(1104, "forestry.speedFast"); + legacy.registerLegacyMapping(1105, "forestry.speedFaster"); + legacy.registerLegacyMapping(1106, "forestry.speedFastest"); + + // Lifespan + legacy.registerLegacyMapping(1200, "forestry.lifespanShortest"); + legacy.registerLegacyMapping(1201, "forestry.lifespanShorter"); + legacy.registerLegacyMapping(1202, "forestry.lifespanShort"); + legacy.registerLegacyMapping(1203, "forestry.lifespanShortened"); + legacy.registerLegacyMapping(1204, "forestry.lifespanNormal"); + legacy.registerLegacyMapping(1205, "forestry.lifespanElongated"); + legacy.registerLegacyMapping(1206, "forestry.lifespanLong"); + legacy.registerLegacyMapping(1207, "forestry.lifespanLonger"); + legacy.registerLegacyMapping(1208, "forestry.lifespanLongest"); + + // Fertility + legacy.registerLegacyMapping(1300, "forestry.fertilityLow"); + legacy.registerLegacyMapping(1301, "forestry.fertilityNormal"); + legacy.registerLegacyMapping(1302, "forestry.fertilityHigh"); + legacy.registerLegacyMapping(1303, "forestry.fertilityMaximum"); + + // Tolerance + legacy.registerLegacyMapping(1450, "forestry.toleranceNone"); + legacy.registerLegacyMapping(1451, "forestry.toleranceBoth1"); + legacy.registerLegacyMapping(1452, "forestry.toleranceBoth2"); + legacy.registerLegacyMapping(1453, "forestry.toleranceBoth3"); + legacy.registerLegacyMapping(1454, "forestry.toleranceBoth4"); + legacy.registerLegacyMapping(1455, "forestry.toleranceBoth5"); + legacy.registerLegacyMapping(1456, "forestry.toleranceUp1"); + legacy.registerLegacyMapping(1457, "forestry.toleranceUp2"); + legacy.registerLegacyMapping(1458, "forestry.toleranceUp3"); + legacy.registerLegacyMapping(1459, "forestry.toleranceUp4"); + legacy.registerLegacyMapping(1460, "forestry.toleranceUp5"); + legacy.registerLegacyMapping(1461, "forestry.toleranceDown1"); + legacy.registerLegacyMapping(1462, "forestry.toleranceDown2"); + legacy.registerLegacyMapping(1463, "forestry.toleranceDown3"); + legacy.registerLegacyMapping(1464, "forestry.toleranceDown4"); + legacy.registerLegacyMapping(1465, "forestry.toleranceDown5"); + + // Flower growth + legacy.registerLegacyMapping(1700, "forestry.floweringSlowest"); + legacy.registerLegacyMapping(1701, "forestry.floweringSlower"); + legacy.registerLegacyMapping(1702, "forestry.floweringSlow"); + legacy.registerLegacyMapping(1710, "forestry.floweringMaximum"); + + // Territory + legacy.registerLegacyMapping(1750, "forestry.territoryDefault"); + legacy.registerLegacyMapping(1751, "forestry.territoryLarge"); + legacy.registerLegacyMapping(1752, "forestry.territoryLarger"); + legacy.registerLegacyMapping(1753, "forestry.territoryLargest"); + + } + + @Override + public String getName() { + return StringUtil.localize(name); + } + + public Allele setName(String string) { + name = string; + return this; + } +} diff --git a/forestry_common/core/forestry/core/genetics/AlleleArea.java b/forestry_common/core/forestry/core/genetics/AlleleArea.java new file mode 100755 index 000000000..0b5d4a41f --- /dev/null +++ b/forestry_common/core/forestry/core/genetics/AlleleArea.java @@ -0,0 +1,34 @@ +/******************************************************************************* + * Copyright 2011-2014 by SirSengir + * + * This work is licensed under a Creative Commons Attribution-NonCommercial-NoDerivs 3.0 Unported License. + * + * To view a copy of this license, visit http://creativecommons.org/licenses/by-nc-nd/3.0/. + ******************************************************************************/ +package forestry.core.genetics; + +import forestry.api.genetics.IAlleleArea; +import forestry.core.utils.Vect; + +public class AlleleArea extends Allele implements IAlleleArea { + + private int[] area; + + public AlleleArea(String uid, int[] value) { + this(uid, value, false); + } + + public AlleleArea(String uid, int[] value, boolean isDominant) { + super(uid, isDominant); + this.area = value; + } + + public int[] getValue() { + return area; + } + + public Vect getArea() { + return new Vect(area); + } + +} diff --git a/forestry_common/core/forestry/core/genetics/AlleleBoolean.java b/forestry_common/core/forestry/core/genetics/AlleleBoolean.java new file mode 100755 index 000000000..cb1de069e --- /dev/null +++ b/forestry_common/core/forestry/core/genetics/AlleleBoolean.java @@ -0,0 +1,30 @@ +/******************************************************************************* + * Copyright 2011-2014 by SirSengir + * + * This work is licensed under a Creative Commons Attribution-NonCommercial-NoDerivs 3.0 Unported License. + * + * To view a copy of this license, visit http://creativecommons.org/licenses/by-nc-nd/3.0/. + ******************************************************************************/ +package forestry.core.genetics; + +import forestry.api.genetics.IAlleleBoolean; + +public class AlleleBoolean extends Allele implements IAlleleBoolean { + + boolean value; + boolean isDominant; + + public AlleleBoolean(String uid, boolean value) { + this(uid, value, false); + } + + public AlleleBoolean(String uid, boolean value, boolean isDominant) { + super(uid, isDominant); + this.value = value; + } + + public boolean getValue() { + return value; + } + +} diff --git a/forestry_common/core/forestry/core/genetics/AlleleFloat.java b/forestry_common/core/forestry/core/genetics/AlleleFloat.java new file mode 100755 index 000000000..6b9038033 --- /dev/null +++ b/forestry_common/core/forestry/core/genetics/AlleleFloat.java @@ -0,0 +1,30 @@ +/******************************************************************************* + * Copyright 2011-2014 by SirSengir + * + * This work is licensed under a Creative Commons Attribution-NonCommercial-NoDerivs 3.0 Unported License. + * + * To view a copy of this license, visit http://creativecommons.org/licenses/by-nc-nd/3.0/. + ******************************************************************************/ +package forestry.core.genetics; + +import forestry.api.genetics.IAlleleFloat; + +public class AlleleFloat extends Allele implements IAlleleFloat { + + float value; + + public AlleleFloat(String uid, float value) { + this(uid, value, false); + } + + public AlleleFloat(String uid, float value, boolean isDominant) { + super(uid, isDominant); + this.value = value; + } + + @Override + public float getValue() { + return value; + } + +} diff --git a/forestry_common/core/forestry/core/genetics/AlleleInteger.java b/forestry_common/core/forestry/core/genetics/AlleleInteger.java new file mode 100755 index 000000000..6cc5568e6 --- /dev/null +++ b/forestry_common/core/forestry/core/genetics/AlleleInteger.java @@ -0,0 +1,30 @@ +/******************************************************************************* + * Copyright 2011-2014 by SirSengir + * + * This work is licensed under a Creative Commons Attribution-NonCommercial-NoDerivs 3.0 Unported License. + * + * To view a copy of this license, visit http://creativecommons.org/licenses/by-nc-nd/3.0/. + ******************************************************************************/ +package forestry.core.genetics; + +import forestry.api.genetics.IAlleleInteger; + +public class AlleleInteger extends Allele implements IAlleleInteger { + + int value; + + public AlleleInteger(String uid, int value) { + this(uid, value, false); + } + + public AlleleInteger(String uid, int value, boolean isDominant) { + super(uid, isDominant); + this.value = value; + } + + @Override + public int getValue() { + return value; + } + +} diff --git a/forestry_common/core/forestry/core/genetics/AllelePlantType.java b/forestry_common/core/forestry/core/genetics/AllelePlantType.java new file mode 100755 index 000000000..b5b294ccb --- /dev/null +++ b/forestry_common/core/forestry/core/genetics/AllelePlantType.java @@ -0,0 +1,36 @@ +/******************************************************************************* + * Copyright 2011-2014 by SirSengir + * + * This work is licensed under a Creative Commons Attribution-NonCommercial-NoDerivs 3.0 Unported License. + * + * To view a copy of this license, visit http://creativecommons.org/licenses/by-nc-nd/3.0/. + ******************************************************************************/ +package forestry.core.genetics; + +import java.util.EnumSet; + +import net.minecraftforge.common.EnumPlantType; + +import forestry.api.genetics.IAllelePlantType; + +public class AllelePlantType extends Allele implements IAllelePlantType { + + private EnumSet types; + + protected AllelePlantType(String uid, EnumPlantType type) { + this(uid, type, false); + } + + protected AllelePlantType(String uid, EnumPlantType type, boolean isDominant) { + this(uid, EnumSet.of(type), isDominant); + } + + protected AllelePlantType(String uid, EnumSet types, boolean isDominant) { + super(uid, isDominant); + this.types = types; + } + + public EnumSet getPlantTypes() { + return types; + } +} diff --git a/forestry_common/core/forestry/core/genetics/AlleleRegistry.java b/forestry_common/core/forestry/core/genetics/AlleleRegistry.java new file mode 100755 index 000000000..a4a685826 --- /dev/null +++ b/forestry_common/core/forestry/core/genetics/AlleleRegistry.java @@ -0,0 +1,296 @@ +/******************************************************************************* + * Copyright 2011-2014 by SirSengir + * + * This work is licensed under a Creative Commons Attribution-NonCommercial-NoDerivs 3.0 Unported License. + * + * To view a copy of this license, visit http://creativecommons.org/licenses/by-nc-nd/3.0/. + ******************************************************************************/ +package forestry.core.genetics; + +import java.util.ArrayList; +import java.util.Collection; +import java.util.Collections; +import java.util.HashMap; +import java.util.HashSet; +import java.util.Iterator; +import java.util.LinkedHashMap; +import java.util.Map; +import java.util.Map.Entry; + +import net.minecraft.item.ItemStack; +import net.minecraft.world.World; + +import forestry.api.genetics.IAllele; +import forestry.api.genetics.IAlleleHandler; +import forestry.api.genetics.IAlleleRegistry; +import forestry.api.genetics.IAlleleSpecies; +import forestry.api.genetics.IClassification; +import forestry.api.genetics.IClassification.EnumClassLevel; +import forestry.api.genetics.IFruitFamily; +import forestry.api.genetics.IIndividual; +import forestry.api.genetics.ILegacyHandler; +import forestry.api.genetics.IMutation; +import forestry.api.genetics.ISpeciesRoot; +import forestry.core.config.ForestryItem; +import forestry.core.genetics.ItemResearchNote.EnumNoteType; +import forestry.core.utils.IDAllocator; + +public class AlleleRegistry implements IAlleleRegistry, ILegacyHandler { + + public static final int ALLELE_ARRAY_SIZE = 2048; + + /* SPECIES ROOT */ + private LinkedHashMap rootMap = new LinkedHashMap(16); + + @Override + public void registerSpeciesRoot(ISpeciesRoot root) { + rootMap.put(root.getUID(), root); + } + + @Override + public Map getSpeciesRoot() { + return Collections.unmodifiableMap(rootMap); + } + + @Override + public ISpeciesRoot getSpeciesRoot(String uid) { + if(rootMap.containsKey(uid)) + return rootMap.get(uid); + return null; + } + + @Override + public ISpeciesRoot getSpeciesRoot(ItemStack stack) { + for(ISpeciesRoot root : rootMap.values()) + if(root.isMember(stack)) + return root; + return null; + } + + @Override + public ISpeciesRoot getSpeciesRoot(Class clz) { + for(ISpeciesRoot root : rootMap.values()) + if(root.getMemberClass().isAssignableFrom(clz)) + return root; + return null; + } + + /* INDIVIDUALS */ + public boolean isIndividual(ItemStack stack) { + return getSpeciesRoot(stack) != null; + } + + public IIndividual getIndividual(ItemStack stack) { + ISpeciesRoot root = getSpeciesRoot(stack); + if(root == null) + return null; + + return root.getMember(stack); + } + + /* ALLELES */ + private LinkedHashMap alleleMap = new LinkedHashMap(ALLELE_ARRAY_SIZE); + private LinkedHashMap deprecatedAlleleMap = new LinkedHashMap(32); + private LinkedHashMap classificationMap = new LinkedHashMap(128); + private LinkedHashMap fruitMap = new LinkedHashMap(64); + + private HashMap metaMapToUID = new HashMap(); + private HashMap uidMapToMeta = new HashMap(); + + private HashMap legacyMap = new HashMap(); + + /* + * Internal HashSet of all alleleHandlers, which trigger when an allele or branch is registered + */ + private HashSet alleleHandlers = new HashSet(); + + public void initialize() { + + createAndRegisterClassification(EnumClassLevel.DOMAIN, "archaea", "Archaea"); + createAndRegisterClassification(EnumClassLevel.DOMAIN, "bacteria", "Bacteria"); + IClassification eukarya = createAndRegisterClassification(EnumClassLevel.DOMAIN, "eukarya", "Eukarya"); + + eukarya.addMemberGroup(createAndRegisterClassification(EnumClassLevel.KINGDOM, "animalia", "Animalia")); + eukarya.addMemberGroup(createAndRegisterClassification(EnumClassLevel.KINGDOM, "plantae", "Plantae")); + eukarya.addMemberGroup(createAndRegisterClassification(EnumClassLevel.KINGDOM, "fungi", "Fungi")); + eukarya.addMemberGroup(createAndRegisterClassification(EnumClassLevel.KINGDOM, "protista", "Protista")); + + getClassification("kingdom.animalia").addMemberGroup(createAndRegisterClassification(EnumClassLevel.PHYLUM, "arthropoda", "Arthropoda")); + + // Animalia + getClassification("phylum.arthropoda").addMemberGroup(createAndRegisterClassification(EnumClassLevel.CLASS, "insecta", "Insecta")); + + } + + @Override + public Map getRegisteredAlleles() { + return Collections.unmodifiableMap(alleleMap); + } + + @Override + public Map getDeprecatedAlleleReplacements() { + return Collections.unmodifiableMap(deprecatedAlleleMap); + } + + @Override + public void registerAllele(IAllele allele) { + alleleMap.put(allele.getUID(), allele); + if (allele instanceof IAlleleSpecies) { + IClassification branch = ((IAlleleSpecies) allele).getBranch(); + if (branch != null) + branch.addMemberSpecies((IAlleleSpecies) allele); + } + for (IAlleleHandler handler : this.alleleHandlers) + handler.onRegisterAllele(allele); + } + + @Override + public void registerDeprecatedAlleleReplacement(String deprecatedUID, IAllele replacementAllele) { + if (deprecatedAlleleMap.containsKey(deprecatedUID)) { + return; + } + + deprecatedAlleleMap.put(deprecatedUID, replacementAllele); + } + + @Override + public IAllele getAllele(String uid) { + IAllele allele = alleleMap.get(uid); + + if (allele == null) { + allele = deprecatedAlleleMap.get(uid); + } + + return allele; + } + + @Override + public void reloadMetaMap(World world) { + metaMapToUID.clear(); + uidMapToMeta.clear(); + + Iterator> it = alleleMap.entrySet().iterator(); + while (it.hasNext()) { + Entry entry = it.next(); + if (!(entry.getValue() instanceof IAlleleSpecies)) + continue; + + int meta = IDAllocator.getIDAllocator(world, "speciesMetaMap").getId(entry.getKey()); + metaMapToUID.put(meta, entry.getKey()); + uidMapToMeta.put(entry.getKey(), meta); + + } + } + + @Override + public IAllele getFromMetaMap(int meta) { + if (!metaMapToUID.containsKey(meta)) + return null; + + return getAllele(metaMapToUID.get(meta)); + } + + @Override + public int getFromUIDMap(String uid) { + if (!uidMapToMeta.containsKey(uid)) + return 0; + + return uidMapToMeta.get(uid); + } + + /* CLASSIFICATIONS */ + @Override + public void registerClassification(IClassification branch) { + + if (classificationMap.containsKey(branch.getUID())) + throw new RuntimeException(String.format("Could not add new classification '%s', because the key is already taken by %s.", branch.getUID(), + classificationMap.get(branch.getUID()))); + + classificationMap.put(branch.getUID(), branch); + for (IAlleleHandler handler : this.alleleHandlers) + handler.onRegisterClassification(branch); + } + + @Override + public Map getRegisteredClassifications() { + return Collections.unmodifiableMap(classificationMap); + } + + @Override + public IClassification createAndRegisterClassification(EnumClassLevel level, String uid, String scientific) { + return new Classification(level, uid, scientific); + } + + @Override + public IClassification getClassification(String uid) { + return classificationMap.get(uid); + } + + /* FRUIT FAMILIES */ + @Override + public void registerFruitFamily(IFruitFamily family) { + fruitMap.put(family.getUID(), family); + for (IAlleleHandler handler : this.alleleHandlers) + handler.onRegisterFruitFamily(family); + } + + @Override + public Map getRegisteredFruitFamilies() { + return Collections.unmodifiableMap(fruitMap); + } + + @Override + public IFruitFamily getFruitFamily(String uid) { + return fruitMap.get(uid); + } + + /* LEGACY MAPPINGS */ + @Override + public void registerLegacyMapping(int id, String uid) { + this.legacyMap.put(id, uid); + } + + @Override + public IAllele getFromLegacyMap(int id) { + if (!legacyMap.containsKey(id)) + return null; + + return getAllele(legacyMap.get(id)); + } + + /* ALLELE HANDLERS */ + @Override + public void registerAlleleHandler(IAlleleHandler handler) { + this.alleleHandlers.add(handler); + } + + /* BLACKLIST */ + private ArrayList blacklist = new ArrayList(); + + @Override + public void blacklistAllele(String uid) { + blacklist.add(uid); + } + + @Override + public Collection getAlleleBlacklist() { + return Collections.unmodifiableCollection(blacklist); + } + + @Override + public boolean isBlacklisted(String uid) { + return blacklist.contains(uid); + } + + /* RESEARCH */ + @Override + public ItemStack getSpeciesNoteStack(String researcher, IAlleleSpecies species) { + return EnumNoteType.createSpeciesNoteStack(ForestryItem.researchNote.item(), researcher, species); + } + + @Override + public ItemStack getMutationNoteStack(String researcher, IMutation mutation) { + return EnumNoteType.createMutationNoteStack(ForestryItem.researchNote.item(), researcher, mutation); + } + +} diff --git a/forestry_common/core/forestry/core/genetics/AlleleSpecies.java b/forestry_common/core/forestry/core/genetics/AlleleSpecies.java new file mode 100755 index 000000000..14255a662 --- /dev/null +++ b/forestry_common/core/forestry/core/genetics/AlleleSpecies.java @@ -0,0 +1,187 @@ +/******************************************************************************* + * Copyright 2011-2014 by SirSengir + * + * This work is licensed under a Creative Commons Attribution-NonCommercial-NoDerivs 3.0 Unported License. + * + * To view a copy of this license, visit http://creativecommons.org/licenses/by-nc-nd/3.0/. + ******************************************************************************/ +package forestry.core.genetics; + +import java.util.Collection; +import java.util.Map; + +import net.minecraft.item.ItemStack; +import net.minecraft.world.World; + +import cpw.mods.fml.relauncher.Side; +import cpw.mods.fml.relauncher.SideOnly; + +import forestry.api.core.EnumHumidity; +import forestry.api.core.EnumTemperature; +import forestry.api.core.IIconProvider; +import forestry.api.genetics.AlleleManager; +import forestry.api.genetics.IAlleleSpecies; +import forestry.api.genetics.IClassification; +import forestry.api.genetics.IIndividual; +import forestry.api.genetics.IMutation; +import forestry.core.config.ForestryItem; +import forestry.core.utils.Localization; +import forestry.core.utils.StackUtils; +import forestry.core.utils.StringUtil; + +public abstract class AlleleSpecies extends Allele implements IAlleleSpecies { + + private String name; + private String binomial; + private String description = null; + private int complexity = 3; + private boolean hasEffect = false; + private boolean isSecret = false; + private boolean isCounted = true; + private IClassification branch = null; + private EnumTemperature climate = EnumTemperature.NORMAL; + private EnumHumidity humidity = EnumHumidity.NORMAL; + + public AlleleSpecies(String uid, boolean isDominant, String name, IClassification branch, String binomial) { + super(uid, isDominant, true); + + this.branch = branch; + this.name = name; + this.binomial = binomial; + + if (Localization.instance.hasMapping("description." + uid)) + description = StringUtil.localize("description." + uid); + + AlleleManager.alleleRegistry.registerAllele(this); + } + + @Override + public String getName() { + return StringUtil.localize(name); + } + + @Override + public String getDescription() { + return description; + } + + @Override + public int getComplexity() { + return complexity; + } + + @Override + public float getResearchSuitability(ItemStack itemstack) { + if (itemstack == null) + return 0f; + + if (ForestryItem.honeyDrop.isItemEqual(itemstack)) + return 0.5f; + else if (ForestryItem.honeydew.isItemEqual(itemstack)) + return 0.7f; + else if (ForestryItem.beeComb.isItemEqual(itemstack)) + return 0.4f; + else if (AlleleManager.alleleRegistry.isIndividual(itemstack)) + return 1.0f; + + for (Map.Entry entry : getRoot().getResearchCatalysts().entrySet()) { + if (StackUtils.isIdenticalItem(entry.getKey(), itemstack)) + return entry.getValue(); + } + + return 0f; + } + + @Override + public ItemStack[] getResearchBounty(World world, String researcher, IIndividual individual, int bountyLevel) { + + ItemStack research = null; + if (world.rand.nextFloat() < ((float) 10 / bountyLevel)) { + Collection combinations = getRoot().getCombinations(this); + if (combinations.size() > 0) { + IMutation[] candidates = combinations.toArray(new IMutation[0]); + research = AlleleManager.alleleRegistry.getMutationNoteStack(researcher, candidates[world.rand.nextInt(candidates.length)]); + } + } + + if (research != null) + return new ItemStack[] { research }; + else + return StackUtils.EMPTY_STACK_ARRAY; + + } + + @Override + public EnumTemperature getTemperature() { + return climate; + } + + @Override + public EnumHumidity getHumidity() { + return humidity; + } + + @Override + public boolean hasEffect() { + return hasEffect; + } + + @Override + public boolean isSecret() { + return isSecret; + } + + @Override + public boolean isCounted() { + return isCounted; + } + + @Override + public String getBinomial() { + return binomial; + } + + @Override + public String getAuthority() { + return "Sengir"; + } + + @Override + public IClassification getBranch() { + return this.branch; + } + + public AlleleSpecies setComplexity(int complexity) { + this.complexity = complexity; + return this; + } + + public AlleleSpecies setTemperature(EnumTemperature temperature) { + climate = temperature; + return this; + } + + public AlleleSpecies setHumidity(EnumHumidity humidity) { + this.humidity = humidity; + return this; + } + + public AlleleSpecies setHasEffect() { + hasEffect = true; + return this; + } + + public AlleleSpecies setIsSecret() { + isSecret = true; + return this; + } + + public AlleleSpecies setIsNotCounted() { + isCounted = false; + return this; + } + + @Override + @SideOnly(Side.CLIENT) + public abstract IIconProvider getIconProvider(); +} diff --git a/forestry_common/core/forestry/core/genetics/AlleleTolerance.java b/forestry_common/core/forestry/core/genetics/AlleleTolerance.java new file mode 100755 index 000000000..d43b746d0 --- /dev/null +++ b/forestry_common/core/forestry/core/genetics/AlleleTolerance.java @@ -0,0 +1,70 @@ +/******************************************************************************* + * Copyright 2011-2014 by SirSengir + * + * This work is licensed under a Creative Commons Attribution-NonCommercial-NoDerivs 3.0 Unported License. + * + * To view a copy of this license, visit http://creativecommons.org/licenses/by-nc-nd/3.0/. + ******************************************************************************/ +package forestry.core.genetics; + +import forestry.api.genetics.EnumTolerance; +import forestry.api.genetics.IAlleleTolerance; + +public class AlleleTolerance extends Allele implements IAlleleTolerance { + + EnumTolerance value; + + public AlleleTolerance(String uid, EnumTolerance value) { + this(uid, value, false); + } + + public AlleleTolerance(String uid, EnumTolerance value, boolean isDominant) { + super(uid, isDominant); + this.value = value; + } + + public EnumTolerance getValue() { + return value; + } + + public String getName() { + switch(value) { + case BOTH_1: + return "Both 1"; + case BOTH_2: + return "Both 2"; + case BOTH_3: + return "Both 3"; + case BOTH_4: + return "Both 4"; + case BOTH_5: + return "Both 5"; + case DOWN_1: + return "Down 1"; + case DOWN_2: + return "Down 2"; + case DOWN_3: + return "Down 3"; + case DOWN_4: + return "Down 4"; + case DOWN_5: + return "Down 5"; + case NONE: + return "None"; + case UP_1: + return "Up 1"; + case UP_2: + return "Up 2"; + case UP_3: + return "Up 3"; + case UP_4: + return "Up 4"; + case UP_5: + return "Up 5"; + default: + return ""; + + } + } + +} diff --git a/forestry_common/core/forestry/core/genetics/Branch.java b/forestry_common/core/forestry/core/genetics/Branch.java new file mode 100755 index 000000000..a13c77898 --- /dev/null +++ b/forestry_common/core/forestry/core/genetics/Branch.java @@ -0,0 +1,16 @@ +/******************************************************************************* + * Copyright 2011-2014 by SirSengir + * + * This work is licensed under a Creative Commons Attribution-NonCommercial-NoDerivs 3.0 Unported License. + * + * To view a copy of this license, visit http://creativecommons.org/licenses/by-nc-nd/3.0/. + ******************************************************************************/ +package forestry.core.genetics; + +public class Branch extends Classification { + + public Branch(String uid, String scientific) { + super(EnumClassLevel.GENUS, uid, scientific); + } + +} diff --git a/forestry_common/core/forestry/core/genetics/BreedingTracker.java b/forestry_common/core/forestry/core/genetics/BreedingTracker.java new file mode 100755 index 000000000..c7ef359ea --- /dev/null +++ b/forestry_common/core/forestry/core/genetics/BreedingTracker.java @@ -0,0 +1,178 @@ +/******************************************************************************* + * Copyright 2011-2014 by SirSengir + * + * This work is licensed under a Creative Commons Attribution-NonCommercial-NoDerivs 3.0 Unported License. + * + * To view a copy of this license, visit http://creativecommons.org/licenses/by-nc-nd/3.0/. + ******************************************************************************/ +package forestry.core.genetics; + +import java.util.ArrayList; + +import net.minecraft.entity.player.EntityPlayer; +import net.minecraft.nbt.NBTTagCompound; +import net.minecraft.world.WorldSavedData; + +import net.minecraftforge.common.MinecraftForge; + +import forestry.api.core.ForestryEvent; +import forestry.api.genetics.AlleleManager; +import forestry.api.genetics.IAllele; +import forestry.api.genetics.IAlleleSpecies; +import forestry.api.genetics.IBreedingTracker; +import forestry.api.genetics.IIndividual; +import forestry.api.genetics.IMutation; +import forestry.core.network.PacketIds; +import forestry.core.network.PacketNBT; +import forestry.core.proxy.Proxies; + +public abstract class BreedingTracker extends WorldSavedData implements IBreedingTracker { + + private ArrayList discoveredSpecies = new ArrayList(); + private ArrayList discoveredMutations = new ArrayList(); + private String modeName; + + String username; + + public BreedingTracker(String s, String username) { + super(s); + this.username = username; + } + + @Override + public String getModeName() { + return modeName; + } + + @Override + public void setModeName(String name) { + this.modeName = name; + markDirty(); + } + + /** + * Returns the common tracker + * + * @param player + * used to get worldObj + * @return common tracker for this breeding system + */ + protected abstract IBreedingTracker getCommonTracker(EntityPlayer player); + + /** + * Tag stored in NBT to identify the type of the tracker being synced + */ + protected abstract String getPacketTag(); + + @Override + public void synchToPlayer(EntityPlayer player) { + setModeName(getCommonTracker(player).getModeName()); + NBTTagCompound nbttagcompound = new NBTTagCompound(); + encodeToNBT(nbttagcompound); + Proxies.net.sendToPlayer(new PacketNBT(PacketIds.GENOME_TRACKER_UPDATE, nbttagcompound), player); + } + + /* HELPER FUNCTIONS TO PREVENT OBFUSCATION OF INTERFACE METHODS */ + @Override + public void decodeFromNBT(NBTTagCompound nbttagcompound) { + readFromNBT(nbttagcompound); + } + + @Override + public void encodeToNBT(NBTTagCompound nbttagcompound) { + writeToNBT(nbttagcompound); + } + + @Override + public void readFromNBT(NBTTagCompound nbttagcompound) { + + if (nbttagcompound.hasKey("BMS")) + modeName = nbttagcompound.getString("BMS"); + + // / SPECIES + discoveredSpecies = new ArrayList(); + int count = nbttagcompound.getInteger("SpeciesCount"); + for (int i = 0; i < count; i++) + discoveredSpecies.add(nbttagcompound.getString("SD" + i)); + + // / MUTATIONS + discoveredMutations = new ArrayList(); + count = nbttagcompound.getInteger("MutationsCount"); + for (int i = 0; i < count; i++) + discoveredMutations.add(nbttagcompound.getString("MD" + i)); + + } + + @Override + public void writeToNBT(NBTTagCompound nbttagcompound) { + + if (modeName != null && !modeName.isEmpty()) + nbttagcompound.setString("BMS", modeName); + + nbttagcompound.setString("TYPE", getPacketTag()); + + // / SPECIES + nbttagcompound.setInteger("SpeciesCount", discoveredSpecies.size()); + for (int i = 0; i < discoveredSpecies.size(); i++) + if (discoveredSpecies.get(i) != null) + nbttagcompound.setString("SD" + i, discoveredSpecies.get(i)); + + // / MUTATIONS + nbttagcompound.setInteger("MutationsCount", discoveredMutations.size()); + for (int i = 0; i < discoveredMutations.size(); i++) + if (discoveredMutations.get(i) != null) + nbttagcompound.setString("MD" + i, discoveredMutations.get(i)); + + } + + private static final String MUTATION_FORMAT = "%s-%s=%s"; + @Override + public void registerMutation(IMutation mutation) { + discoveredMutations.add(String.format(MUTATION_FORMAT, mutation.getAllele0().getUID(), mutation.getAllele1().getUID(), mutation.getTemplate()[0].getUID())); + markDirty(); + MinecraftForge.EVENT_BUS.post(new ForestryEvent.MutationDiscovered( + AlleleManager.alleleRegistry.getSpeciesRoot(this.getPacketTag()), + username, + mutation, this)); + } + + @Override + public void registerMutation(IAllele allele0, IAllele allele1) { + discoveredMutations.add(allele0.getUID() + "-" + allele1.getUID()); + markDirty(); + } + + @Override + public boolean isDiscovered(IMutation mutation) { + return discoveredMutations.contains(String.format(MUTATION_FORMAT, mutation.getAllele0().getUID(), mutation.getAllele1().getUID(), mutation.getTemplate()[0].getUID())) + || discoveredMutations.contains(mutation.getAllele0().getUID() + "-" + mutation.getAllele1().getUID()); + } + + @Override + public boolean isDiscovered(IAlleleSpecies species) { + return discoveredSpecies.contains(species.getUID()); + } + + @Override + public int getSpeciesBred() { + return discoveredSpecies.size(); + } + + @Override + public void registerBirth(IIndividual individual) { + registerSpecies(individual.getGenome().getPrimary()); + registerSpecies(individual.getGenome().getSecondary()); + } + + @Override + public void registerSpecies(IAlleleSpecies species) { + if (!discoveredSpecies.contains(species.getUID())) { + discoveredSpecies.add(species.getUID()); + MinecraftForge.EVENT_BUS.post(new ForestryEvent.SpeciesDiscovered( + AlleleManager.alleleRegistry.getSpeciesRoot(this.getPacketTag()), + username, + species, this)); + } + } + +} diff --git a/forestry_common/core/forestry/core/genetics/Chromosome.java b/forestry_common/core/forestry/core/genetics/Chromosome.java new file mode 100755 index 000000000..95ee20bba --- /dev/null +++ b/forestry_common/core/forestry/core/genetics/Chromosome.java @@ -0,0 +1,137 @@ +/******************************************************************************* + * Copyright 2011-2014 by SirSengir + * + * This work is licensed under a Creative Commons Attribution-NonCommercial-NoDerivs 3.0 Unported License. + * + * To view a copy of this license, visit http://creativecommons.org/licenses/by-nc-nd/3.0/. + ******************************************************************************/ +package forestry.core.genetics; + +import java.util.Random; + +import net.minecraft.nbt.NBTTagCompound; + +import forestry.api.genetics.AlleleManager; +import forestry.api.genetics.IAllele; +import forestry.api.genetics.IChromosome; +import forestry.api.genetics.ILegacyHandler; + +public class Chromosome implements IChromosome { + + private static final String UID0_TAG = "UID0"; + private static final String UID1_TAG = "UID1"; + + private IAllele primary; + private IAllele secondary; + + // / CONSTRUCTOR + private Chromosome() { + } + + public Chromosome(IAllele allele) { + primary = secondary = allele; + } + + public Chromosome(IAllele primary, IAllele secondary) { + this.primary = primary; + this.secondary = secondary; + } + + // / SAVING & LOADING + @Override + public void readFromNBT(NBTTagCompound nbttagcompound) { + + // Legacy + if (nbttagcompound.hasKey("PrimaryId")) { + primary = ((ILegacyHandler) AlleleManager.alleleRegistry).getFromLegacyMap(nbttagcompound.getInteger("PrimaryId")); + secondary = ((ILegacyHandler) AlleleManager.alleleRegistry).getFromLegacyMap(nbttagcompound.getInteger("SecondaryId")); + + if (primary == null || secondary == null) + throw new RuntimeException("Legacy conversion of chromosome failed. Did one of your bee addons not update? No legacy mapping for ids: " + + nbttagcompound.getInteger("PrimaryId") + " - " + nbttagcompound.getInteger("SecondaryId")); + + return; + } + + primary = AlleleManager.alleleRegistry.getAllele(nbttagcompound.getString(UID0_TAG)); + secondary = AlleleManager.alleleRegistry.getAllele(nbttagcompound.getString(UID1_TAG)); + } + + @Override + public void writeToNBT(NBTTagCompound nbttagcompound) { + nbttagcompound.setString(UID0_TAG, primary.getUID()); + nbttagcompound.setString(UID1_TAG, secondary.getUID()); + } + + @Override + public IAllele getPrimaryAllele() { + return primary; + } + + @Override + public IAllele getSecondaryAllele() { + return secondary; + } + + @Override + public IAllele getActiveAllele() { + if (primary.isDominant()) + return primary; + if (secondary.isDominant()) + return secondary; + // Leaves only the case of both being recessive + return primary; + } + + @Override + public IAllele getInactiveAllele() { + if (!secondary.isDominant()) + return secondary; + if (!primary.isDominant()) + return primary; + // Leaves only the case of both being dominant + return secondary; + } + + public IAllele getRandomAllele(Random rand) { + if (rand.nextBoolean()) + return primary; + else + return secondary; + } + + public void overrideInvalidAlleles(IAllele template, Class chromosomeClass) { + if (primary == null || !chromosomeClass.isInstance(primary)) + primary = template; + if (secondary == null || !chromosomeClass.isInstance(secondary)) + secondary = template; + } + + /* HELPER FUNCTIONS */ + public static Chromosome loadChromosomeFromNBT(NBTTagCompound compound) { + Chromosome chromosome = new Chromosome(); + chromosome.readFromNBT(compound); + return chromosome; + } + + public static IChromosome inheritChromosome(Random rand, IChromosome parent1, IChromosome parent2) { + + IAllele choice1; + if (rand.nextBoolean()) + choice1 = parent1.getPrimaryAllele(); + else + choice1 = parent1.getSecondaryAllele(); + + IAllele choice2; + if (rand.nextBoolean()) + choice2 = parent2.getPrimaryAllele(); + else + choice2 = parent2.getSecondaryAllele(); + + if (rand.nextBoolean()) + return new Chromosome(choice1, choice2); + else + return new Chromosome(choice2, choice1); + } + +} diff --git a/forestry_common/core/forestry/core/genetics/Classification.java b/forestry_common/core/forestry/core/genetics/Classification.java new file mode 100755 index 000000000..fdcdaf480 --- /dev/null +++ b/forestry_common/core/forestry/core/genetics/Classification.java @@ -0,0 +1,92 @@ +/******************************************************************************* + * Copyright 2011-2014 by SirSengir + * + * This work is licensed under a Creative Commons Attribution-NonCommercial-NoDerivs 3.0 Unported License. + * + * To view a copy of this license, visit http://creativecommons.org/licenses/by-nc-nd/3.0/. + ******************************************************************************/ +package forestry.core.genetics; + +import java.util.ArrayList; +import java.util.Locale; + +import forestry.api.genetics.AlleleManager; +import forestry.api.genetics.IAlleleSpecies; +import forestry.api.genetics.IClassification; +import forestry.core.utils.StringUtil; + +public class Classification implements IClassification { + + private EnumClassLevel level; + private String uid; + private String scientific; + + private IClassification parent; + + private ArrayList members = new ArrayList(); + private ArrayList groups = new ArrayList(); + + public Classification(EnumClassLevel level, String uid, String scientific) { + this.level = level; + this.uid = level.name().toLowerCase(Locale.ENGLISH) + "." + uid; + this.scientific = scientific; + AlleleManager.alleleRegistry.registerClassification(this); + } + + @Override + public EnumClassLevel getLevel() { + return level; + } + + @Override + public String getUID() { + return uid; + } + + @Override + public IClassification getParent() { + return parent; + } + + @Override + public void setParent(IClassification parent) { + this.parent = parent; + } + + @Override + public String getScientific() { + return this.scientific; + } + + @Override + public String getName() { + return StringUtil.localize(uid); + } + + @Override + public String getDescription() { + return StringUtil.localize(uid + ".description"); + } + + @Override + public IClassification[] getMemberGroups() { + return groups.toArray(new IClassification[0]); + } + + @Override + public void addMemberGroup(IClassification group) { + groups.add(group); + group.setParent(this); + } + + @Override + public IAlleleSpecies[] getMemberSpecies() { + return members.toArray(new IAlleleSpecies[0]); + } + + @Override + public void addMemberSpecies(IAlleleSpecies species) { + members.add(species); + } + +} diff --git a/forestry_common/core/forestry/core/genetics/ClimateHelper.java b/forestry_common/core/forestry/core/genetics/ClimateHelper.java new file mode 100755 index 000000000..15b726f0a --- /dev/null +++ b/forestry_common/core/forestry/core/genetics/ClimateHelper.java @@ -0,0 +1,159 @@ +/******************************************************************************* + * Copyright 2011-2014 by SirSengir + * + * This work is licensed under a Creative Commons Attribution-NonCommercial-NoDerivs 3.0 Unported License. + * + * To view a copy of this license, visit http://creativecommons.org/licenses/by-nc-nd/3.0/. + ******************************************************************************/ +package forestry.core.genetics; + +import java.util.ArrayList; +import java.util.Locale; + +import forestry.api.core.EnumHumidity; +import forestry.api.core.EnumTemperature; +import forestry.api.genetics.EnumTolerance; +import forestry.core.utils.StringUtil; + +public class ClimateHelper { + + public static boolean isWithinLimits(EnumTemperature temperature, EnumHumidity humidity, + EnumTemperature baseTemp, EnumTolerance tolTemp, + EnumHumidity baseHumid, EnumTolerance tolHumid) { + if(!getToleratedTemperature(baseTemp, tolTemp).contains(temperature)) + return false; + + return getToleratedHumidity(baseHumid, tolHumid).contains(humidity); + } + + public static ArrayList getToleratedHumidity(EnumHumidity prefered, EnumTolerance tolerance) { + + ArrayList tolerated = new ArrayList(); + tolerated.add(prefered); + + switch (tolerance) { + + case BOTH_5: + case BOTH_4: + case BOTH_3: + case BOTH_2: + if (prefered.ordinal() + 2 < EnumHumidity.values().length) + tolerated.add(EnumHumidity.values()[prefered.ordinal() + 2]); + if (prefered.ordinal() - 2 >= 0) + tolerated.add(EnumHumidity.values()[prefered.ordinal() - 2]); + case BOTH_1: + if (prefered.ordinal() + 1 < EnumHumidity.values().length) + tolerated.add(EnumHumidity.values()[prefered.ordinal() + 1]); + if (prefered.ordinal() - 1 >= 0) + tolerated.add(EnumHumidity.values()[prefered.ordinal() - 1]); + return tolerated; + + case UP_5: + case UP_4: + case UP_3: + case UP_2: + if (prefered.ordinal() + 2 < EnumHumidity.values().length) + tolerated.add(EnumHumidity.values()[prefered.ordinal() + 2]); + case UP_1: + if (prefered.ordinal() + 1 < EnumHumidity.values().length) + tolerated.add(EnumHumidity.values()[prefered.ordinal() + 1]); + return tolerated; + + case DOWN_5: + case DOWN_4: + case DOWN_3: + case DOWN_2: + if (prefered.ordinal() - 2 >= 0) + tolerated.add(EnumHumidity.values()[prefered.ordinal() - 2]); + case DOWN_1: + if (prefered.ordinal() - 1 >= 0) + tolerated.add(EnumHumidity.values()[prefered.ordinal() - 1]); + return tolerated; + + default: + return tolerated; + } + + } + + public static ArrayList getToleratedTemperature(EnumTemperature prefered, EnumTolerance tolerance) { + + ArrayList tolerated = new ArrayList(); + tolerated.add(prefered); + + switch (tolerance) { + + case BOTH_5: + if (prefered.ordinal() + 5 < EnumTemperature.values().length) + tolerated.add(EnumTemperature.values()[prefered.ordinal() + 5]); + if (prefered.ordinal() - 5 >= 0) + tolerated.add(EnumTemperature.values()[prefered.ordinal() - 5]); + case BOTH_4: + if (prefered.ordinal() + 4 < EnumTemperature.values().length) + tolerated.add(EnumTemperature.values()[prefered.ordinal() + 4]); + if (prefered.ordinal() - 4 >= 0) + tolerated.add(EnumTemperature.values()[prefered.ordinal() - 4]); + case BOTH_3: + if (prefered.ordinal() + 3 < EnumTemperature.values().length) + tolerated.add(EnumTemperature.values()[prefered.ordinal() + 3]); + if (prefered.ordinal() - 3 >= 0) + tolerated.add(EnumTemperature.values()[prefered.ordinal() - 3]); + case BOTH_2: + if (prefered.ordinal() + 2 < EnumTemperature.values().length) + tolerated.add(EnumTemperature.values()[prefered.ordinal() + 2]); + if (prefered.ordinal() - 2 >= 0) + tolerated.add(EnumTemperature.values()[prefered.ordinal() - 2]); + case BOTH_1: + if (prefered.ordinal() + 1 < EnumTemperature.values().length) + tolerated.add(EnumTemperature.values()[prefered.ordinal() + 1]); + if (prefered.ordinal() - 1 >= 0) + tolerated.add(EnumTemperature.values()[prefered.ordinal() - 1]); + return tolerated; + + case UP_5: + if (prefered.ordinal() + 5 < EnumTemperature.values().length) + tolerated.add(EnumTemperature.values()[prefered.ordinal() + 5]); + case UP_4: + if (prefered.ordinal() + 4 < EnumTemperature.values().length) + tolerated.add(EnumTemperature.values()[prefered.ordinal() + 4]); + case UP_3: + if (prefered.ordinal() + 3 < EnumTemperature.values().length) + tolerated.add(EnumTemperature.values()[prefered.ordinal() + 3]); + case UP_2: + if (prefered.ordinal() + 2 < EnumTemperature.values().length) + tolerated.add(EnumTemperature.values()[prefered.ordinal() + 2]); + case UP_1: + if (prefered.ordinal() + 1 < EnumTemperature.values().length) + tolerated.add(EnumTemperature.values()[prefered.ordinal() + 1]); + return tolerated; + + case DOWN_5: + if (prefered.ordinal() - 5 >= 0) + tolerated.add(EnumTemperature.values()[prefered.ordinal() - 5]); + case DOWN_4: + if (prefered.ordinal() - 4 >= 0) + tolerated.add(EnumTemperature.values()[prefered.ordinal() - 4]); + case DOWN_3: + if (prefered.ordinal() - 3 >= 0) + tolerated.add(EnumTemperature.values()[prefered.ordinal() - 3]); + case DOWN_2: + if (prefered.ordinal() - 2 >= 0) + tolerated.add(EnumTemperature.values()[prefered.ordinal() - 2]); + case DOWN_1: + if (prefered.ordinal() - 1 >= 0) + tolerated.add(EnumTemperature.values()[prefered.ordinal() - 1]); + return tolerated; + + default: + return tolerated; + } + } + + public static String toDisplay(EnumTemperature temperature) { + return StringUtil.localize("gui." + temperature.toString().toLowerCase(Locale.ENGLISH)); + } + + public static String toDisplay(EnumHumidity humidity) { + return StringUtil.localize("gui." + humidity.toString().toLowerCase(Locale.ENGLISH)); + } +} diff --git a/forestry_common/core/forestry/core/genetics/EffectData.java b/forestry_common/core/forestry/core/genetics/EffectData.java new file mode 100755 index 000000000..71bece2d6 --- /dev/null +++ b/forestry_common/core/forestry/core/genetics/EffectData.java @@ -0,0 +1,66 @@ +/******************************************************************************* + * Copyright 2011-2014 by SirSengir + * + * This work is licensed under a Creative Commons Attribution-NonCommercial-NoDerivs 3.0 Unported License. + * + * To view a copy of this license, visit http://creativecommons.org/licenses/by-nc-nd/3.0/. + ******************************************************************************/ +package forestry.core.genetics; + +import net.minecraft.nbt.NBTTagCompound; + +import forestry.api.genetics.IEffectData; + +public class EffectData implements IEffectData { + + private int[] intData; + private float[] floatData; + private boolean[] boolData; + + public EffectData(int intSize, int boolSize) { + this.intData = new int[intSize]; + this.boolData = new boolean[boolSize]; + } + + @Override + public void setInteger(int index, int val) { + intData[index] = val; + } + + @Override + public void setBoolean(int index, boolean val) { + boolData[index] = val; + } + + @Override + public int getInteger(int index) { + return intData[index]; + } + + @Override + public boolean getBoolean(int index) { + return boolData[index]; + } + + public int getIntSize() { + return intData.length; + } + + @Override + public void setFloat(int index, float val) { + floatData[index] = val; + } + + @Override + public float getFloat(int index) { + return floatData[index]; + } + + @Override + public void readFromNBT(NBTTagCompound nbttagcompound) { + } + + @Override + public void writeToNBT(NBTTagCompound nbttagcompound) { + } +} diff --git a/forestry_common/core/forestry/core/genetics/EnumMutateChance.java b/forestry_common/core/forestry/core/genetics/EnumMutateChance.java new file mode 100755 index 000000000..fe87c3eea --- /dev/null +++ b/forestry_common/core/forestry/core/genetics/EnumMutateChance.java @@ -0,0 +1,35 @@ +/******************************************************************************* + * Copyright 2011-2014 by SirSengir + * + * This work is licensed under a Creative Commons Attribution-NonCommercial-NoDerivs 3.0 Unported License. + * + * To view a copy of this license, visit http://creativecommons.org/licenses/by-nc-nd/3.0/. + ******************************************************************************/ +package forestry.core.genetics; + +public enum EnumMutateChance { + NONE(0xffffff), LOWEST(0xffba77), LOW(0xfffd77), NORMAL(0xfffd77), HIGH(0xfffd77), HIGHER(0xbeff77), HIGHEST(0x7bff77); + + public final int colour; + + private EnumMutateChance(int colour) { + this.colour = colour; + } + + public static EnumMutateChance rateChance(float percent) { + + if (percent >= 20) + return HIGHEST; + else if (percent >= 15) + return HIGHER; + else if (percent >= 12) + return HIGH; + else if (percent >= 10) + return NORMAL; + else if (percent >= 5) + return LOW; + else + return LOWEST; + + } +} diff --git a/forestry_common/core/forestry/core/genetics/FruitFamily.java b/forestry_common/core/forestry/core/genetics/FruitFamily.java new file mode 100755 index 000000000..52a1845e5 --- /dev/null +++ b/forestry_common/core/forestry/core/genetics/FruitFamily.java @@ -0,0 +1,45 @@ +/******************************************************************************* + * Copyright 2011-2014 by SirSengir + * + * This work is licensed under a Creative Commons Attribution-NonCommercial-NoDerivs 3.0 Unported License. + * + * To view a copy of this license, visit http://creativecommons.org/licenses/by-nc-nd/3.0/. + ******************************************************************************/ +package forestry.core.genetics; + +import forestry.api.genetics.AlleleManager; +import forestry.api.genetics.IFruitFamily; +import forestry.core.utils.StringUtil; + +public class FruitFamily implements IFruitFamily { + + private String uid; + private String scientific; + + public FruitFamily(String uid, String scientific) { + this.uid = uid; + this.scientific = scientific; + AlleleManager.alleleRegistry.registerFruitFamily(this); + } + + @Override + public String getUID() { + return "forestry." + uid; + } + + @Override + public String getScientific() { + return this.scientific; + } + + @Override + public String getName() { + return StringUtil.localize("family." + uid); + } + + @Override + public String getDescription() { + return null; + } + +} diff --git a/forestry_common/core/forestry/core/genetics/GenericRatings.java b/forestry_common/core/forestry/core/genetics/GenericRatings.java new file mode 100755 index 000000000..95ec88a88 --- /dev/null +++ b/forestry_common/core/forestry/core/genetics/GenericRatings.java @@ -0,0 +1,38 @@ +/******************************************************************************* + * Copyright 2011-2014 by SirSengir + * + * This work is licensed under a Creative Commons Attribution-NonCommercial-NoDerivs 3.0 Unported License. + * + * To view a copy of this license, visit http://creativecommons.org/licenses/by-nc-nd/3.0/. + ******************************************************************************/ +package forestry.core.genetics; + +import forestry.core.utils.StringUtil; + +public class GenericRatings { + + public static String rateMetabolism(int metabolism) { + if (metabolism >= 19) + return StringUtil.localize("gui.highest"); + else if (metabolism >= 16) + return StringUtil.localize("gui.higher"); + else if (metabolism >= 13) + return StringUtil.localize("gui.high"); + else if (metabolism >= 10) + return StringUtil.localize("gui.average"); + else if (metabolism >= 7) + return StringUtil.localize("gui.slow"); + else if (metabolism >= 4) + return StringUtil.localize("gui.slower"); + else + return StringUtil.localize("gui.slowest"); + } + + public static String rateActivityTime(boolean nocturnalTrait, boolean naturalNocturnal) { + String active = naturalNocturnal ? StringUtil.localize("gui.nocturnal") : StringUtil.localize("gui.diurnal"); + if(nocturnalTrait) + active = StringUtil.append(", ", active, naturalNocturnal ? StringUtil.localize("gui.diurnal") : StringUtil.localize("gui.nocturnal")); + + return active; + } +} diff --git a/forestry_common/core/forestry/core/genetics/Genome.java b/forestry_common/core/forestry/core/genetics/Genome.java new file mode 100755 index 000000000..616549576 --- /dev/null +++ b/forestry_common/core/forestry/core/genetics/Genome.java @@ -0,0 +1,112 @@ +/******************************************************************************* + * Copyright 2011-2014 by SirSengir + * + * This work is licensed under a Creative Commons Attribution-NonCommercial-NoDerivs 3.0 Unported License. + * + * To view a copy of this license, visit http://creativecommons.org/licenses/by-nc-nd/3.0/. + ******************************************************************************/ +package forestry.core.genetics; + +import net.minecraft.nbt.NBTTagCompound; +import net.minecraft.nbt.NBTTagList; + +import forestry.api.genetics.IAllele; +import forestry.api.genetics.IChromosome; +import forestry.api.genetics.IGenome; +import forestry.core.config.Config; + +public abstract class Genome implements IGenome { + + private static final String SLOT_TAG = "Slot"; + + private IChromosome[] chromosomes; + + // / CONSTRUCTOR + public Genome(NBTTagCompound nbttagcompound) { + this.chromosomes = new Chromosome[getDefaultTemplate().length]; + readFromNBT(nbttagcompound); + } + + private IAllele[] getDefaultTemplate() { + return getSpeciesRoot().getDefaultTemplate(); + } + + public Genome(IChromosome[] chromosomes) { + if(chromosomes.length != getDefaultTemplate().length) + throw new IllegalArgumentException(String.format("Tried to create a genome for '%s' from an invalid chromosome template.", getSpeciesRoot().getUID())); + this.chromosomes = chromosomes; + } + + // / SAVING & LOADING + @Override + public void readFromNBT(NBTTagCompound nbttagcompound) { + + NBTTagList nbttaglist = nbttagcompound.getTagList("Chromosomes", 10); + chromosomes = new Chromosome[chromosomes.length]; + for (int i = 0; i < nbttaglist.tagCount(); i++) { + NBTTagCompound nbttagcompound1 = nbttaglist.getCompoundTagAt(i); + byte byte0 = nbttagcompound1.getByte(SLOT_TAG); + if (byte0 >= 0 && byte0 < chromosomes.length) { + Chromosome chromosome = Chromosome.loadChromosomeFromNBT(nbttagcompound1); + chromosomes[byte0] = chromosome; + if (Config.clearInvalidChromosomes) + chromosome.overrideInvalidAlleles(getDefaultTemplate()[byte0], getSpeciesRoot().getKaryotype()[byte0].getAlleleClass()); + } + } + } + + @Override + public void writeToNBT(NBTTagCompound nbttagcompound) { + + NBTTagList nbttaglist = new NBTTagList(); + for (int i = 0; i < chromosomes.length; i++) + if (chromosomes[i] != null) { + NBTTagCompound nbttagcompound1 = new NBTTagCompound(); + nbttagcompound1.setByte(SLOT_TAG, (byte) i); + chromosomes[i].writeToNBT(nbttagcompound1); + nbttaglist.appendTag(nbttagcompound1); + } + nbttagcompound.setTag("Chromosomes", nbttaglist); + + } + + // / INFORMATION RETRIEVAL + @Override + public IChromosome[] getChromosomes() { + return chromosomes; + } + + @Override + public IAllele getActiveAllele(int chromosome) { + return chromosomes[chromosome].getActiveAllele(); + } + + @Override + public IAllele getInactiveAllele(int chromosome) { + return chromosomes[chromosome].getInactiveAllele(); + } + + @Override + public boolean isGeneticEqual(IGenome other) { + IChromosome[] genetics = other.getChromosomes(); + if (chromosomes.length != genetics.length) + return false; + + for (int i = 0; i < chromosomes.length; i++) { + IChromosome chromosome = chromosomes[i]; + if (chromosome == null && genetics[i] != null) + return false; + if (chromosome != null && genetics[i] == null) + return false; + if (chromosome == null && genetics[i] == null) + continue; + + if (!chromosome.getPrimaryAllele().getUID().equals(genetics[i].getPrimaryAllele().getUID())) + return false; + if (!chromosome.getSecondaryAllele().getUID().equals(genetics[i].getSecondaryAllele().getUID())) + return false; + } + + return true; + } +} diff --git a/forestry_common/core/forestry/core/genetics/Individual.java b/forestry_common/core/forestry/core/genetics/Individual.java new file mode 100755 index 000000000..50f79f35d --- /dev/null +++ b/forestry_common/core/forestry/core/genetics/Individual.java @@ -0,0 +1,78 @@ +/******************************************************************************* + * Copyright 2011-2014 by SirSengir + * + * This work is licensed under a Creative Commons Attribution-NonCommercial-NoDerivs 3.0 Unported License. + * + * To view a copy of this license, visit http://creativecommons.org/licenses/by-nc-nd/3.0/. + ******************************************************************************/ +package forestry.core.genetics; + +import net.minecraft.nbt.NBTTagCompound; + +import forestry.api.genetics.IIndividual; + +public abstract class Individual implements IIndividual { + + protected boolean isAnalyzed = false; + + @Override + public boolean isAnalyzed() { + return isAnalyzed; + } + + @Override + public boolean analyze() { + if (isAnalyzed) + return false; + + isAnalyzed = true; + return true; + } + + /* SAVING & LOADING */ + @Override + public void readFromNBT(NBTTagCompound nbttagcompound) { + if (nbttagcompound == null) + return; + + isAnalyzed = nbttagcompound.getBoolean("IsAnalyzed"); + } + + @Override + public void writeToNBT(NBTTagCompound nbttagcompound) { + nbttagcompound.setBoolean("IsAnalyzed", isAnalyzed); + } + + /* IDENTIFICATION */ + @Override + public String getIdent() { + return getGenome().getPrimary().getUID(); + } + + @Override + public String getDisplayName() { + return getGenome().getPrimary().getName(); + } + + /* INFORMATION */ + @Override + public boolean hasEffect() { + return getGenome().getPrimary().hasEffect(); + } + + @Override + public boolean isSecret() { + return getGenome().getPrimary().isSecret(); + } + + @Override + public boolean isGeneticEqual(IIndividual other) { + return getGenome().isGeneticEqual(other.getGenome()); + } + + @Override + public boolean isPureBred(int chromosomeOrdinal) { + return getGenome().getActiveAllele(chromosomeOrdinal).getUID().equals(getGenome().getInactiveAllele(chromosomeOrdinal).getUID()); + } + +} diff --git a/forestry_common/core/forestry/core/genetics/IndividualLiving.java b/forestry_common/core/forestry/core/genetics/IndividualLiving.java new file mode 100755 index 000000000..1898a7246 --- /dev/null +++ b/forestry_common/core/forestry/core/genetics/IndividualLiving.java @@ -0,0 +1,135 @@ +/******************************************************************************* + * Copyright 2011-2014 by SirSengir + * + * This work is licensed under a Creative Commons Attribution-NonCommercial-NoDerivs 3.0 Unported License. + * + * To view a copy of this license, visit http://creativecommons.org/licenses/by-nc-nd/3.0/. + ******************************************************************************/ +package forestry.core.genetics; + +import net.minecraft.nbt.NBTTagCompound; +import net.minecraft.world.World; + +import forestry.api.genetics.IGenome; +import forestry.api.genetics.IIndividualLiving; + +public abstract class IndividualLiving extends Individual implements IIndividualLiving { + + protected int generation; + protected boolean isNatural; + protected boolean isIrregularMating; + + protected int health; + protected int maxHealth; + + public IndividualLiving() {} + + public IndividualLiving(int newHealth, boolean isNatural, int generation) { + health = maxHealth = newHealth; + this.isNatural = isNatural; + this.generation = generation; + } + + /* SAVING & LOADING */ + @Override + public void readFromNBT(NBTTagCompound nbttagcompound) { + + super.readFromNBT(nbttagcompound); + + if (nbttagcompound.hasKey("NA")) + isNatural = nbttagcompound.getBoolean("NA"); + else + isNatural = true; + isIrregularMating = nbttagcompound.getBoolean("IM"); + generation = nbttagcompound.getInteger("GEN"); + + health = nbttagcompound.getInteger("Health"); + maxHealth = nbttagcompound.getInteger("MaxH"); + + } + + @Override + public void writeToNBT(NBTTagCompound nbttagcompound) { + + super.writeToNBT(nbttagcompound); + + nbttagcompound.setBoolean("NA", isNatural); + nbttagcompound.setBoolean("IM", isIrregularMating); + nbttagcompound.setInteger("GEN", generation); + + nbttagcompound.setInteger("Health", health); + nbttagcompound.setInteger("MaxH", maxHealth); + + if (getGenome() != null) { + NBTTagCompound NBTmachine = new NBTTagCompound(); + getGenome().writeToNBT(NBTmachine); + nbttagcompound.setTag("Genome", NBTmachine); + } + if (getMate() != null) { + NBTTagCompound NBTmachine = new NBTTagCompound(); + getMate().writeToNBT(NBTmachine); + nbttagcompound.setTag("Mate", NBTmachine); + } + + } + + /* GENERATION */ + public abstract IGenome getMate(); + + public void setIsNatural(boolean flag) { + this.isNatural = flag; + } + + public boolean isIrregularMating() { + return this.isIrregularMating; + } + + public boolean isNatural() { + return this.isNatural; + } + + public int getGeneration() { + return generation; + } + + @Override + public boolean isAlive() { + return health > 0; + } + + @Override + public int getHealth() { + return health; + } + + @Override + public int getMaxHealth() { + return this.maxHealth; + } + + @Override + public void age(World world, float lifespanModifier) { + + if (lifespanModifier < 0.001f) { + this.health = 0; + return; + } + + float ageModifier = 1.0f / lifespanModifier; + + while (ageModifier > 1.0f) { + decreaseHealth(); + ageModifier--; + } + if (world.rand.nextFloat() < ageModifier) + decreaseHealth(); + + } + + public void decreaseHealth() { + if (health > 0) + health--; + } + + +} diff --git a/forestry_common/core/forestry/core/genetics/ItemGE.java b/forestry_common/core/forestry/core/genetics/ItemGE.java new file mode 100755 index 000000000..dcdbf22d5 --- /dev/null +++ b/forestry_common/core/forestry/core/genetics/ItemGE.java @@ -0,0 +1,103 @@ +/******************************************************************************* + * Copyright 2011-2014 by SirSengir + * + * This work is licensed under a Creative Commons Attribution-NonCommercial-NoDerivs 3.0 Unported License. + * + * To view a copy of this license, visit http://creativecommons.org/licenses/by-nc-nd/3.0/. + ******************************************************************************/ +package forestry.core.genetics; + +import java.util.List; + +import net.minecraft.client.renderer.texture.IIconRegister; +import net.minecraft.entity.player.EntityPlayer; +import net.minecraft.item.Item; +import net.minecraft.item.ItemStack; + +import cpw.mods.fml.relauncher.Side; +import cpw.mods.fml.relauncher.SideOnly; + +import forestry.api.genetics.IAlleleSpecies; +import forestry.api.genetics.IIndividual; +import forestry.core.proxy.Proxies; +import forestry.core.utils.StringUtil; + +public abstract class ItemGE extends Item { + + protected ItemGE() { + super(); + // maxStackSize = 1; + hasSubtypes = true; + } + + protected abstract int getDefaultPrimaryColour(); + + protected abstract int getDefaultSecondaryColour(); + + protected abstract IIndividual getIndividual(ItemStack itemstack); + + @Override + public boolean isDamageable() { + return false; + } + + @Override + public boolean isRepairable() { + return false; + } + + @Override + public boolean getShareTag() { + return true; + } + + @Override + public boolean hasEffect(ItemStack itemstack) { + if (!itemstack.hasTagCompound()) + return false; + + IIndividual individual = getIndividual(itemstack); + return individual.hasEffect(); + } + + @SuppressWarnings({ "rawtypes", "unchecked" }) + @Override + public void addInformation(ItemStack itemstack, EntityPlayer player, List list, boolean flag) { + if(!itemstack.hasTagCompound()) + return; + + IIndividual individual = getIndividual(itemstack); + + if(individual.isAnalyzed()) { + if(Proxies.common.isShiftDown()) + individual.addTooltip(list); + else + list.add("\u00A7o<" + StringUtil.localize("gui.tooltip.tmi") + ">"); + } else + list.add("<" + StringUtil.localize("gui.unknown") + ">"); + } + + /* ICONS */ + @SideOnly(Side.CLIENT) + @Override + public void registerIcons(IIconRegister par1IconRegister) { + // Need to disable normal registration. + } + + @Override + public int getColorFromItemStack(ItemStack itemstack, int renderPass) { + + if (renderPass == 0) + return getDefaultPrimaryColour(); + else if (renderPass == 1) + return getDefaultSecondaryColour(); + else + return 0xffffff; + + } + + public int getColourFromSpecies(IAlleleSpecies species, int renderPass) { + return 0xffffff; + } + +} diff --git a/forestry_common/core/forestry/core/genetics/ItemResearchNote.java b/forestry_common/core/forestry/core/genetics/ItemResearchNote.java new file mode 100755 index 000000000..5ca0faf2b --- /dev/null +++ b/forestry_common/core/forestry/core/genetics/ItemResearchNote.java @@ -0,0 +1,264 @@ +/******************************************************************************* + * Copyright 2011-2014 by SirSengir + * + * This work is licensed under a Creative Commons Attribution-NonCommercial-NoDerivs 3.0 Unported License. + * + * To view a copy of this license, visit http://creativecommons.org/licenses/by-nc-nd/3.0/. + ******************************************************************************/ +package forestry.core.genetics; + +import java.util.ArrayList; +import java.util.List; + +import net.minecraft.client.renderer.texture.IIconRegister; +import net.minecraft.entity.player.EntityPlayer; +import net.minecraft.init.Items; +import net.minecraft.item.Item; +import net.minecraft.item.ItemStack; +import net.minecraft.nbt.NBTTagCompound; +import net.minecraft.util.ChatComponentTranslation; +import net.minecraft.util.IIcon; +import net.minecraft.world.World; + +import cpw.mods.fml.relauncher.Side; +import cpw.mods.fml.relauncher.SideOnly; + +import forestry.api.genetics.AlleleManager; +import forestry.api.genetics.IAllele; +import forestry.api.genetics.IAlleleSpecies; +import forestry.api.genetics.IBreedingTracker; +import forestry.api.genetics.IMutation; +import forestry.api.genetics.ISpeciesRoot; +import forestry.core.items.ItemForestry; +import forestry.core.proxy.Proxies; + +public class ItemResearchNote extends ItemForestry { + + public static enum EnumNoteType { + NONE, MUTATION, SPECIES; + + public static EnumNoteType[] VALUES = values(); + + private IMutation getEncodedMutation(ISpeciesRoot root, NBTTagCompound compound) { + IAllele allele0 = AlleleManager.alleleRegistry.getAllele(compound.getString("AL0")); + IAllele allele1 = AlleleManager.alleleRegistry.getAllele(compound.getString("AL1")); + if(allele0 == null || allele1 == null) + return null; + + IAllele result = null; + if(compound.hasKey("RST")) + result = AlleleManager.alleleRegistry.getAllele(compound.getString("RST")); + + IMutation encoded = null; + for(IMutation mutation : root.getCombinations(allele0)) + if(mutation.isPartner(allele1)) { + if(result == null + || mutation.getTemplate()[0].getUID().equals(result.getUID())) { + encoded = mutation; + break; + } + } + + return encoded; + } + + public ArrayList getTooltip(NBTTagCompound compound) { + ArrayList tooltips = new ArrayList(); + + if(compound == null || this == NONE) + return tooltips; + + if(this == MUTATION) { + ISpeciesRoot root = AlleleManager.alleleRegistry.getSpeciesRoot(compound.getString("ROT")); + if(root == null) + return tooltips; + + IMutation encoded = getEncodedMutation(root, compound); + if(encoded == null) + return tooltips; + + tooltips.add("\u00A7aMutation discovered!"); + tooltips.add(String.format("\u00A7e'%s'\u00A77 and \u00A7e'%s'\u00A77.", encoded.getAllele0().getName(), encoded.getAllele1().getName())); + tooltips.add(String.format("Chance for success is \u00A79%s\u00A77.", EnumMutateChance.rateChance(encoded.getBaseChance()))); + tooltips.add(String.format("New species is \u00A7d'%s'\u00A77.", (encoded.getTemplate()[root.getKaryotypeKey().ordinal()].getName()))); + + if(encoded.getSpecialConditions() != null && encoded.getSpecialConditions().size() > 0) { + for(String line : encoded.getSpecialConditions()) + tooltips.add("\u00A76" + line); + } + } else if(this == SPECIES) { + IAlleleSpecies allele0 = (IAlleleSpecies)AlleleManager.alleleRegistry.getAllele(compound.getString("AL0")); + if(allele0 == null) + return tooltips; + ISpeciesRoot root = AlleleManager.alleleRegistry.getSpeciesRoot(compound.getString("ROT")); + if(root == null) + return tooltips; + + tooltips.add("\u00A7aSpecies researched!"); + tooltips.add(String.format("\u00A7e'%s'\u00A77 (%s)", allele0.getName(), allele0.getBinomial())); + } + + return tooltips; + } + + public boolean registerResults(World world, EntityPlayer player, NBTTagCompound compound) { + if(compound == null || this == NONE) + return false; + + if(this == MUTATION) { + ISpeciesRoot root = AlleleManager.alleleRegistry.getSpeciesRoot(compound.getString("ROT")); + if(root == null) + return false; + + IMutation encoded = getEncodedMutation(root, compound); + if(encoded == null) + return false; + + IBreedingTracker tracker = encoded.getRoot().getBreedingTracker(world, player.getGameProfile().getId()); + if(tracker.isDiscovered(encoded)) { + player.addChatMessage(new ChatComponentTranslation("chat.cannotmemorizeagain")); + return false; + } + + tracker.registerSpecies((IAlleleSpecies)encoded.getAllele0()); + tracker.registerSpecies((IAlleleSpecies)encoded.getAllele1()); + tracker.registerSpecies((IAlleleSpecies)encoded.getTemplate()[root.getKaryotypeKey().ordinal()]); + tracker.registerMutation(encoded); + player.addChatMessage(new ChatComponentTranslation("chat.memorizednote")); + return true; + } + + return false; + + } + + public static ResearchNote createMutationNote(String researcher, IMutation mutation) { + NBTTagCompound compound = new NBTTagCompound(); + compound.setString("ROT", mutation.getRoot().getUID()); + compound.setString("AL0", mutation.getAllele0().getUID()); + compound.setString("AL1", mutation.getAllele1().getUID()); + compound.setString("RST", mutation.getTemplate()[0].getUID()); + return new ResearchNote(researcher, MUTATION, compound); + } + + public static ItemStack createMutationNoteStack(Item item, String researcher, IMutation mutation) { + ResearchNote note = createMutationNote(researcher, mutation); + NBTTagCompound compound = new NBTTagCompound(); + note.writeToNBT(compound); + ItemStack created = new ItemStack(item); + created.setTagCompound(compound); + return created; + } + + public static ResearchNote createSpeciesNote(String researcher, IAlleleSpecies species) { + NBTTagCompound compound = new NBTTagCompound(); + compound.setString("ROT", species.getRoot().getUID()); + compound.setString("AL0", species.getUID()); + return new ResearchNote(researcher, SPECIES, compound); + } + + public static ItemStack createSpeciesNoteStack(Item item, String researcher, IAlleleSpecies species) { + ResearchNote note = createSpeciesNote(researcher, species); + NBTTagCompound compound = new NBTTagCompound(); + note.writeToNBT(compound); + ItemStack created = new ItemStack(item); + created.setTagCompound(compound); + return created; + } + + } + + public static class ResearchNote { + + private String researcher = "fdssffd"; + private EnumNoteType type = EnumNoteType.NONE; + private NBTTagCompound inner; + + public ResearchNote(String researcher, EnumNoteType type, NBTTagCompound inner) { + this.researcher = researcher; + this.type = type; + this.inner = inner; + } + + public ResearchNote(NBTTagCompound compound) { + if(compound != null) { + this.researcher = compound.getString("RES"); + this.type = EnumNoteType.VALUES[compound.getByte("TYP")]; + this.inner = compound.getCompoundTag("INN"); + } else + this.inner = new NBTTagCompound(); + } + + public void writeToNBT(NBTTagCompound compound) { + compound.setString("RES", researcher); + compound.setByte("TYP", (byte)type.ordinal()); + compound.setTag("INN", inner); + } + + @SuppressWarnings({ "rawtypes", "unchecked" }) + public void addTooltip(List list) { + ArrayList tooltips = type.getTooltip(inner); + if(tooltips.size() <= 0) { + list.add("\u00A7o\u00A7cIt is impossible to decipher the washed out scribbles."); + list.add("The note has become unreadable and is worthless."); + return; + } + + list.addAll(tooltips); + } + + public boolean registerResults(World world, EntityPlayer player) { + return type.registerResults(world, player, inner); + } + } + + public ItemResearchNote() { + super(); + setCreativeTab(null); + } + + @Override + public String getItemStackDisplayName(ItemStack itemstack) { + ResearchNote note = new ResearchNote(itemstack.getTagCompound()); + return String.format("%s's Notes", note.researcher); + } + + @SuppressWarnings("rawtypes") + @Override + public void addInformation(ItemStack itemstack, EntityPlayer player, List list, boolean flag) { + ResearchNote note = new ResearchNote(itemstack.getTagCompound()); + note.addTooltip(list); + } + + @Override + public ItemStack onItemRightClick(ItemStack itemstack, World world, EntityPlayer entityplayer) { + + if (!Proxies.common.isSimulating(world)) + return itemstack; + + ResearchNote note = new ResearchNote(itemstack.getTagCompound()); + if(note.registerResults(world, entityplayer)) { + entityplayer.inventory.decrStackSize(entityplayer.inventory.currentItem, 1); + // Notify player that his inventory has changed. + Proxies.net.inventoryChangeNotify(entityplayer); + } + + return itemstack; + } + + @Override + public int getColorFromItemStack(ItemStack itemstack, int j) { + return 0xffe8a5; + } + + @SideOnly(Side.CLIENT) + @Override + public void registerIcons(IIconRegister register) { + } + + @SideOnly(Side.CLIENT) + @Override + public IIcon getIconFromDamage(int meta) { + return Items.paper.getIconFromDamage(0); + } +} diff --git a/forestry_common/core/forestry/core/genetics/Mutation.java b/forestry_common/core/forestry/core/genetics/Mutation.java new file mode 100755 index 000000000..2d912bf22 --- /dev/null +++ b/forestry_common/core/forestry/core/genetics/Mutation.java @@ -0,0 +1,129 @@ +/******************************************************************************* + * Copyright 2011-2014 by SirSengir + * + * This work is licensed under a Creative Commons Attribution-NonCommercial-NoDerivs 3.0 Unported License. + * + * To view a copy of this license, visit http://creativecommons.org/licenses/by-nc-nd/3.0/. + ******************************************************************************/ +package forestry.core.genetics; + + +import java.util.ArrayList; +import java.util.Collection; + +import forestry.api.core.EnumHumidity; +import forestry.api.core.EnumTemperature; +import forestry.api.genetics.IAllele; +import forestry.api.genetics.IMutation; + +public abstract class Mutation implements IMutation { + + protected int chance; + boolean isSecret = false; + + protected IAllele allele0; + protected IAllele allele1; + + IAllele[] template; + + protected float minTemperature = 0.0f; + protected float maxTemperature = 2.0f; + protected float minRainfall = 0.0f; + protected float maxRainfall = 2.0f; + + protected ArrayList specialConditions = new ArrayList(); + + public Mutation(IAllele allele0, IAllele allele1, IAllele[] template, int chance) { + this.allele0 = allele0; + this.allele1 = allele1; + this.template = template; + this.chance = chance; + } + + + public Mutation setSpecialConditions(Collection conditions) { + specialConditions.addAll(conditions); + return this; + } + + public Collection getSpecialConditions() { + return specialConditions; + } + + public Mutation setIsSecret() { + isSecret = true; + return this; + } + + public Mutation setTemperature(float minTemperature, float maxTemperature) { + this.minTemperature = minTemperature; + this.maxTemperature = maxTemperature; + + EnumTemperature temp1 = EnumTemperature.getFromValue(minTemperature); + EnumTemperature temp2 = EnumTemperature.getFromValue(maxTemperature); + if(temp1 != temp2) + specialConditions.add(String.format("Temperature between %s and %s.", temp1, temp2)); + else + specialConditions.add(String.format("Temperature %s required.", temp1)); + return this; + } + + public Mutation setRainfall(float minRainfall, float maxRainfall) { + this.minRainfall = minRainfall; + this.maxRainfall = maxRainfall; + + EnumHumidity temp1 = EnumHumidity.getFromValue(minRainfall); + EnumHumidity temp2 = EnumHumidity.getFromValue(maxRainfall); + + if(temp1 != temp2) + specialConditions.add(String.format("Humidity between %s and %s.", temp1, temp2)); + else + specialConditions.add(String.format("Humidity %s required.", temp1)); + return this; + } + + public Mutation setTemperatureRainfall(float minTemperature, float maxTemperature, float minRainfall, float maxRainfall) { + setTemperature(minTemperature, maxTemperature); + setRainfall(minRainfall, maxRainfall); + return this; + } + + @Override + public IAllele getAllele0() { + return allele0; + } + + @Override + public IAllele getAllele1() { + return allele1; + } + + @Override + public float getBaseChance() { + return chance; + } + + @Override + public IAllele[] getTemplate() { + return template; + } + + @Override + public boolean isPartner(IAllele allele) { + return allele0.getUID().equals(allele.getUID()) || allele1.getUID().equals(allele.getUID()); + } + + @Override + public IAllele getPartner(IAllele allele) { + if (allele0.getUID().equals(allele.getUID())) + return allele1; + else + return allele0; + } + + @Override + public boolean isSecret() { + return isSecret; + } + +} diff --git a/forestry_common/core/forestry/core/genetics/SpeciesRoot.java b/forestry_common/core/forestry/core/genetics/SpeciesRoot.java new file mode 100755 index 000000000..965880a8d --- /dev/null +++ b/forestry_common/core/forestry/core/genetics/SpeciesRoot.java @@ -0,0 +1,105 @@ +/******************************************************************************* + * Copyright 2011-2014 by SirSengir + * + * This work is licensed under a Creative Commons Attribution-NonCommercial-NoDerivs 3.0 Unported License. + * + * To view a copy of this license, visit http://creativecommons.org/licenses/by-nc-nd/3.0/. + ******************************************************************************/ +package forestry.core.genetics; + +import java.util.ArrayList; +import java.util.Collection; +import java.util.Collections; +import java.util.HashMap; +import java.util.LinkedHashMap; +import java.util.Map; +import java.util.Random; + +import net.minecraft.item.ItemStack; + +import forestry.api.genetics.IAllele; +import forestry.api.genetics.IChromosome; +import forestry.api.genetics.IMutation; +import forestry.api.genetics.ISpeciesRoot; + +public abstract class SpeciesRoot implements ISpeciesRoot { + + /* RESEARCH */ + LinkedHashMap researchCatalysts = new LinkedHashMap(); + + @Override + public Map getResearchCatalysts() { + return Collections.unmodifiableMap(researchCatalysts); + } + + @Override + public void setResearchSuitability(ItemStack itemstack, float suitability) { + researchCatalysts.put(itemstack, suitability); + } + + /* TEMPLATES */ + public HashMap speciesTemplates = new HashMap(); + + @Override + public Map getGenomeTemplates() { + return speciesTemplates; + } + + @Override + public void registerTemplate(IAllele[] template) { + registerTemplate(template[0].getUID(), template); + } + + @Override + public IAllele[] getRandomTemplate(Random rand) { + return speciesTemplates.values().toArray(new IAllele[0][])[rand.nextInt(speciesTemplates.values().size())]; + } + + @Override + public IAllele[] getTemplate(String identifier) { + return speciesTemplates.get(identifier); + } + + /* MUTATIONS */ + @Override + public Collection getCombinations(IAllele other) { + ArrayList combinations = new ArrayList(); + for (IMutation mutation : getMutations(false)) + if (mutation.isPartner(other)) + combinations.add(mutation); + + return combinations; + } + + @Override + public Collection getPaths(IAllele result, int chromosomeOrdinal) { + ArrayList paths = new ArrayList(); + for (IMutation mutation : getMutations(false)) + if(mutation.getTemplate()[chromosomeOrdinal] == result) + paths.add(mutation); + + return paths; + } + + /* GENOME CONVERSIONS */ + @Override + public IChromosome[] templateAsChromosomes(IAllele[] template) { + Chromosome[] chromosomes = new Chromosome[template.length]; + for (int i = 0; i < template.length; i++) + if (template[i] != null) + chromosomes[i] = new Chromosome(template[i]); + + return chromosomes; + } + + @Override + public IChromosome[] templateAsChromosomes(IAllele[] templateActive, IAllele[] templateInactive) { + Chromosome[] chromosomes = new Chromosome[templateActive.length]; + for (int i = 0; i < templateActive.length; i++) + if (templateActive[i] != null) + chromosomes[i] = new Chromosome(templateActive[i], templateInactive[i]); + + return chromosomes; + } + +} diff --git a/forestry_common/core/forestry/core/gui/ClimateLedger.java b/forestry_common/core/forestry/core/gui/ClimateLedger.java new file mode 100755 index 000000000..143d673e2 --- /dev/null +++ b/forestry_common/core/forestry/core/gui/ClimateLedger.java @@ -0,0 +1,60 @@ +/******************************************************************************* + * Copyright 2011-2014 by SirSengir + * + * This work is licensed under a Creative Commons Attribution-NonCommercial-NoDerivs 3.0 Unported License. + * + * To view a copy of this license, visit http://creativecommons.org/licenses/by-nc-nd/3.0/. + ******************************************************************************/ +package forestry.core.gui; + +import forestry.api.core.EnumTemperature; +import forestry.core.genetics.ClimateHelper; +import forestry.core.interfaces.IClimatised; +import forestry.core.utils.StringUtil; + +/** + * A ledger containing climate information. + */ +public class ClimateLedger extends Ledger { + + IClimatised tile; + + public ClimateLedger(LedgerManager manager, IClimatised tile) { + super(manager); + this.tile = tile; + maxHeight = 72; + overlayColor = manager.gui.fontColor.get("ledger.climate.background"); + } + + @Override + public void draw(int x, int y) { + + EnumTemperature temperature = tile.getTemperature(); + + // Draw background + drawBackground(x, y); + + // Draw icon + drawIcon(temperature.getIcon(), x + 3, y + 4); + + if (!isFullyOpened()) + return; + + manager.minecraft.fontRenderer.drawStringWithShadow(StringUtil.localize("gui.climate"), x + 22, y + 8, + manager.gui.fontColor.get("ledger.climate.header")); + manager.minecraft.fontRenderer.drawStringWithShadow(StringUtil.localize("gui.temperature") + ":", x + 22, y + 20, + manager.gui.fontColor.get("ledger.climate.subheader")); + manager.minecraft.fontRenderer.drawString(ClimateHelper.toDisplay(temperature) + " " + StringUtil.floatAsPercent(tile.getExactTemperature()), x + 22, + y + 32, manager.gui.fontColor.get("ledger.climate.text")); + manager.minecraft.fontRenderer.drawStringWithShadow(StringUtil.localize("gui.humidity") + ":", x + 22, y + 44, + manager.gui.fontColor.get("ledger.climate.subheader")); + manager.minecraft.fontRenderer.drawString(ClimateHelper.toDisplay(tile.getHumidity()) + " " + StringUtil.floatAsPercent(tile.getExactHumidity()), + x + 22, y + 56, manager.gui.fontColor.get("ledger.climate.text")); + } + + @Override + public String getTooltip() { + return "T: " + ClimateHelper.toDisplay(tile.getTemperature()) + " / H: " + ClimateHelper.toDisplay(tile.getHumidity()); + } + +} diff --git a/forestry_common/core/forestry/core/gui/ContainerAnalyzer.java b/forestry_common/core/forestry/core/gui/ContainerAnalyzer.java new file mode 100755 index 000000000..9f6e40ff6 --- /dev/null +++ b/forestry_common/core/forestry/core/gui/ContainerAnalyzer.java @@ -0,0 +1,67 @@ +/******************************************************************************* + * Copyright 2011-2014 by SirSengir + * + * This work is licensed under a Creative Commons Attribution-NonCommercial-NoDerivs 3.0 Unported License. + * + * To view a copy of this license, visit http://creativecommons.org/licenses/by-nc-nd/3.0/. + ******************************************************************************/ +package forestry.core.gui; + +import net.minecraft.entity.player.InventoryPlayer; +import net.minecraft.inventory.ICrafting; +import net.minecraft.inventory.Slot; + +import forestry.core.gadgets.TileAnalyzer; +import forestry.core.genetics.ItemGE; +import forestry.core.gui.slots.SlotCustom; +import forestry.core.gui.slots.SlotLiquidContainer; + +public class ContainerAnalyzer extends ContainerLiquidTanks { + + private TileAnalyzer tile; + + public ContainerAnalyzer(InventoryPlayer player, TileAnalyzer tile) { + super(tile, tile); + + this.tile = tile; + + // Input buffer + for (int i = 0; i < 3; i++) + for (int k = 0; k < 2; k++) + addSlot(new SlotCustom(tile, TileAnalyzer.SLOT_INPUT_1 + i * 2 + k, 8 + k * 18, 28 + i * 18, new Object[] { ItemGE.class })); + + // Analyze slot + addSlot(new SlotCustom(tile, TileAnalyzer.SLOT_ANALYZE, 73, 59, new Object[] {})); + + // Can slot + addSlot(new SlotLiquidContainer(tile, TileAnalyzer.SLOT_CAN, 143, 24)); + + // Output buffer + for (int i = 0; i < 2; i++) + for (int k = 0; k < 2; k++) + addSlot(new SlotCustom(tile, TileAnalyzer.SLOT_OUTPUT_1 + i * 2 + k, 134 + k * 18, 48 + i * 18, new Object[] { ItemGE.class })); + + // Player inventory + for (int i1 = 0; i1 < 3; i1++) + for (int l1 = 0; l1 < 9; l1++) + addSlot(new Slot(player, l1 + i1 * 9 + 9, 8 + l1 * 18, 94 + i1 * 18)); + // Player hotbar + for (int j1 = 0; j1 < 9; j1++) + addSlot(new Slot(player, j1, 8 + j1 * 18, 152)); + + } + + @Override + public void updateProgressBar(int i, int j) { + tile.getGUINetworkData(i, j); + } + + @Override + public void detectAndSendChanges() { + super.detectAndSendChanges(); + + for (int i = 0; i < crafters.size(); i++) + tile.sendGUINetworkData(this, (ICrafting) crafters.get(i)); + } + +} diff --git a/forestry_common/core/forestry/core/gui/ContainerDummy.java b/forestry_common/core/forestry/core/gui/ContainerDummy.java new file mode 100755 index 000000000..6484986f4 --- /dev/null +++ b/forestry_common/core/forestry/core/gui/ContainerDummy.java @@ -0,0 +1,20 @@ +/******************************************************************************* + * Copyright 2011-2014 by SirSengir + * + * This work is licensed under a Creative Commons Attribution-NonCommercial-NoDerivs 3.0 Unported License. + * + * To view a copy of this license, visit http://creativecommons.org/licenses/by-nc-nd/3.0/. + ******************************************************************************/ +package forestry.core.gui; + +import net.minecraft.entity.player.EntityPlayer; +import net.minecraft.inventory.Container; + +public class ContainerDummy extends Container { + + @Override + public boolean canInteractWith(EntityPlayer entityplayer) { + return true; + } + +} diff --git a/forestry_common/core/forestry/core/gui/ContainerEscritoire.java b/forestry_common/core/forestry/core/gui/ContainerEscritoire.java new file mode 100755 index 000000000..7aaeefa50 --- /dev/null +++ b/forestry_common/core/forestry/core/gui/ContainerEscritoire.java @@ -0,0 +1,104 @@ +/******************************************************************************* + * Copyright 2011-2014 by SirSengir + * + * This work is licensed under a Creative Commons Attribution-NonCommercial-NoDerivs 3.0 Unported License. + * + * To view a copy of this license, visit http://creativecommons.org/licenses/by-nc-nd/3.0/. + ******************************************************************************/ +package forestry.core.gui; + +import java.util.ArrayList; +import java.util.Collection; + +import net.minecraft.entity.player.EntityPlayer; +import net.minecraft.init.Blocks; +import net.minecraft.inventory.Slot; + +import forestry.api.genetics.AlleleManager; +import forestry.core.gadgets.TileEscritoire; +import forestry.core.gui.slots.SlotClosed; +import forestry.core.gui.slots.SlotCustom; +import forestry.core.network.PacketIds; +import forestry.core.network.PacketPayload; +import forestry.core.network.PacketUpdate; +import forestry.core.proxy.Proxies; + +public class ContainerEscritoire extends ContainerForestry implements IGuiSelectable { + + final EntityPlayer player; + final TileEscritoire tile; + + public long lastUpdate; + + public ContainerEscritoire(EntityPlayer player, TileEscritoire t) { + super(t); + + this.player = player; + this.tile = t; + + Collection filters = new ArrayList(); + filters.add(Blocks.sapling); + filters.addAll(AlleleManager.alleleRegistry.getSpeciesRoot().values()); + // Analyze slot + addSlot(new SlotCustom(tile, TileEscritoire.SLOT_ANALYZE, 97, 67, filters.toArray()).setCrafter(tile)); + + for (int i = 0; i < TileEscritoire.SLOTS_INPUT_COUNT; i++) { + addSlot(new SlotCustom(tile, TileEscritoire.SLOT_INPUT_1 + i, 17, 49 + i * 18, true).setBlockedTexture("slots/blocked_2")); + } + + for(int i = 0; i < 3; i++) + for(int j = 0; j < 2; j++) { + addSlot(new SlotClosed(tile, TileEscritoire.SLOT_RESULTS_1 + (i*2) + j, 177 + j*18, 85 + i*18)); + } + + // Player inventory + for (int i = 0; i < 3; i++) + for (int j = 0; j < 9; j++) + addSlot(new Slot(player.inventory, j + i * 9 + 9, 34 + j * 18, 153 + i * 18)); + // Player hotbar + for (int k = 0; k < 9; k++) + addSlot(new Slot(player.inventory, k, 34 + k * 18, 211)); + } + + @Override + public void detectAndSendChanges() { + super.detectAndSendChanges(); + if(lastUpdate == tile.getGame().getLastUpdate()) + return; + + lastUpdate = tile.getGame().getLastUpdate(); + tile.sendBoard(player); + } + + public void sendTokenClick(int index) { + PacketPayload payload = new PacketPayload(1, 0, 0); + payload.intPayload[0] = index; + PacketUpdate packet = new PacketUpdate(PacketIds.GUI_SELECTION_CHANGE, payload); + Proxies.net.sendToServer(packet); + } + + public void sendProbeClick() { + PacketPayload payload = new PacketPayload(1, 0, 0); + payload.intPayload[0] = -1; + PacketUpdate packet = new PacketUpdate(PacketIds.GUI_SELECTION_CHANGE, payload); + Proxies.net.sendToServer(packet); + } + + @Override + public void handleSelectionChange(EntityPlayer player, PacketUpdate packet) { + if (!tile.getGame().isEnded()) { + int index = packet.payload.intPayload[0]; + if (index == -1) { + tile.probe(); + } else { + tile.getGame().choose(packet.payload.intPayload[0]); + tile.processTurnResult(player.getGameProfile().getId()); + } + } + } + + @Override + public void setSelection(PacketUpdate packet) { + } + +} diff --git a/forestry_common/core/forestry/core/gui/ContainerForestry.java b/forestry_common/core/forestry/core/gui/ContainerForestry.java new file mode 100755 index 000000000..3a65b5bff --- /dev/null +++ b/forestry_common/core/forestry/core/gui/ContainerForestry.java @@ -0,0 +1,211 @@ +/******************************************************************************* + * Copyright 2011-2014 by SirSengir + * + * This work is licensed under a Creative Commons Attribution-NonCommercial-NoDerivs 3.0 Unported License. + * + * To view a copy of this license, visit http://creativecommons.org/licenses/by-nc-nd/3.0/. + ******************************************************************************/ +package forestry.core.gui; + +import net.minecraft.entity.player.EntityPlayer; +import net.minecraft.entity.player.InventoryPlayer; +import net.minecraft.inventory.Container; +import net.minecraft.inventory.IInventory; +import net.minecraft.inventory.Slot; +import net.minecraft.item.ItemStack; +import net.minecraft.nbt.NBTTagCompound; + +import forestry.core.gui.slots.SlotForestry; +import forestry.core.utils.ForestryTank; +import forestry.core.utils.StackUtils; + +public class ContainerForestry extends Container { + + protected IInventory inventory; + + public ContainerForestry(IInventory inventory) { + this.inventory = inventory; + } + + /** + * Adds a slot to the container, shortcut for addSlotToContainer(slot). + * + * @param slot + */ + protected Slot addSlot(Slot slot) { + return addSlotToContainer(slot); + } + + @Override + public ItemStack slotClick(int slotIndex, int button, int modifier, EntityPlayer player) { + Slot slot = slotIndex < 0 ? null : (Slot) this.inventorySlots.get(slotIndex); + if (slot instanceof SlotForestry) { + ((SlotForestry) slot).onSlotClick(slotIndex, button, modifier, player); + + if (((SlotForestry) slot).isPhantom()) { + return slotClickPhantom(slot, button, modifier, player); + } + } + return super.slotClick(slotIndex, button, modifier, player); + } + + private ItemStack slotClickPhantom(Slot slot, int mouseButton, int modifier, EntityPlayer player) { + ItemStack stack = null; + + if (mouseButton == 2) { + if (((SlotForestry) slot).canAdjustPhantom()) + slot.putStack(null); + } else if (mouseButton == 0 || mouseButton == 1) { + InventoryPlayer playerInv = player.inventory; + slot.onSlotChanged(); + ItemStack stackSlot = slot.getStack(); + ItemStack stackHeld = playerInv.getItemStack(); + + if (stackSlot != null) + stack = stackSlot.copy(); + + if (stackSlot == null) { + if (stackHeld != null && slot.isItemValid(stackHeld)) + fillPhantomSlot(slot, stackHeld, mouseButton, modifier); + } else if (stackHeld == null) { + adjustPhantomSlot(slot, mouseButton, modifier); + slot.onPickupFromSlot(player, playerInv.getItemStack()); + } else if (slot.isItemValid(stackHeld)) + if (StackUtils.isIdenticalItem(stackSlot, stackHeld)) + adjustPhantomSlot(slot, mouseButton, modifier); + else + fillPhantomSlot(slot, stackHeld, mouseButton, modifier); + } + return stack; + } + + protected void adjustPhantomSlot(Slot slot, int mouseButton, int modifier) { + if (!((SlotForestry) slot).canAdjustPhantom()) + return; + ItemStack stackSlot = slot.getStack(); + int stackSize; + if (modifier == 1) + stackSize = mouseButton == 0 ? (stackSlot.stackSize + 1) / 2 : stackSlot.stackSize * 2; + else + stackSize = mouseButton == 0 ? stackSlot.stackSize - 1 : stackSlot.stackSize + 1; + + if (stackSize > slot.getSlotStackLimit()) + stackSize = slot.getSlotStackLimit(); + + stackSlot.stackSize = stackSize; + + if (stackSlot.stackSize <= 0) + slot.putStack((ItemStack) null); + } + + protected void fillPhantomSlot(Slot slot, ItemStack stackHeld, int mouseButton, int modifier) { + if (!((SlotForestry) slot).canAdjustPhantom()) + return; + int stackSize = mouseButton == 0 ? stackHeld.stackSize : 1; + if (stackSize > slot.getSlotStackLimit()) + stackSize = slot.getSlotStackLimit(); + ItemStack phantomStack = stackHeld.copy(); + phantomStack.stackSize = stackSize; + + slot.putStack(phantomStack); + } + + protected boolean shiftItemStack(ItemStack stackToShift, int start, int end) { + boolean changed = false; + if (stackToShift.isStackable()) + for (int slotIndex = start; stackToShift.stackSize > 0 && slotIndex < end; slotIndex++) { + Slot slot = (Slot) inventorySlots.get(slotIndex); + ItemStack stackInSlot = slot.getStack(); + if (stackInSlot != null && StackUtils.isIdenticalItem(stackInSlot, stackToShift)) { + int resultingStackSize = stackInSlot.stackSize + stackToShift.stackSize; + int max = Math.min(stackToShift.getMaxStackSize(), slot.getSlotStackLimit()); + if (resultingStackSize <= max) { + stackToShift.stackSize = 0; + stackInSlot.stackSize = resultingStackSize; + slot.onSlotChanged(); + changed = true; + } else if (stackInSlot.stackSize < max) { + stackToShift.stackSize -= max - stackInSlot.stackSize; + stackInSlot.stackSize = max; + slot.onSlotChanged(); + changed = true; + } + } + } + if (stackToShift.stackSize > 0) + for (int slotIndex = start; stackToShift.stackSize > 0 && slotIndex < end; slotIndex++) { + Slot slot = (Slot) inventorySlots.get(slotIndex); + ItemStack stackInSlot = slot.getStack(); + if (stackInSlot == null) { + int max = Math.min(stackToShift.getMaxStackSize(), slot.getSlotStackLimit()); + stackInSlot = stackToShift.copy(); + stackInSlot.stackSize = Math.min(stackToShift.stackSize, max); + stackToShift.stackSize -= stackInSlot.stackSize; + slot.putStack(stackInSlot); + slot.onSlotChanged(); + changed = true; + } + } + return changed; + } + + private boolean tryShiftItem(ItemStack stackToShift, int numSlots) { + for (int machineIndex = 0; machineIndex < numSlots - 9 * 4; machineIndex++) { + Slot slot = (Slot) inventorySlots.get(machineIndex); + if (slot instanceof SlotForestry) { + SlotForestry slotForestry = (SlotForestry) slot; + if (!slotForestry.canShift()) + continue; + if (slotForestry.isPhantom()) + continue; + } + if (!slot.isItemValid(stackToShift)) + continue; + if (shiftItemStack(stackToShift, machineIndex, machineIndex + 1)) + return true; + } + return false; + } + + @Override + public ItemStack transferStackInSlot(EntityPlayer player, int slotIndex) { + ItemStack originalStack = null; + Slot slot = (Slot) inventorySlots.get(slotIndex); + int numSlots = inventorySlots.size(); + if (slot != null && slot.getHasStack()) { + ItemStack stackInSlot = slot.getStack(); + originalStack = stackInSlot.copy(); + if (slotIndex >= numSlots - 9 * 4 && tryShiftItem(stackInSlot, numSlots)) { + // NOOP + } else if (slotIndex >= numSlots - 9 * 4 && slotIndex < numSlots - 9) { + if (!shiftItemStack(stackInSlot, numSlots - 9, numSlots)) + return null; + } else if (slotIndex >= numSlots - 9 && slotIndex < numSlots) { + if (!shiftItemStack(stackInSlot, numSlots - 9 * 4, numSlots - 9)) + return null; + } else if (!shiftItemStack(stackInSlot, numSlots - 9 * 4, numSlots)) + return null; + slot.onSlotChange(stackInSlot, originalStack); + if (stackInSlot.stackSize <= 0) + slot.putStack(null); + else + slot.onSlotChanged(); + if (stackInSlot.stackSize == originalStack.stackSize) + return null; + slot.onPickupFromSlot(player, stackInSlot); + } + return originalStack; + } + + @Override + public boolean canInteractWith(EntityPlayer entityplayer) { + return inventory.isUseableByPlayer(entityplayer); + } + + public void onTankUpdate(NBTTagCompound nbt) { + } + + public ForestryTank getTank(int slot) { + return ForestryTank.FAKETANK; + } +} diff --git a/forestry_common/core/forestry/core/gui/ContainerItemInventory.java b/forestry_common/core/forestry/core/gui/ContainerItemInventory.java new file mode 100755 index 000000000..b2335d6e9 --- /dev/null +++ b/forestry_common/core/forestry/core/gui/ContainerItemInventory.java @@ -0,0 +1,71 @@ +/******************************************************************************* + * Copyright 2011-2014 by SirSengir + * + * This work is licensed under a Creative Commons Attribution-NonCommercial-NoDerivs 3.0 Unported License. + * + * To view a copy of this license, visit http://creativecommons.org/licenses/by-nc-nd/3.0/. + ******************************************************************************/ +package forestry.core.gui; + +import net.minecraft.entity.player.EntityPlayer; +import net.minecraft.inventory.IInventory; +import net.minecraft.item.ItemStack; + +import forestry.core.gui.slots.SlotItemInventory; +import forestry.core.gui.slots.SlotLocked; +import forestry.core.proxy.Proxies; +import forestry.core.utils.ItemInventory; + +public abstract class ContainerItemInventory extends ContainerForestry { + + protected final EntityPlayer player; + protected final ItemInventory inventory; + + public ContainerItemInventory(ItemInventory inventory, EntityPlayer player) { + super(inventory); + this.inventory = inventory; + this.player = player; + } + + public ItemInventory getItemInventory() { + return inventory; + } + + protected void addSecuredSlot(IInventory other, int slot, int x, int y) { + if (other.getStackInSlot(slot) != null && inventory.itemClass.isAssignableFrom(other.getStackInSlot(slot).getItem().getClass())) + addSlot(new SlotLocked(other, slot, x, y)); + else + addSlot(new SlotItemInventory(this, other, player, slot, x, y)); + } + + protected abstract boolean isAcceptedItem(EntityPlayer player, ItemStack stack); + + public void purgeBag(EntityPlayer player) { + for (int i = 0; i < inventory.getSizeInventory(); i++) { + ItemStack stack = inventory.getStackInSlot(i); + if (stack == null) + continue; + + if (isAcceptedItem(player, stack)) + continue; + + Proxies.common.dropItemPlayer(player, stack); + inventory.setInventorySlotContents(i, null); + } + } + + public void saveInventory(EntityPlayer entityplayer) { + if (inventory.isItemInventory) + inventory.onGuiSaved(entityplayer); + } + + @Override + public void onContainerClosed(EntityPlayer player) { + super.onContainerClosed(player); + if (!Proxies.common.isSimulating(player.worldObj)) + return; + + purgeBag(player); + saveInventory(player); + } +} diff --git a/forestry_common/core/forestry/core/gui/ContainerLiquidTanks.java b/forestry_common/core/forestry/core/gui/ContainerLiquidTanks.java new file mode 100755 index 000000000..8155cd2bd --- /dev/null +++ b/forestry_common/core/forestry/core/gui/ContainerLiquidTanks.java @@ -0,0 +1,123 @@ +/******************************************************************************* + * Copyright 2011-2014 by SirSengir + * + * This work is licensed under a Creative Commons Attribution-NonCommercial-NoDerivs 3.0 Unported License. + * + * To view a copy of this license, visit http://creativecommons.org/licenses/by-nc-nd/3.0/. + ******************************************************************************/ +package forestry.core.gui; + +import java.util.HashMap; +import java.util.Map; + +import net.minecraft.entity.player.EntityPlayer; +import net.minecraft.entity.player.EntityPlayerMP; +import net.minecraft.inventory.IInventory; +import net.minecraft.item.Item; +import net.minecraft.item.ItemStack; +import net.minecraft.nbt.NBTTagCompound; + +import net.minecraftforge.fluids.FluidStack; +import net.minecraftforge.fluids.IFluidTank; + +import buildcraft.api.tools.IToolPipette; + +import forestry.core.interfaces.ILiquidTankContainer; +import forestry.core.network.PacketIds; +import forestry.core.network.PacketPayload; +import forestry.core.network.PacketTankUpdate; +import forestry.core.network.PacketUpdate; +import forestry.core.proxy.Proxies; +import forestry.core.utils.ForestryTank; + +public class ContainerLiquidTanks extends ContainerForestry { + + private ILiquidTankContainer tanks; + + public ContainerLiquidTanks(IInventory inventory, ILiquidTankContainer tanks) { + super(inventory); + this.tanks = tanks; + } + + public void handlePipetteClick(int slot, EntityPlayer player) { + + ItemStack itemstack = player.inventory.getItemStack(); + if (itemstack == null) + return; + + Item held = itemstack.getItem(); + if (!(held instanceof IToolPipette)) + return; + + if (!Proxies.common.isSimulating(player.worldObj)) { + + PacketPayload payload = new PacketPayload(1, 0, 0); + payload.intPayload[0] = slot; + Proxies.net.sendToServer(new PacketUpdate(PacketIds.PIPETTE_CLICK, payload)); + return; + + } + + IToolPipette pipette = (IToolPipette) held; + int liquidAmount = tanks.getTanks()[slot].getFluid().amount; + if (pipette.canPipette(itemstack) && liquidAmount > 0) { + + if (liquidAmount > 0) { + int filled = pipette.fill(itemstack, tanks.getTanks()[slot].drain(1000, false), + true); + tanks.getTanks()[slot].drain(filled, true); + } + + } else { + + IFluidTank tank = tanks.getTanks()[slot]; + FluidStack potential = pipette.drain(itemstack, pipette.getCapacity(itemstack), false); + if (potential != null) + pipette.drain(itemstack, tank.fill(potential, true), true); + + } + } + private Map syncedFluids = new HashMap(); + + @Override + public void detectAndSendChanges() { + super.detectAndSendChanges(); + + for (int i = 0; i < tanks.getTanks().length; i++) { + ForestryTank tank = tanks.getTanks()[i]; + + // If null has been synced + if (tank.getFluid() == null && getTank(i).getFluidAmount() <= 0) + continue; + // If fluid has been synced + if (tank.getFluid() != null && tank.getFluid().isFluidStackIdentical(getTank(i).getFluid())) + continue; + + for (int j = 0; j < this.crafters.size(); ++j) { + if (this.crafters.get(j) instanceof EntityPlayerMP) { + EntityPlayerMP player = (EntityPlayerMP) this.crafters.get(j); + Proxies.net.sendToPlayer(new PacketTankUpdate(i, tank), player); + } + } + + syncedFluids.put(i, new ForestryTank(tank.getFluid() == null ? null : tank.getFluid().copy(), tank.getCapacity())); + + } + } + + @Override + public void onTankUpdate(NBTTagCompound nbt) { + int tankID = nbt.getByte("tank"); + int capacity = nbt.getShort("capacity"); + tanks.getTanks()[tankID].readFromNBT(nbt); + + ForestryTank tank = new ForestryTank(capacity); + tank.readFromNBT(nbt); + syncedFluids.put(tankID, tank); + } + + @Override + public ForestryTank getTank(int slot) { + return syncedFluids.get(slot) == null ? ForestryTank.FAKETANK : syncedFluids.get(slot); + } +} diff --git a/forestry_common/core/forestry/core/gui/ContainerNaturalistInventory.java b/forestry_common/core/forestry/core/gui/ContainerNaturalistInventory.java new file mode 100755 index 000000000..3eecb2a09 --- /dev/null +++ b/forestry_common/core/forestry/core/gui/ContainerNaturalistInventory.java @@ -0,0 +1,71 @@ +/******************************************************************************* + * Copyright 2011-2014 by SirSengir + * + * This work is licensed under a Creative Commons Attribution-NonCommercial-NoDerivs 3.0 Unported License. + * + * To view a copy of this license, visit http://creativecommons.org/licenses/by-nc-nd/3.0/. + ******************************************************************************/ +package forestry.core.gui; + +import net.minecraft.entity.player.EntityPlayer; +import net.minecraft.entity.player.InventoryPlayer; +import net.minecraft.inventory.Slot; +import net.minecraft.item.ItemStack; + +import forestry.api.genetics.ISpeciesRoot; +import forestry.core.gui.slots.SlotCustom; +import forestry.core.network.PacketUpdate; +import forestry.core.proxy.Proxies; + +public class ContainerNaturalistInventory extends ContainerForestry implements IGuiSelectable { + + private final IPagedInventory inv; + private ISpeciesRoot speciesRoot; + + public ContainerNaturalistInventory(ISpeciesRoot speciesRoot, InventoryPlayer player, IPagedInventory inventory, int page, int pageSize) { + super(inventory); + this.inv = inventory; + this.speciesRoot = speciesRoot; + + // Inventory + for (int x = 0; x < 5; x++) { + for (int y = 0; y < 5; y++) { + addSlot(new SlotCustom(inventory, y + page * pageSize + x * 5, 100 + y * 18, 21 + x * 18, new Object[]{speciesRoot})); + } + } + + // Player inventory + for (int i1 = 0; i1 < 3; i1++) { + for (int l1 = 0; l1 < 9; l1++) { + addSlot(new Slot(player, l1 + i1 * 9 + 9, 18 + l1 * 18, 120 + i1 * 18)); + } + } + // Player hotbar + for (int j1 = 0; j1 < 9; j1++) { + addSlot(new Slot(player, j1, 18 + j1 * 18, 178)); + } + } + + public void purgeBag(EntityPlayer player) { + for (int i = 0; i < inventory.getSizeInventory(); i++) { + ItemStack stack = inventory.getStackInSlot(i); + if (stack == null) + continue; + + if (speciesRoot.isMember(stack)) + continue; + + Proxies.common.dropItemPlayer(player, stack); + inventory.setInventorySlotContents(i, null); + } + } + + @Override + public void handleSelectionChange(EntityPlayer player, PacketUpdate packet) { + inv.flipPage(player, packet.payload.intPayload[0]); + } + + @Override + public void setSelection(PacketUpdate packet) { + } +} diff --git a/forestry_common/core/forestry/core/gui/ContainerSocketed.java b/forestry_common/core/forestry/core/gui/ContainerSocketed.java new file mode 100755 index 000000000..0ff47e3fd --- /dev/null +++ b/forestry_common/core/forestry/core/gui/ContainerSocketed.java @@ -0,0 +1,85 @@ +/******************************************************************************* + * Copyright 2011-2014 by SirSengir + * + * This work is licensed under a Creative Commons Attribution-NonCommercial-NoDerivs 3.0 Unported License. + * + * To view a copy of this license, visit http://creativecommons.org/licenses/by-nc-nd/3.0/. + ******************************************************************************/ +package forestry.core.gui; + +import net.minecraft.entity.player.EntityPlayer; +import net.minecraft.inventory.IInventory; +import net.minecraft.item.ItemStack; +import net.minecraft.tileentity.TileEntity; + +import forestry.core.interfaces.ISocketable; +import forestry.core.network.PacketIds; +import forestry.core.network.PacketPayload; +import forestry.core.network.PacketSocketUpdate; +import forestry.core.network.PacketUpdate; +import forestry.core.proxy.Proxies; +import forestry.core.utils.StackUtils; + +public class ContainerSocketed extends ContainerForestry { + + ISocketable tile; + + public ContainerSocketed(IInventory inventory, ISocketable tile) { + super(inventory); + this.tile = tile; + } + + public void handleChipsetClick(int slot, EntityPlayer player, ItemStack itemstack) { + if (!Proxies.common.isSimulating(player.worldObj)) { + PacketPayload payload = new PacketPayload(1, 0, 0); + payload.intPayload[0] = slot; + Proxies.net.sendToServer(new PacketUpdate(PacketIds.CHIPSET_CLICK, payload)); + player.inventory.setItemStack(null); + return; + } + + ItemStack toSocket = itemstack.copy(); + toSocket.stackSize = 1; + tile.setSocket(slot, toSocket); + + if (Proxies.common.isSimulating(player.worldObj)) { + ItemStack stack = player.inventory.getItemStack(); + stack.stackSize--; + if(stack.stackSize <= 0) + player.inventory.setItemStack(null); + Proxies.net.inventoryChangeNotify(player); + + TileEntity te = (TileEntity) tile; + Proxies.net.sendToPlayer(new PacketSocketUpdate(PacketIds.SOCKET_UPDATE, te.xCoord, te.yCoord, te.zCoord, tile), player); + } + + } + + public void handleSolderingIronClick(int slot, EntityPlayer player, ItemStack itemstack) { + if (!Proxies.common.isSimulating(player.worldObj)) { + PacketPayload payload = new PacketPayload(1, 0, 0); + payload.intPayload[0] = slot; + Proxies.net.sendToServer(new PacketUpdate(PacketIds.SOLDERING_IRON_CLICK, payload)); + return; + } + + ItemStack socket = tile.getSocket(slot); + if (socket == null) + return; + + StackUtils.stowInInventory(socket, player.inventory, true); + // Not sufficient space in player's inventory. failed to stow. + if (socket.stackSize > 0) + return; + + tile.setSocket(slot, null); + itemstack.damageItem(1, player); + if (itemstack.stackSize <= 0) + player.inventory.setItemStack(null); + + TileEntity te = (TileEntity) tile; + Proxies.net.sendToPlayer(new PacketSocketUpdate(PacketIds.SOCKET_UPDATE, te.xCoord, te.yCoord, te.zCoord, tile), player); + + } + +} diff --git a/forestry_common/core/forestry/core/gui/ErrorLedger.java b/forestry_common/core/forestry/core/gui/ErrorLedger.java new file mode 100755 index 000000000..9dd062be7 --- /dev/null +++ b/forestry_common/core/forestry/core/gui/ErrorLedger.java @@ -0,0 +1,64 @@ +/******************************************************************************* + * Copyright 2011-2014 by SirSengir + * + * This work is licensed under a Creative Commons Attribution-NonCommercial-NoDerivs 3.0 Unported License. + * + * To view a copy of this license, visit http://creativecommons.org/licenses/by-nc-nd/3.0/. + ******************************************************************************/ +package forestry.core.gui; + +import forestry.core.EnumErrorCode; +import forestry.core.interfaces.IErrorSource; +import forestry.core.utils.StringUtil; + +/** + * A ledger displaying error messages and help text. + */ +public class ErrorLedger extends Ledger { + + IErrorSource tile; + + public ErrorLedger(LedgerManager manager, IErrorSource tile) { + super(manager); + this.tile = tile; + maxHeight = 72; + overlayColor = manager.gui.fontColor.get("ledger.error.background"); + } + + @Override + public void draw(int x, int y) { + EnumErrorCode state = tile.getErrorState(); + if (state == EnumErrorCode.OK) + return; + + // Draw background + drawBackground(x, y); + + // Draw icon + drawIcon(state.getIcon(), x + 3, y + 4); + + // Write description if fully opened + if (isFullyOpened()) { + // fontRendererObj.drawStringWithShadow(getTooltip(), x + 22, y + + // 8, 0xe1c92f); + manager.minecraft.fontRenderer.drawStringWithShadow(getTooltip(), x + 22, y + 8, manager.gui.fontColor.get("ledger.error.header")); + manager.minecraft.fontRenderer.drawSplitString(StringUtil.localize(tile.getErrorState().getHelp()), x + 22, y + 20, maxWidth - 28, + manager.gui.fontColor.get("ledger.error.text")); + } + } + + @Override + public boolean isVisible() { + EnumErrorCode state = tile.getErrorState(); + if (state == EnumErrorCode.OK) + return false; + else + return true; + } + + @Override + public String getTooltip() { + return StringUtil.localize(tile.getErrorState().getDescription()); + } + +} diff --git a/forestry_common/core/forestry/core/gui/GuiAlyzer.java b/forestry_common/core/forestry/core/gui/GuiAlyzer.java new file mode 100755 index 000000000..5023671b8 --- /dev/null +++ b/forestry_common/core/forestry/core/gui/GuiAlyzer.java @@ -0,0 +1,376 @@ +/******************************************************************************* + * Copyright 2011-2014 by SirSengir + * + * This work is licensed under a Creative Commons Attribution-NonCommercial-NoDerivs 3.0 Unported License. + * + * To view a copy of this license, visit http://creativecommons.org/licenses/by-nc-nd/3.0/. + ******************************************************************************/ +package forestry.core.gui; + +import java.util.HashMap; +import java.util.Locale; +import java.util.Map; +import java.util.Stack; + +import net.minecraft.client.renderer.RenderHelper; +import net.minecraft.entity.player.EntityPlayer; +import net.minecraft.inventory.IInventory; +import net.minecraft.item.ItemStack; + +import org.lwjgl.opengl.GL11; + +import forestry.api.apiculture.EnumBeeChromosome; +import forestry.api.genetics.AlleleManager; +import forestry.api.genetics.EnumTolerance; +import forestry.api.genetics.IAllele; +import forestry.api.genetics.IAlleleSpecies; +import forestry.api.genetics.IBreedingTracker; +import forestry.api.genetics.IClassification; +import forestry.api.genetics.IClassification.EnumClassLevel; +import forestry.api.genetics.IIndividual; +import forestry.api.genetics.IMutation; +import forestry.api.genetics.ISpeciesRoot; +import forestry.core.config.Defaults; +import forestry.core.gadgets.TileForestry; +import forestry.core.genetics.EnumMutateChance; +import forestry.core.proxy.Proxies; +import forestry.core.utils.StringUtil; + +public abstract class GuiAlyzer extends GuiForestry { + + protected static final int COLUMN_0 = 12; + protected static final int COLUMN_1 = 52; + protected static final int COLUMN_2 = 108; + + protected IInventory inventory; + protected ISpeciesRoot speciesRoot; + protected IBreedingTracker breedingTracker; + + protected HashMap iconStacks = new HashMap(); + + public GuiAlyzer(ISpeciesRoot speciesRoot, EntityPlayer player, ContainerForestry container, IInventory inventory, int pageMax, int pageSize) { + super(Defaults.TEXTURE_PATH_GUI + "/beealyzer.png", container); + + this.inventory = inventory; + this.speciesRoot = speciesRoot; + this.breedingTracker = speciesRoot.getBreedingTracker(player.worldObj, player.getGameProfile().getId()); + } + + protected final int getColorCoding(boolean dominant) { + if (dominant) + return fontColor.get("gui.beealyzer.dominant"); + else + return fontColor.get("gui.beealyzer.recessive"); + } + + protected final void drawLine(String text, int x, IIndividual individual, Enum chromosome, boolean inactive) { + if (!inactive) + drawLine(text, x, getColorCoding(individual.getGenome().getActiveAllele(chromosome.ordinal()).isDominant())); + else + drawLine(text, x, getColorCoding(individual.getGenome().getInactiveAllele(chromosome.ordinal()).isDominant())); + } + + protected final void drawSplitLine(String text, int x, int maxWidth, IIndividual individual, Enum chromosome, boolean inactive) { + if (!inactive) + drawSplitLine(text, x, maxWidth, getColorCoding(individual.getGenome().getActiveAllele(chromosome.ordinal()).isDominant())); + else + drawSplitLine(text, x, maxWidth, getColorCoding(individual.getGenome().getInactiveAllele(chromosome.ordinal()).isDominant())); + } + + protected final void drawRow(String text0, String text1, String text2, IIndividual individual, Enum chromosome) { + drawRow(text0, text1, text2, fontColor.get("gui.screen"), getColorCoding(individual.getGenome().getActiveAllele(chromosome.ordinal()).isDominant()), + getColorCoding(individual.getGenome().getInactiveAllele(chromosome.ordinal()).isDominant())); + } + + protected final void drawSpeciesRow(String text0, IIndividual individual, Enum chromosome) { + IAlleleSpecies primary = individual.getGenome().getPrimary(); + IAlleleSpecies secondary = individual.getGenome().getSecondary(); + + drawLine(text0, column0); + int columnwidth = column2 - column1 - 16; + + RenderHelper.enableStandardItemLighting(); + drawItemStack(iconStacks.get(primary.getUID()), adjustToFactor(guiLeft + column1 + columnwidth + 2), adjustToFactor(guiTop + getLineY())); + drawItemStack(iconStacks.get(secondary.getUID()), adjustToFactor(guiLeft + column2 + columnwidth + 4), adjustToFactor(guiTop + getLineY())); + RenderHelper.disableStandardItemLighting(); + + drawSplitLine(primary.getName(), column1, columnwidth, individual, chromosome, false); + drawSplitLine(secondary.getName(), column2, columnwidth, individual, chromosome, true); + + newLine(); + newLine(); + + } + + protected final void drawAnalyticsPageClassification(IIndividual individual) { + + startPage(); + + drawLine(StringUtil.localize("gui.alyzer.classification") + ":", 12); + newLine(); + + Stack hierarchy = new Stack(); + IClassification classification = individual.getGenome().getPrimary().getBranch(); + while (classification != null) { + + if (classification.getScientific() != null && !classification.getScientific().isEmpty()) + hierarchy.push(classification); + classification = classification.getParent(); + } + + boolean overcrowded = hierarchy.size() > 5; + int x = 12; + IClassification group = null; + + while (!hierarchy.isEmpty()) { + + group = hierarchy.pop(); + if (overcrowded && group.getLevel().isDroppable()) + continue; + + drawLine(group.getScientific(), x, group.getLevel().getColour()); + drawLine(group.getLevel().name(), 130, group.getLevel().getColour()); + newLine(); + x += 8; + } + + // Add the species name + String binomial = individual.getGenome().getPrimary().getBinomial(); + if (group != null && group.getLevel() == EnumClassLevel.GENUS) + binomial = group.getScientific().substring(0, 1) + ". " + binomial.toLowerCase(Locale.ENGLISH); + + drawLine(binomial, x, 0xebae85); + drawLine("SPECIES", 130, 0xebae85); + + newLine(); + newLine(); + drawLine(StringUtil.localize("gui.alyzer.authority") + ": " + individual.getGenome().getPrimary().getAuthority(), 12); + if (AlleleManager.alleleRegistry.isBlacklisted(individual.getIdent())) { + String extinct = ">> " + StringUtil.localize("gui.alyzer.extinct").toUpperCase() + " <<"; + fontRendererObj.drawStringWithShadow(extinct, adjustToFactor(guiLeft + 160) - fontRendererObj.getStringWidth(extinct), + adjustToFactor(guiTop + getLineY()), fontColor.get("gui.beealyzer.dominant")); + } + + newLine(); + String description = individual.getGenome().getPrimary().getDescription(); + if (description == null || description.isEmpty()) + drawSplitLine(StringUtil.localize("gui.alyzer.nodescription"), 12, 156, 0x666666); + else { + String tokens[] = description.split("\\|"); + drawSplitLine(tokens[0], 12, 152, 0x666666); + if (tokens.length > 1) + fontRendererObj.drawStringWithShadow("- " + tokens[1], adjustToFactor(guiLeft + 160) - fontRendererObj.getStringWidth("- " + tokens[1]), + adjustToFactor(guiTop + 145 - 14), 0x99cc32); + } + + endPage(); + + } + + protected void drawAnalyticsPage4(IIndividual individual) { + + startPage(COLUMN_0, COLUMN_1, COLUMN_2); + drawLine(StringUtil.localize("gui.beealyzer.mutations") + ":", COLUMN_0); + newLine(); + newLine(); + + RenderHelper.enableGUIStandardItemLighting(); + + HashMap combinations = new HashMap(); + + for (IMutation mutation : speciesRoot.getCombinations(individual.getGenome().getPrimary())) + combinations.put(mutation, individual.getGenome().getPrimary()); + + for (IMutation mutation : speciesRoot.getCombinations(individual.getGenome().getSecondary())) + combinations.put(mutation, individual.getGenome().getSecondary()); + + int columnWidth = 50; + int x = 0; + + for (Map.Entry mutation : combinations.entrySet()) { + + if (breedingTracker.isDiscovered(mutation.getKey())) + drawMutationInfo(mutation.getKey(), mutation.getValue(), COLUMN_0 + x); + else { + // Do not display secret undiscovered mutations. + if (mutation.getKey().isSecret()) + continue; + + drawUnknownMutation(mutation.getKey(), mutation.getValue(), COLUMN_0 + x); + } + + x += columnWidth; + if (x > 150) { + x = 0; + newLine(); + newLine(); + } + } + + endPage(); + } + + protected void drawMutationInfo(IMutation combination, IAllele species, int x) { + + drawItemStack(iconStacks.get(combination.getPartner(species).getUID()), + adjustToFactor(guiLeft) + x, adjustToFactor(guiTop) + getLineY()); + /* + itemRenderer.renderItemIntoGUI(fontRendererObj, mc.renderEngine, iconStacks.get(combination.getPartner(species).getUID()), adjustToFactor(guiLeft) + x, + adjustToFactor(guiTop) + getLineY()); + itemRenderer.renderItemOverlayIntoGUI(fontRendererObj, mc.renderEngine, iconStacks.get(combination.getPartner(species).getUID()), adjustToFactor(guiLeft) + + x, adjustToFactor(guiTop) + getLineY()); + */ + + IAllele result = combination.getTemplate()[EnumBeeChromosome.SPECIES.ordinal()]; + + drawItemStack(iconStacks.get(result.getUID()), + adjustToFactor(guiLeft) + x + 33, adjustToFactor(guiTop) + getLineY()); + /* + itemRenderer.renderItemIntoGUI(fontRendererObj, mc.renderEngine, iconStacks.get(result.getUID()), adjustToFactor(guiLeft) + x + 33, adjustToFactor(guiTop) + + getLineY()); + itemRenderer.renderItemOverlayIntoGUI(fontRendererObj, mc.renderEngine, iconStacks.get(result.getUID()), adjustToFactor(guiLeft) + x + 33, + adjustToFactor(guiTop) + getLineY()); + */ + + int line = 0; + int column = 196; + + switch (EnumMutateChance.rateChance(combination.getBaseChance())) { + case HIGHEST: + column = 226; + line = 9; + break; + case HIGHER: + column = 211; + line = 9; + break; + case HIGH: + line = 9; + break; + case NORMAL: + column = 226; + break; + case LOW: + column = 211; + break; + case LOWEST: + default: + break; + } + + Proxies.common.bindTexture(textureFile); + drawTexturedModalRect(adjustToFactor(guiLeft) + x + 18, adjustToFactor(guiTop) + getLineY() + 4, column, line, 15, 9); + + } + + protected void drawUnknownMutation(IMutation combination, IAllele species, int x) { + + // Question marks + Proxies.common.bindTexture(textureFile); + drawTexturedModalRect(adjustToFactor(guiLeft) + x, adjustToFactor(guiTop) + getLineY(), 196, 18, 16, 16); + + Proxies.common.bindTexture(textureFile); + drawTexturedModalRect(adjustToFactor(guiLeft) + x + 32, adjustToFactor(guiTop) + getLineY(), 196, 18, 16, 16); + + int line = 0; + int column = 196; + + switch (EnumMutateChance.rateChance(combination.getBaseChance())) { + case HIGHEST: + column = 226; + line = 9; + break; + case HIGHER: + column = 211; + line = 9; + break; + case HIGH: + line = 9; + break; + case NORMAL: + column = 226; + break; + case LOW: + column = 211; + break; + case LOWEST: + default: + break; + } + + // Probability arrow + Proxies.common.bindTexture(textureFile); + drawTexturedModalRect(adjustToFactor(guiLeft) + x + 18, adjustToFactor(guiTop) + getLineY() + 4, column, line, 15, 9); + + } + + protected void drawToleranceInfo(EnumTolerance tolerance, int x, int textColor) { + int length = tolerance.toString().length(); + String text = "(" + tolerance.toString().substring(length - 1) + ")"; + + // Enable correct lighting. + GL11.glColor4f(1.0F, 1.0F, 1.0F, 1.0F); + + switch (tolerance) { + case BOTH_1: + case BOTH_2: + case BOTH_3: + case BOTH_4: + case BOTH_5: + drawBothSymbol(x, getLineY() - 1); + drawLine(text, x + (int) (20 * factor), textColor); + break; + case DOWN_1: + case DOWN_2: + case DOWN_3: + case DOWN_4: + case DOWN_5: + drawDownSymbol(x, getLineY() - 1); + drawLine(text, x + (int) (20 * factor), textColor); + break; + case UP_1: + case UP_2: + case UP_3: + case UP_4: + case UP_5: + drawUpSymbol(x, getLineY() - 1); + drawLine(text, x + (int) (20 * factor), textColor); + break; + default: + drawNoneSymbol(x, getLineY() - 1); + drawLine("(0)", x + (int) (20 * factor), textColor); + break; + } + } + + private void drawDownSymbol(int x, int y) { + Proxies.common.bindTexture(textureFile); + drawTexturedModalRect((int) ((guiLeft + x) * (1 / factor)), (int) ((guiTop + getLineY()) * (1 / factor)), 196, 34, 15, 9); + } + + private void drawUpSymbol(int x, int y) { + Proxies.common.bindTexture(textureFile); + drawTexturedModalRect((int) ((guiLeft + x) * (1 / factor)), (int) ((guiTop + getLineY()) * (1 / factor)), 211, 34, 15, 9); + } + + private void drawBothSymbol(int x, int y) { + Proxies.common.bindTexture(textureFile); + drawTexturedModalRect((int) ((guiLeft + x) * (1 / factor)), (int) ((guiTop + getLineY()) * (1 / factor)), 226, 34, 15, 9); + } + + private void drawNoneSymbol(int x, int y) { + Proxies.common.bindTexture(textureFile); + drawTexturedModalRect((int) ((guiLeft + x) * (1 / factor)), (int) ((guiTop + getLineY()) * (1 / factor)), 241, 34, 15, 9); + } + + protected void drawFertilityInfo(int fertility, int x, int textColor, int texOffset) { + // Enable correct lighting. + GL11.glColor4f(1.0F, 1.0F, 1.0F, 1.0F); + + Proxies.common.bindTexture(textureFile); + drawTexturedModalRect((int) ((guiLeft + x + 19) * (1 / factor)), (int) ((guiTop + getLineY()) * (1 / factor)), 196, 43 + texOffset, 12, 9); + + drawLine(Integer.toString(fertility) + " x", x, textColor); + } + +} diff --git a/forestry_common/core/forestry/core/gui/GuiAnalyzer.java b/forestry_common/core/forestry/core/gui/GuiAnalyzer.java new file mode 100755 index 000000000..a2f6fabab --- /dev/null +++ b/forestry_common/core/forestry/core/gui/GuiAnalyzer.java @@ -0,0 +1,64 @@ +/******************************************************************************* + * Copyright 2011-2014 by SirSengir + * + * This work is licensed under a Creative Commons Attribution-NonCommercial-NoDerivs 3.0 Unported License. + * + * To view a copy of this license, visit http://creativecommons.org/licenses/by-nc-nd/3.0/. + ******************************************************************************/ +package forestry.core.gui; + +import net.minecraft.entity.player.InventoryPlayer; + +import forestry.core.config.Defaults; +import forestry.core.gadgets.TileAnalyzer; +import forestry.core.gui.widgets.TankWidget; +import forestry.core.utils.EnumTankLevel; +import forestry.core.utils.StringUtil; +import forestry.core.utils.Utils; + +public class GuiAnalyzer extends GuiForestry { + + public GuiAnalyzer(InventoryPlayer inventory, TileAnalyzer tile) { + super(Defaults.TEXTURE_PATH_GUI + "/alyzer.png", new ContainerAnalyzer(inventory, tile), tile); + ySize = 176; + widgetManager.add(new TankWidget(this.widgetManager, 95, 24, 0)); + } + + @Override + protected void drawGuiContainerForegroundLayer(int mouseX, int mouseY) { + super.drawGuiContainerForegroundLayer(mouseX, mouseY); + String title = StringUtil.localize("tile.for." + tile.getInventoryName()); + this.fontRendererObj.drawString(title, getCenteredOffset(title), 6, fontColor.get("gui.title")); + } + + @Override + protected void drawGuiContainerBackgroundLayer(float var1, int mouseX, int mouseY) { + super.drawGuiContainerBackgroundLayer(var1, mouseX, mouseY); + TileAnalyzer machine = tile; + drawAnalyzeMeter(guiLeft + 64, guiTop + 30, machine.getProgressScaled(46), Utils.rateTankLevel(machine.getProgressScaled(100))); + + } + + private void drawAnalyzeMeter(int x, int y, int height, EnumTankLevel rated) { + int i = 176; + int k = 60; + switch (rated) { + case EMPTY: + break; + case LOW: + i += 4; + break; + case MEDIUM: + i += 8; + break; + case HIGH: + i += 12; + break; + case MAXIMUM: + i += 16; + break; + } + + drawTexturedModalRect(x, y + 46 - height, i, k + 46 - height, 4, height); + } +} diff --git a/forestry_common/core/forestry/core/gui/GuiEscritoire.java b/forestry_common/core/forestry/core/gui/GuiEscritoire.java new file mode 100755 index 000000000..e629b1e78 --- /dev/null +++ b/forestry_common/core/forestry/core/gui/GuiEscritoire.java @@ -0,0 +1,254 @@ +/******************************************************************************* + * Copyright 2011-2014 by SirSengir + * + * This work is licensed under a Creative Commons Attribution-NonCommercial-NoDerivs 3.0 Unported License. + * + * To view a copy of this license, visit http://creativecommons.org/licenses/by-nc-nd/3.0/. + ******************************************************************************/ +package forestry.core.gui; + +import net.minecraft.client.renderer.RenderHelper; +import net.minecraft.entity.player.EntityPlayer; +import net.minecraft.init.Items; +import net.minecraft.item.ItemStack; + +import org.lwjgl.opengl.GL11; + +import forestry.core.config.Defaults; +import forestry.core.gadgets.NaturalistGame; +import forestry.core.gadgets.NaturalistGame.GameToken; +import forestry.core.gadgets.TileEscritoire; +import forestry.core.gui.widgets.Widget; +import forestry.core.proxy.Proxies; +import forestry.core.render.SpriteSheet; +import forestry.core.render.TextureManager; +import forestry.core.utils.StringUtil; + +public class GuiEscritoire extends GuiForestry { + + private static String[][] researchNotes = new String[][] { + new String[] { "I have found a curious specimen on my travels.", "This strange fellow needs further investigation.", "Elated, I wanted to start at once with my research." }, + new String[] { "I was amazed at the wondrous nature of it.", "The specimen twitched, while I inspected it more closely.", "Strange markings on the underside made me curious.", "This will be the talk of the society when I am done investigating." }, + new String[] { "After some prodding I discovered an interesting new lead.", "I scratched my head at this discovery and questioned everything.", "I thought my eyes deceived me, but there it was.", "A previously unseen dot led me to question the specimen's classification." }, + new String[] { "My screams of frustration had the housekeeper look into my study in worry.", "In a frenzy and on the verge of despair, I ripped up all the notes!", "This... just doesn't make any sense!", "It just cannot be. It didn't do that before!", "The sledgehammer barely made a dent, so I sent for the chainsaw.", "I swear it was looking at me, with its beady, cruel, little eyes.", "Is that laughter? Do I hear laughter? Who is laughing here?" }, + new String[] { "EUREKA!", "Wondrous! My name will go down in history!", "My colleagues will be impressed!", "I will be the envy of everyone at the society!", "Woot!" }, + new String[] { "All is lost.", "I consign my notes to the fire.", "Why? I had made such great strides at first...", "Failed. Again.", "Oh my..." } + }; + + private class TokenSlot extends Widget { + + private final ItemStack HIDDEN_TOKEN; + private final int index; + + public TokenSlot(WidgetManager manager, int xPos, int yPos, int index) { + super(manager, xPos, yPos); + this.index = index; + + HIDDEN_TOKEN = new ItemStack(Items.book); + } + + private boolean hasToken() { + return tile.getGame().getToken(index) != null; + } + + private GameToken getToken() { + return tile.getGame().getToken(index); + } + + @Override + public void draw(int startX, int startY) { + + if (!hasToken()) + return; + + int tokenColour = getToken().getTokenColour(); + + float colorR = (tokenColour >> 16 & 255) / 255.0F; + float colorG = (tokenColour >> 8 & 255) / 255.0F; + float colorB = (tokenColour & 255) / 255.0F; + + manager.gui.bindTexture(manager.gui.textureFile); + GL11.glColor4f(colorR, colorG, colorB, 1.0F); + manager.gui.drawTexturedModalRect(startX + xPos, startY + yPos, 228, 0, 22, 22); + GL11.glColor4f(1.0f, 1.0f, 1.0f, 1.0F); + + ItemStack tokenStack = HIDDEN_TOKEN; + if (getToken().isVisible()) + tokenStack = getToken().tokenStack; + + + + GL11.glPushAttrib(GL11.GL_ENABLE_BIT); + GL11.glEnable(GL11.GL_DEPTH_TEST); + RenderHelper.enableGUIStandardItemLighting(); + manager.gui.drawItemStack(tokenStack, startX + xPos + 3, startY + yPos + 3); + RenderHelper.disableStandardItemLighting(); + GL11.glPopAttrib(); + + manager.gui.setZLevel(150f); + for (String ident : getToken().getOverlayIcons()) { + RenderHelper.enableGUIStandardItemLighting(); + Proxies.common.bindTexture(SpriteSheet.ITEMS); + manager.gui.drawTexturedModelRectFromIcon(startX + xPos + 3, startY + yPos + 3, TextureManager.getInstance().getDefault(ident), 16, 16); + RenderHelper.disableStandardItemLighting(); + } + manager.gui.setZLevel(0f); + } + + @Override + protected String getLegacyTooltip(EntityPlayer player) { + return hasToken() && getToken().isVisible() ? getToken().getTooltip() : null; + } + + @Override + public void handleMouseClick(int mouseX, int mouseY, int mouseButton) { + container.sendTokenClick(index); + } + } + + private class ProbeButton extends Widget { + + private boolean pressed; + + public ProbeButton(WidgetManager manager, int xPos, int yPos) { + super(manager, xPos, yPos); + width = 22; + height = 25; + } + + @Override + public void draw(int startX, int startY) { + manager.gui.bindTexture(manager.gui.textureFile); + GL11.glColor4f(1.0f, 1.0f, 1.0f, 1.0F); + manager.gui.drawTexturedModalRect(startX + xPos, startY + yPos, 228, pressed ? 47 : 22, width, height); + } + + @Override + protected String getLegacyTooltip(EntityPlayer player) { + return StringUtil.localize("gui.escritoire.probe"); + } + + @Override + public void handleMouseClick(int mouseX, int mouseY, int mouseButton) { + pressed = true; + container.sendProbeClick(); + } + + @Override + public void handleMouseRelease(int mouseX, int mouseY, int eventType) { + if (pressed) + pressed = false; + } + + @Override + public void handleMouseMove(int mouseX, int mouseY, int mouseButton, long time) { + if (widgetManager.getAtPosition(mouseX - getGuiLeft(), mouseY - getGuiTop()) != this) + pressed = false; + } + } + private final ItemStack LEVEL_ITEM; + protected ContainerEscritoire container; + private final TileEscritoire tile; + private String researchNote = ""; + private long lastUpdate; + + public GuiEscritoire(EntityPlayer player, TileEscritoire tile) { + super(Defaults.TEXTURE_PATH_GUI + "/escritoire.png", new ContainerEscritoire(player, tile)); + + LEVEL_ITEM = new ItemStack(Items.paper); + + xSize = 228; + ySize = 235; + + this.container = (ContainerEscritoire) inventorySlots; + this.tile = tile; + + widgetManager.add(new ProbeButton(widgetManager, 14, 16)); + + // Inner ring + widgetManager.add(new TokenSlot(widgetManager, 115, 51, 0)); + widgetManager.add(new TokenSlot(widgetManager, 115, 77, 1)); + widgetManager.add(new TokenSlot(widgetManager, 94, 90, 2)); + widgetManager.add(new TokenSlot(widgetManager, 73, 77, 3)); + widgetManager.add(new TokenSlot(widgetManager, 73, 51, 4)); + widgetManager.add(new TokenSlot(widgetManager, 94, 38, 5)); + + // Outer ring + widgetManager.add(new TokenSlot(widgetManager, 115, 25, 6)); + widgetManager.add(new TokenSlot(widgetManager, 136, 38, 7)); + widgetManager.add(new TokenSlot(widgetManager, 136, 64, 8)); + + widgetManager.add(new TokenSlot(widgetManager, 136, 90, 9)); + widgetManager.add(new TokenSlot(widgetManager, 115, 103, 10)); + widgetManager.add(new TokenSlot(widgetManager, 94, 116, 11)); + + widgetManager.add(new TokenSlot(widgetManager, 73, 103, 12)); + widgetManager.add(new TokenSlot(widgetManager, 52, 90, 13)); + widgetManager.add(new TokenSlot(widgetManager, 52, 64, 14)); + + widgetManager.add(new TokenSlot(widgetManager, 52, 38, 15)); + widgetManager.add(new TokenSlot(widgetManager, 73, 25, 16)); + widgetManager.add(new TokenSlot(widgetManager, 94, 12, 17)); + + // Corners + widgetManager.add(new TokenSlot(widgetManager, 52, 12, 18)); + widgetManager.add(new TokenSlot(widgetManager, 136, 12, 19)); + widgetManager.add(new TokenSlot(widgetManager, 52, 116, 20)); + widgetManager.add(new TokenSlot(widgetManager, 136, 116, 21)); + } + + @Override + protected void drawGuiContainerBackgroundLayer(float var1, int mouseX, int mouseY) { + super.drawGuiContainerBackgroundLayer(var1, mouseX, mouseY); + + for (int i = 0; i <= tile.getGame().getBountyLevel() / 4; i++) { + RenderHelper.enableGUIStandardItemLighting(); + GuiForestry.itemRender.renderItemAndEffectIntoGUI(mc.fontRenderer, + mc.renderEngine, LEVEL_ITEM, guiLeft + 170 + i * 8, guiTop + 7); + RenderHelper.disableStandardItemLighting(); + } + + startPage(); + setFactor(0.5f); + + newLine(); + newLine(); + drawLine("\u00A7n\u00A7oAttempt No. " + (NaturalistGame.BOUNTY_MAX - tile.getGame().getBountyLevel()), 171, fontColor.get("gui.mail.lettertext")); + newLine(); + drawSplitLine(getResearchNote(), 171, 46, fontColor.get("gui.mail.lettertext")); + + endPage(); + } + + private String getResearchNote() { + if (lastUpdate == tile.getGame().getLastUpdate()) + return researchNote; + + if (!tile.getGame().isInited()) + researchNote = ""; + else { + if (tile.getGame().isWon()) { + researchNote = getRandomNote(researchNotes[4]); + } else if (tile.getGame().isEnded()) { + researchNote = getRandomNote(researchNotes[5]); + } else { + int bounty = tile.getGame().getBountyLevel(); + if (bounty >= NaturalistGame.BOUNTY_MAX) { + researchNote = getRandomNote(researchNotes[0]); + } else if (bounty > NaturalistGame.BOUNTY_MAX / 2) { + researchNote = getRandomNote(researchNotes[1]); + } else if (bounty > NaturalistGame.BOUNTY_MAX / 4) { + researchNote = getRandomNote(researchNotes[2]); + } else + researchNote = getRandomNote(researchNotes[3]); + } + } + + lastUpdate = tile.getGame().getLastUpdate(); + return researchNote; + } + + private String getRandomNote(String[] candidates) { + return candidates[mc.theWorld.rand.nextInt(candidates.length)]; + } +} diff --git a/forestry_common/core/forestry/core/gui/GuiForestry.java b/forestry_common/core/forestry/core/gui/GuiForestry.java new file mode 100755 index 000000000..6ac3fb086 --- /dev/null +++ b/forestry_common/core/forestry/core/gui/GuiForestry.java @@ -0,0 +1,545 @@ +/******************************************************************************* + * Copyright 2011-2014 by SirSengir + * + * This work is licensed under a Creative Commons Attribution-NonCommercial-NoDerivs 3.0 Unported License. + * + * To view a copy of this license, visit http://creativecommons.org/licenses/by-nc-nd/3.0/. + ******************************************************************************/ +package forestry.core.gui; + +import java.util.Collection; +import java.util.List; + +import net.minecraft.client.gui.FontRenderer; +import net.minecraft.client.gui.inventory.GuiContainer; +import net.minecraft.client.renderer.OpenGlHelper; +import net.minecraft.client.renderer.RenderHelper; +import net.minecraft.client.renderer.Tessellator; +import net.minecraft.client.renderer.entity.RenderItem; +import net.minecraft.entity.player.InventoryPlayer; +import net.minecraft.inventory.Slot; +import net.minecraft.item.EnumRarity; +import net.minecraft.item.ItemStack; +import net.minecraft.util.IIcon; +import net.minecraft.util.ResourceLocation; + +import org.lwjgl.opengl.GL11; +import org.lwjgl.opengl.GL12; + +import forestry.core.config.Config; +import forestry.core.gadgets.TileForestry; +import forestry.core.gui.slots.SlotForestry; +import forestry.core.gui.tooltips.IToolTipProvider; +import forestry.core.gui.tooltips.ToolTip; +import forestry.core.gui.tooltips.ToolTipLine; +import forestry.core.interfaces.IClimatised; +import forestry.core.interfaces.IErrorSource; +import forestry.core.interfaces.IHintSource; +import forestry.core.interfaces.IOwnable; +import forestry.core.interfaces.IPowerHandler; +import forestry.core.proxy.Proxies; +import forestry.core.utils.FontColour; + +public abstract class GuiForestry extends GuiContainer { + + /* WIDGETS */ + protected WidgetManager widgetManager; + /* LEDGERS */ + protected LedgerManager ledgerManager = new LedgerManager(this); + protected T tile; + public ResourceLocation textureFile; + protected FontColour fontColor; + + public GuiForestry(ContainerForestry container) { + this("", container); + } + + public GuiForestry(String texture, ContainerForestry container) { + this(new ResourceLocation("forestry", texture), container, null); + } + + public GuiForestry(String texture, ContainerForestry container, Object inventory) { + this(new ResourceLocation("forestry", texture), container, inventory); + } + + public GuiForestry(ResourceLocation texture, ContainerForestry container) { + this(texture, container, null); + } + + @SuppressWarnings("unchecked") + public GuiForestry(ResourceLocation texture, ContainerForestry container, Object inventory) { + super(container); + this.widgetManager = new WidgetManager(this); + this.ledgerManager = new LedgerManager(this); + + this.textureFile = texture; + this.inventorySlots = container; + + if (inventory instanceof TileForestry) + this.tile = (T) inventory; + + fontColor = new FontColour(Proxies.common.getSelectedTexturePack(Proxies.common.getClientInstance())); + initLedgers(inventory); + } + + /* LEDGERS */ + protected void initLedgers(Object inventory) { + + if (inventory instanceof IErrorSource && ((IErrorSource) inventory).throwsErrors()) + ledgerManager.add(new ErrorLedger(ledgerManager, (IErrorSource) inventory)); + + if (inventory instanceof IClimatised && ((IClimatised) inventory).isClimatized()) + ledgerManager.add(new ClimateLedger(ledgerManager, (IClimatised) inventory)); + + if (!Config.disableEnergyStat && inventory instanceof IPowerHandler) + ledgerManager.add(new PowerLedger(ledgerManager, (IPowerHandler) inventory)); + + if (!Config.disableHints && inventory instanceof IHintSource && ((IHintSource) inventory).hasHints()) + ledgerManager.add(new HintLedger(ledgerManager, (IHintSource) inventory)); + + if (inventory instanceof IOwnable && ((IOwnable) inventory).isOwnable()) + ledgerManager.add(new OwnerLedger(ledgerManager, (IOwnable) inventory)); + + } + + /* TEXT HELPER FUNCTIONS */ + protected int column0; + protected int column1; + protected int column2; + private int line; + protected float factor = 0.75f; + + protected final void setFactor(float factor) { + this.factor = factor; + } + + protected final void startPage() { + line = 12; + GL11.glPushMatrix(); + GL11.glScalef(factor, factor, factor); + } + + protected final void startPage(int column0, int column1, int column2) { + + this.column0 = column0; + this.column1 = column1; + this.column2 = column2; + + startPage(); + } + + protected final int adjustToFactor(int fixed) { + return (int) (fixed * (1 / factor)); + } + + protected final int getLineY() { + return line; + } + + protected final void newLine() { + line += 12 * factor; + } + + protected final void newLine(int lineHeight) { + line += lineHeight * factor; + } + + protected final void endPage() { + GL11.glPopMatrix(); + } + + protected final void drawRow(String text0, String text1, String text2, int colour0, int colour1, int colour2) { + drawLine(text0, column0, colour0); + drawLine(text1, column1, colour1); + drawLine(text2, column2, colour2); + newLine(); + } + + protected final void drawLine(String text, int x) { + drawLine(text, x, fontColor.get("gui.screen")); + } + + protected final void drawSplitLine(String text, int x, int maxWidth) { + drawSplitLine(text, x, maxWidth, fontColor.get("gui.screen")); + } + + protected final void drawCenteredLine(String text, int x, int width) { + drawCenteredLine(text, x, width, fontColor.get("gui.screen")); + } + + protected final void drawCenteredLine(String text, int x, int width, int color) { + fontRendererObj.drawString(text, (int) ((guiLeft + x) * (1 / factor)) + (adjustToFactor(width) - fontRendererObj.getStringWidth(text)) / 2, + (int) ((guiTop + line) * (1 / factor)), color); + } + + protected final void drawLine(String text, int x, int color) { + fontRendererObj.drawString(text, (int) ((guiLeft + x) * (1 / factor)), (int) ((guiTop + line) * (1 / factor)), color); + } + + protected final void drawSplitLine(String text, int x, int maxWidth, int color) { + fontRendererObj.drawSplitString(text, (int) ((guiLeft + x) * (1 / factor)), (int) ((guiTop + line) * (1 / factor)), (int) (maxWidth * (1 / factor)), color); + } + + public void spinTextureIcon(int par1, int par2, IIcon par3Icon, int par4, int par5, int rotation) { + par1 += width / 2 - xSize / 2; + par2 += height / 2 - ySize / 2; + + float x = par1 + par4 / 2; + float y = par2 + par5 / 2; + GL11.glPushMatrix(); + GL11.glTranslatef(x, y, 0); + GL11.glRotatef(rotation, 0, 0, 1); + GL11.glTranslatef(-x, -y, 0); + + Tessellator tessellator = Tessellator.instance; + tessellator.startDrawingQuads(); + tessellator.addVertexWithUV(par1 + 0, par2 + par5, this.zLevel, par3Icon.getMinU(), par3Icon.getMaxV()); + tessellator.addVertexWithUV(par1 + par4, par2 + par5, this.zLevel, par3Icon.getMaxU(), par3Icon.getMaxV()); + tessellator.addVertexWithUV(par1 + par4, par2 + 0, this.zLevel, par3Icon.getMaxU(), par3Icon.getMinV()); + tessellator.addVertexWithUV(par1 + 0, par2 + 0, this.zLevel, par3Icon.getMinU(), par3Icon.getMinV()); + tessellator.draw(); + GL11.glPopMatrix(); + } + + /* CORE GUI HANDLING */ + protected int getCenteredOffset(String string) { + return getCenteredOffset(string, xSize); + } + + protected int getCenteredOffset(String string, int xWidth) { + return (xWidth - fontRendererObj.getStringWidth(string)) / 2; + } + + @Override + protected void mouseClicked(int xPos, int yPos, int mouseButton) { + super.mouseClicked(xPos, yPos, mouseButton); + + // / Handle ledger clicks + ledgerManager.handleMouseClicked(xPos, yPos, mouseButton); + widgetManager.handleMouseClicked(xPos, yPos, mouseButton); + } + + @Override + protected void mouseMovedOrUp(int mouseX, int mouseY, int eventType) { + super.mouseMovedOrUp(mouseX, mouseY, eventType); + + widgetManager.handleMouseRelease(mouseX, mouseY, eventType); + } + + @Override + protected void mouseClickMove(int mouseX, int mouseY, int mouseButton, long time) { + + widgetManager.handleMouseMove(mouseX, mouseY, mouseButton, time); + + Slot slot = getSlotAtPosition(mouseX, mouseY); + if (mouseButton == 1 && slot instanceof SlotForestry && ((SlotForestry) slot).isPhantom()) + return; + super.mouseClickMove(mouseX, mouseY, mouseButton, time); + } + + public Slot getSlotAtPosition(int par1, int par2) { + for (int k = 0; k < this.inventorySlots.inventorySlots.size(); ++k) { + Slot slot = (Slot) this.inventorySlots.inventorySlots.get(k); + + if (isMouseOverSlot(slot, par1, par2)) { + return slot; + } + } + + return null; + } + + public boolean isMouseOverSlot(Slot par1Slot, int par2, int par3) { + return this.func_146978_c(par1Slot.xDisplayPosition, par1Slot.yDisplayPosition, 16, 16, par2, par3); + } + + @SuppressWarnings("rawtypes") + protected void drawTooltip(int mouseX, int mouseY, float zLevel, List information, EnumRarity rarity) { + + if (information.size() > 0) { + this.zLevel = 0f; + itemRender.zLevel = 0f; + + int tooltipWidth = 0; + + for (int i = 0; i < information.size(); ++i) { + int textWidth = this.fontRendererObj.getStringWidth((String) information.get(i)); + + if (textWidth > tooltipWidth) + tooltipWidth = textWidth; + } + + int xPos = mouseX - this.guiLeft + 12; + int yPos = mouseY - this.guiTop - 12; + int var14 = 8; + + if (information.size() > 1) + var14 += 2 + (information.size() - 1) * 10; + + this.zLevel = zLevel; + itemRender.zLevel = zLevel; + int var15 = -267386864; + this.drawGradientRect(xPos - 3, yPos - 4, xPos + tooltipWidth + 3, yPos - 3, var15, var15); + this.drawGradientRect(xPos - 3, yPos + var14 + 3, xPos + tooltipWidth + 3, yPos + var14 + 4, var15, var15); + this.drawGradientRect(xPos - 3, yPos - 3, xPos + tooltipWidth + 3, yPos + var14 + 3, var15, var15); + this.drawGradientRect(xPos - 4, yPos - 3, xPos - 3, yPos + var14 + 3, var15, var15); + this.drawGradientRect(xPos + tooltipWidth + 3, yPos - 3, xPos + tooltipWidth + 4, yPos + var14 + 3, var15, var15); + int var16 = 1347420415; + int var17 = (var16 & 16711422) >> 1 | var16 & -16777216; + this.drawGradientRect(xPos - 3, yPos - 3 + 1, xPos - 3 + 1, yPos + var14 + 3 - 1, var16, var17); + this.drawGradientRect(xPos + tooltipWidth + 2, yPos - 3 + 1, xPos + tooltipWidth + 3, yPos + var14 + 3 - 1, var16, var17); + this.drawGradientRect(xPos - 3, yPos - 3, xPos + tooltipWidth + 3, yPos - 3 + 1, var16, var16); + this.drawGradientRect(xPos - 3, yPos + var14 + 2, xPos + tooltipWidth + 3, yPos + var14 + 3, var17, var17); + + for (int i = 0; i < information.size(); ++i) { + String line = (String) information.get(i); + + if (i == 0) + line = "\u00a7" + rarity.rarityColor.getFormattingCode() + line; + else + line = "\u00a77" + line; + + this.fontRendererObj.drawStringWithShadow(line, xPos, yPos, -1); + + if (i == 0) + yPos += 2; + + yPos += 10; + } + + this.zLevel = 0.0F; + itemRender.zLevel = 0.0F; + } + } + + public void drawToolTips(ToolTip toolTips, int mouseX, int mouseY) { + if (toolTips == null) + return; + if (toolTips.isEmpty()) + return; + + int left = this.guiLeft; + int top = this.guiTop; + int lenght = 0; + int x; + int y; + + for (ToolTipLine tip : toolTips) { + y = this.fontRendererObj.getStringWidth(tip.text); + + if (y > lenght) + lenght = y; + } + + x = mouseX - left + 12; + y = mouseY - top - 12; + int var14 = 8; + + if (toolTips.size() > 1) + var14 += 2 + (toolTips.size() - 1) * 10; + + this.zLevel = 300.0F; + itemRender.zLevel = 300.0F; + int var15 = -267386864; + this.drawGradientRect(x - 3, y - 4, x + lenght + 3, y - 3, var15, var15); + this.drawGradientRect(x - 3, y + var14 + 3, x + lenght + 3, y + var14 + 4, var15, var15); + this.drawGradientRect(x - 3, y - 3, x + lenght + 3, y + var14 + 3, var15, var15); + this.drawGradientRect(x - 4, y - 3, x - 3, y + var14 + 3, var15, var15); + this.drawGradientRect(x + lenght + 3, y - 3, x + lenght + 4, y + var14 + 3, var15, var15); + int var16 = 1347420415; + int var17 = (var16 & 16711422) >> 1 | var16 & -16777216; + this.drawGradientRect(x - 3, y - 3 + 1, x - 3 + 1, y + var14 + 3 - 1, var16, var17); + this.drawGradientRect(x + lenght + 2, y - 3 + 1, x + lenght + 3, y + var14 + 3 - 1, var16, var17); + this.drawGradientRect(x - 3, y - 3, x + lenght + 3, y - 3 + 1, var16, var16); + this.drawGradientRect(x - 3, y + var14 + 2, x + lenght + 3, y + var14 + 3, var17, var17); + + for (ToolTipLine tip : toolTips) { + String line = tip.text; + + if (tip.color == null) + line = "\u00a77" + line; + else + line = "\u00a7" + tip.color.getFormattingCode() + line; + + this.fontRendererObj.drawStringWithShadow(line, x, y, -1); + + y += 10 + tip.getSpacing(); + } + + this.zLevel = 0.0F; + itemRender.zLevel = 0.0F; + } + + @Override + protected void drawGuiContainerForegroundLayer(int mouseX, int mouseY) { + GL11.glPushAttrib(GL11.GL_ENABLE_BIT); + RenderHelper.enableGUIStandardItemLighting(); + GL11.glDisable(GL11.GL_LIGHTING); + GL11.glDisable(GL11.GL_DEPTH_TEST); + GL11.glPushMatrix(); + GL11.glColor4f(1.0F, 1.0F, 1.0F, 1.0F); + + GL11.glEnable(GL12.GL_RESCALE_NORMAL); + OpenGlHelper.setLightmapTextureCoords(OpenGlHelper.lightmapTexUnit, 240 / 1.0F, 240 / 1.0F); + GL11.glColor4f(1.0F, 1.0F, 1.0F, 1.0F); + + ledgerManager.drawTooltips(mouseX, mouseY); + + InventoryPlayer playerInv = mc.thePlayer.inventory; + + if (playerInv.getItemStack() == null) { + drawToolTips(widgetManager.widgets, mouseX, mouseY); + drawToolTips(buttonList, mouseX, mouseY); + drawToolTips(inventorySlots.inventorySlots, mouseX, mouseY); + } + + GL11.glPopMatrix(); + GL11.glPopAttrib(); + } + + private void drawToolTips(Collection objects, int mouseX, int mouseY) { + for (Object obj : objects) { + if (!(obj instanceof IToolTipProvider)) + continue; + IToolTipProvider provider = (IToolTipProvider) obj; + if (!provider.isToolTipVisible()) + continue; + ToolTip tips = provider.getToolTip(); + if (tips == null) + continue; + boolean mouseOver = provider.isMouseOver(mouseX - guiLeft, mouseY - guiTop); + tips.onTick(mouseOver); + if (mouseOver && tips.isReady()) { + tips.refresh(); + drawToolTips(tips, mouseX, mouseY); + } + } + } + + @Override + protected void drawGuiContainerBackgroundLayer(float f, int mouseX, int mouseY) { + GL11.glColor4f(1.0F, 1.0F, 1.0F, 1.0F); + bindTexture(textureFile); + int x = (width - xSize) / 2; + int y = (height - ySize) / 2; + drawTexturedModalRect(x, y, 0, 0, xSize, ySize); + + int left = this.guiLeft; + int top = this.guiTop; + + GL11.glPushAttrib(GL11.GL_ENABLE_BIT); + RenderHelper.enableGUIStandardItemLighting(); + GL11.glDisable(GL11.GL_LIGHTING); + GL11.glDisable(GL11.GL_DEPTH_TEST); + GL11.glPushMatrix(); + GL11.glTranslatef(left, top, 0.0F); + GL11.glColor4f(1.0F, 1.0F, 1.0F, 1.0F); + + GL11.glEnable(GL12.GL_RESCALE_NORMAL); + OpenGlHelper.setLightmapTextureCoords(OpenGlHelper.lightmapTexUnit, 240 / 1.0F, 240 / 1.0F); + GL11.glColor4f(1.0F, 1.0F, 1.0F, 1.0F); + + ledgerManager.drawLedgers(); + widgetManager.drawWidgets(); + + GL11.glPopMatrix(); + GL11.glPopAttrib(); + + bindTexture(textureFile); + } + + protected void bindTexture(ResourceLocation texturePath) { + GL11.glColor4f(1.0F, 1.0F, 1.0F, 1.0F); + Proxies.common.bindTexture(texturePath); + } + + public void setZLevel(float level) { + this.zLevel = level; + } + + public static RenderItem getItemRenderer() { + return itemRender; + } + + public int getSizeX() { + return xSize; + } + + public int getSizeY() { + return ySize; + } + + public int getGuiLeft() { + return guiLeft; + } + + public int getGuiTop() { + return guiTop; + } + + @Override + public void drawGradientRect(int par1, int par2, int par3, int par4, int par5, int par6) { + super.drawGradientRect(par1, par2, par3, par4, par5, par6); + } + // + // protected void drawGuiContainerForegroundLayer() { + // } + + /** + * Draws the basic background texture centered on the screen. + */ + // protected void drawBackground() { + // drawBackground((this.width - this.xSize) / 2, (this.height - this.ySize) / 2, this.xSize, this.ySize); + // } + // protected void drawBackground(int x, int y, int w, int h) { + // bindTexture(); + // this.drawTexturedModalRect(x, y, 0, 0, w, h); + // } + // protected void bindTexture() { + // bindTexture(textureFile); + // } + // + // protected void drawSlotInventory(Slot slot) { + // + // int xPos = slot.xDisplayPosition; + // int yPos = slot.yDisplayPosition; + // ItemStack slotStack = slot.getStack(); + // boolean backgroundDrawn = false; + // + // this.zLevel = 100.0F; + // itemRenderer.zLevel = 100.0F; + // + // if (slotStack == null) { + // IIcon icon = slot.getBackgroundIconIndex(); + // + // if (icon != null) { + // GL11.glDisable(GL11.GL_LIGHTING); + // GL11.glColor4f(1.0f, 1.0f, 1.0f, 1.0F); + // Proxies.common.bindTexture(SpriteSheet.ITEMS); + // this.drawTexturedModelRectFromIcon(xPos, yPos, icon, 16, 16); + // GL11.glEnable(GL11.GL_LIGHTING); + // backgroundDrawn = true; + // } + // } + // + // if (!backgroundDrawn && slotStack != null) + // drawItemStack(slotStack, xPos, yPos); + // + // this.zLevel = 0.0F; + // itemRenderer.zLevel = 0.0F; + // } + public void drawItemStack(ItemStack stack, int xPos, int yPos) { + GL11.glTranslatef(0.0F, 0.0F, 32.0F); + this.zLevel = 100.0F; + itemRender.zLevel = 100.0F; + FontRenderer font = null; + if (stack != null) + font = stack.getItem().getFontRenderer(stack); + if (font == null) + font = fontRendererObj; + itemRender.renderItemAndEffectIntoGUI(font, this.mc.getTextureManager(), stack, xPos, yPos); + itemRender.renderItemOverlayIntoGUI(font, this.mc.getTextureManager(), stack, xPos, yPos); + this.zLevel = 0.0F; + itemRender.zLevel = 0.0F; + } +} diff --git a/forestry_common/core/forestry/core/gui/GuiNaturalistInventory.java b/forestry_common/core/forestry/core/gui/GuiNaturalistInventory.java new file mode 100755 index 000000000..5cf6393c1 --- /dev/null +++ b/forestry_common/core/forestry/core/gui/GuiNaturalistInventory.java @@ -0,0 +1,255 @@ +/******************************************************************************* + * Copyright 2011-2014 by SirSengir + * + * This work is licensed under a Creative Commons Attribution-NonCommercial-NoDerivs 3.0 Unported License. + * + * To view a copy of this license, visit http://creativecommons.org/licenses/by-nc-nd/3.0/. + ******************************************************************************/ +package forestry.core.gui; + +import java.util.HashMap; + +import net.minecraft.client.gui.GuiButton; +import net.minecraft.client.renderer.RenderHelper; +import net.minecraft.entity.player.EntityPlayer; +import net.minecraft.inventory.Slot; +import net.minecraft.item.ItemStack; + +import forestry.api.apiculture.IApiaristTracker; +import forestry.api.genetics.IAlleleSpecies; +import forestry.api.genetics.IBreedingTracker; +import forestry.api.genetics.IIndividual; +import forestry.api.genetics.IMutation; +import forestry.api.genetics.ISpeciesRoot; +import forestry.core.config.Defaults; +import forestry.core.gadgets.TileForestry; +import forestry.core.genetics.EnumMutateChance; +import forestry.core.gui.buttons.GuiBetterButton; +import forestry.core.gui.buttons.StandardButtonTextureSets; +import forestry.core.network.PacketIds; +import forestry.core.network.PacketPayload; +import forestry.core.network.PacketUpdate; +import forestry.core.proxy.Proxies; +import forestry.core.utils.StringUtil; + +public class GuiNaturalistInventory extends GuiForestry { + private final ISpeciesRoot speciesRoot; + private final IBreedingTracker breedingTracker; + private final HashMap iconStacks = new HashMap(); + private final int pageCurrent, pageMax; + + public GuiNaturalistInventory(ISpeciesRoot speciesRoot, EntityPlayer player, ContainerForestry container, IPagedInventory inventory, int page, int maxPages) { + super(Defaults.TEXTURE_PATH_GUI + "/apiaristinventory.png", container, inventory); + + this.speciesRoot = speciesRoot; + + this.pageCurrent = page; + this.pageMax = maxPages; + + xSize = 196; + ySize = 202; + + for (IIndividual individual : speciesRoot.getIndividualTemplates()) { + iconStacks.put(individual.getIdent(), speciesRoot.getMemberStack(individual, 0)); + } + + breedingTracker = speciesRoot.getBreedingTracker(player.worldObj, player.getGameProfile().getId()); + } + + @Override + protected void drawGuiContainerBackgroundLayer(float f, int i, int j) { + super.drawGuiContainerBackgroundLayer(f, i, j); + String header = StringUtil.localize("gui.page") + " " + (pageCurrent + 1) + "/" + pageMax; + fontRendererObj.drawString(header, guiLeft + 95 + getCenteredOffset(header, 98), guiTop + 10, fontColor.get("gui.title")); + + IIndividual individual = getIndividualAtPosition(i, j); + if (individual == null) + displayBreedingStatistics(10); + + if (individual != null) { + RenderHelper.enableGUIStandardItemLighting(); + startPage(); + + displaySpeciesInformation(true, individual.getGenome().getPrimary(), iconStacks.get(individual.getIdent()), 10); + if (!individual.isPureBred(0)) + displaySpeciesInformation(individual.isAnalyzed(), individual.getGenome().getSecondary(), iconStacks.get(individual.getGenome().getSecondary().getUID()), + 10); + + endPage(); + } + } + + @SuppressWarnings("unchecked") + @Override + public void initGui() { + super.initGui(); + + buttonList.add(new GuiBetterButton(1, guiLeft + 99, guiTop + 7, StandardButtonTextureSets.LEFT_BUTTON_SMALL)); + buttonList.add(new GuiBetterButton(2, guiLeft + 180, guiTop + 7, StandardButtonTextureSets.RIGHT_BUTTON_SMALL)); + } + + private void flipPage(int page) { + PacketPayload payload = new PacketPayload(1, 0, 0); + payload.intPayload[0] = page; + PacketUpdate packet = new PacketUpdate(PacketIds.GUI_SELECTION_CHANGE, payload); + Proxies.net.sendToServer(packet); + } + + @Override + protected void actionPerformed(GuiButton guibutton) { + super.actionPerformed(guibutton); + + if (guibutton.id == 1 && pageCurrent > 0) + flipPage(pageCurrent - 1); + else if (guibutton.id == 2 && pageCurrent < pageMax - 1) + flipPage(pageCurrent + 1); + } + + private IIndividual getIndividualAtPosition(int x, int y) { + Slot slot = getSlotAtPosition(x, y); + if (slot == null) + return null; + + if (!slot.getHasStack()) + return null; + + if (!slot.getStack().hasTagCompound()) + return null; + + if (!speciesRoot.isMember(slot.getStack())) + return null; + + return speciesRoot.getMember(slot.getStack()); + } + + private void displayBreedingStatistics(int x) { + + startPage(); + + drawLine(StringUtil.localize("gui.speciescount") + ": " + breedingTracker.getSpeciesBred() + "/" + speciesRoot.getSpeciesCount(), x); + newLine(); + newLine(); + + if (breedingTracker instanceof IApiaristTracker) { + IApiaristTracker tracker = (IApiaristTracker) breedingTracker; + drawLine(StringUtil.localize("gui.queens") + ": " + tracker.getQueenCount(), x); + newLine(); + + drawLine(StringUtil.localize("gui.princesses") + ": " + tracker.getPrincessCount(), x); + newLine(); + + drawLine(StringUtil.localize("gui.drones") + ": " + tracker.getDroneCount(), x); + newLine(); + } + + endPage(); + } + + private void displaySpeciesInformation(boolean analyzed, IAlleleSpecies species, ItemStack iconStack, int x) { + + if (!analyzed) { + drawLine(StringUtil.localize("gui.unknown"), x); + return; + } + + drawLine(species.getName(), x); + RenderHelper.enableGUIStandardItemLighting(); + drawItemStack(iconStack, adjustToFactor(guiLeft + x + 69), adjustToFactor(guiTop + getLineY() - 2)); + RenderHelper.disableStandardItemLighting(); + + newLine(); + + // Viable Combinations + int columnWidth = 16; + int column = 10; + + for (IMutation combination : speciesRoot.getCombinations(species)) { + if (combination.isSecret()) + continue; + + if (breedingTracker.isDiscovered(combination)) + drawMutationIcon(combination, species, column); + else + drawUnknownIcon(combination, column); + + column += columnWidth; + if (column > 75) { + column = 10; + newLine(18); + } + } + + newLine(); + newLine(); + } + + private void drawMutationIcon(IMutation combination, IAlleleSpecies species, int x) { + + RenderHelper.enableGUIStandardItemLighting(); + drawItemStack(iconStacks.get(combination.getPartner(species).getUID()), adjustToFactor(guiLeft + x), + adjustToFactor(guiTop + getLineY())); + RenderHelper.disableStandardItemLighting(); + + int line = 48; + int column = 0; + EnumMutateChance chance = EnumMutateChance.rateChance(combination.getBaseChance()); + if (chance == EnumMutateChance.HIGHEST) { + line += 16; + column = 228; + } else if (chance == EnumMutateChance.HIGHER) { + line += 16; + column = 212; + } else if (chance == EnumMutateChance.HIGH) { + line += 16; + column = 196; + } else if (chance == EnumMutateChance.NORMAL) { + line += 0; + column = 228; + } else if (chance == EnumMutateChance.LOW) { + line += 0; + column = 212; + } else { + line += 0; + column = 196; + } + + Proxies.common.bindTexture(textureFile); + drawTexturedModalRect(adjustToFactor(guiLeft + x), adjustToFactor(guiTop + getLineY()), column, line, 16, 16); + + } + + private void drawUnknownIcon(IMutation mutation, int x) { + + float chance = mutation.getBaseChance(); + + int line = 0; + int column = 0; + if (chance >= 20) { + line = 16; + column = 228; + } else if (chance >= 15) { + line = 16; + column = 212; + } else if (chance >= 12) { + line = 16; + column = 196; + } else if (chance >= 10) { + line = 0; + column = 228; + } else if (chance >= 5) { + line = 0; + column = 212; + } else { + line = 0; + column = 196; + } + + Proxies.common.bindTexture(textureFile); + drawTexturedModalRect(adjustToFactor(guiLeft + x), adjustToFactor(guiTop + getLineY()), column, line, 16, 16); + } + + @Override + protected boolean checkHotbarKeys(int key) { + return false; + } +} diff --git a/forestry_common/core/forestry/core/gui/GuiTextBox.java b/forestry_common/core/forestry/core/gui/GuiTextBox.java new file mode 100755 index 000000000..da26bc4de --- /dev/null +++ b/forestry_common/core/forestry/core/gui/GuiTextBox.java @@ -0,0 +1,107 @@ +/******************************************************************************* + * Copyright 2011-2014 by SirSengir + * + * This work is licensed under a Creative Commons Attribution-NonCommercial-NoDerivs 3.0 Unported License. + * + * To view a copy of this license, visit http://creativecommons.org/licenses/by-nc-nd/3.0/. + ******************************************************************************/ +package forestry.core.gui; + +import java.util.Iterator; +import java.util.List; + +import net.minecraft.client.gui.FontRenderer; +import net.minecraft.client.gui.GuiTextField; + +public class GuiTextBox extends GuiTextField { + + private final FontRenderer fontRendererObj; + + private final int startX, startY, width, height; + private final int enabledColor = 14737632; + private final int disabledColor = 7368816; + + private int lineScroll = 0; + private int maxLines = 0; + + public GuiTextBox(FontRenderer fontRendererObj, int startX, int startY, int width, int height) { + super(fontRendererObj, startX, startY, width, height); + this.fontRendererObj = fontRendererObj; + this.startX = startX; + this.startY = startY; + this.width = width; + this.height = height; + } + + private int getLineScrollOffset() { + return 0; + } + + public void advanceLine() { + if(lineScroll < maxLines - 1) + lineScroll++; + } + + public void regressLine() { + if(lineScroll > 0) + lineScroll--; + } + + public boolean moreLinesAllowed() { + return fontRendererObj.listFormattedStringToWidth(getCursoredText(), width).size() * fontRendererObj.FONT_HEIGHT < height; + } + + private String getCursoredText() { + if(!isFocused()) + return getText(); + + int cursorPos = getCursorPosition() - getLineScrollOffset(); + String text = getText(); + if(cursorPos < 0) + return text; + if(cursorPos >= text.length()) + return text + "_"; + return text.substring(0, cursorPos) + "_" + text.substring(cursorPos); + } + + @SuppressWarnings("unchecked") + private void drawScrolledSplitString(String text, int startX, int startY, int width, int textColour) { + List list = fontRendererObj.listFormattedStringToWidth(text, width); + maxLines = list.size(); + + int count = 0; + int lineY = startY; + + for (Iterator iterator = list.iterator(); iterator.hasNext();) { + if(count < lineScroll) { + count++; + continue; + } + else if(lineY + fontRendererObj.FONT_HEIGHT - startY > height) + break; + + String line = iterator.next(); + fontRendererObj.drawString(line, startX, lineY, textColour); + lineY += fontRendererObj.FONT_HEIGHT; + + count++; + } + + } + + @Override + public void drawTextBox() { + if(!getVisible()) + return; + + if(getEnableBackgroundDrawing()) { + drawRect(startX - 1, startY - 1, startX + this.width + 1, startY + this.height + 1, -6250336); + drawRect(startX, startY, startX + this.width, startY + this.height, -16777216); + } + + int textColour = isFocused() ? this.enabledColor : this.disabledColor; + + drawScrolledSplitString(getCursoredText(), startX + 2, startY + 2, width - 4, textColour); + } + +} diff --git a/forestry_common/core/forestry/core/gui/HintLedger.java b/forestry_common/core/forestry/core/gui/HintLedger.java new file mode 100755 index 000000000..c997858da --- /dev/null +++ b/forestry_common/core/forestry/core/gui/HintLedger.java @@ -0,0 +1,53 @@ +/******************************************************************************* + * Copyright 2011-2014 by SirSengir + * + * This work is licensed under a Creative Commons Attribution-NonCommercial-NoDerivs 3.0 Unported License. + * + * To view a copy of this license, visit http://creativecommons.org/licenses/by-nc-nd/3.0/. + ******************************************************************************/ +package forestry.core.gui; + +import java.util.Random; + +import forestry.core.interfaces.IHintSource; +import forestry.core.render.TextureManager; +import forestry.core.utils.StringUtil; + +public class HintLedger extends Ledger { + + int position; + String[] hints; + + public HintLedger(LedgerManager manager, IHintSource tile) { + super(manager); + this.hints = tile.getHints(); + maxHeight = 96; + position = new Random().nextInt(hints.length); + overlayColor = manager.gui.fontColor.get("ledger.hint.background"); + } + + @Override + public void draw(int x, int y) { + + // Draw background + drawBackground(x, y); + + // Draw icon + drawIcon(TextureManager.getInstance().getDefault("misc/hint"), x + 3, y + 4); + + if (!isFullyOpened()) + return; + + manager.minecraft.fontRenderer.drawStringWithShadow(StringUtil.localize("gui.didyouknow") + "?", x + 22, y + 8, + manager.gui.fontColor.get("ledger.hint.header")); + manager.minecraft.fontRenderer.drawSplitString(StringUtil.localize("hints." + hints[position] + ".desc"), x + 22, y + 20, maxWidth - 28, + manager.gui.fontColor.get("ledger.hint.text")); + + } + + @Override + public String getTooltip() { + return StringUtil.localize("hints." + hints[position] + ".tag"); + } + +} diff --git a/forestry_common/core/forestry/core/gui/IGuiSelectable.java b/forestry_common/core/forestry/core/gui/IGuiSelectable.java new file mode 100755 index 000000000..a1d72f470 --- /dev/null +++ b/forestry_common/core/forestry/core/gui/IGuiSelectable.java @@ -0,0 +1,18 @@ +/******************************************************************************* + * Copyright 2011-2014 by SirSengir + * + * This work is licensed under a Creative Commons Attribution-NonCommercial-NoDerivs 3.0 Unported License. + * + * To view a copy of this license, visit http://creativecommons.org/licenses/by-nc-nd/3.0/. + ******************************************************************************/ +package forestry.core.gui; + +import net.minecraft.entity.player.EntityPlayer; + +import forestry.core.network.PacketUpdate; + +public interface IGuiSelectable { + void handleSelectionChange(EntityPlayer player, PacketUpdate packet); + + void setSelection(PacketUpdate packet); +} diff --git a/forestry_common/core/forestry/core/gui/IPagedInventory.java b/forestry_common/core/forestry/core/gui/IPagedInventory.java new file mode 100755 index 000000000..ad7b0984e --- /dev/null +++ b/forestry_common/core/forestry/core/gui/IPagedInventory.java @@ -0,0 +1,20 @@ +/******************************************************************************* + * Copyright 2011-2014 by SirSengir + * + * This work is licensed under a Creative Commons Attribution-NonCommercial-NoDerivs 3.0 Unported License. + * + * To view a copy of this license, visit http://creativecommons.org/licenses/by-nc-nd/3.0/. + ******************************************************************************/ +package forestry.core.gui; + +import net.minecraft.entity.player.EntityPlayer; +import net.minecraft.inventory.IInventory; + +/** + * + * @author CovertJaguar + */ +public interface IPagedInventory extends IInventory { + + void flipPage(EntityPlayer player, int page); +} diff --git a/forestry_common/core/forestry/core/gui/Ledger.java b/forestry_common/core/forestry/core/gui/Ledger.java new file mode 100755 index 000000000..360ac50f9 --- /dev/null +++ b/forestry_common/core/forestry/core/gui/Ledger.java @@ -0,0 +1,146 @@ +/******************************************************************************* + * Copyright 2011-2014 by SirSengir + * + * This work is licensed under a Creative Commons Attribution-NonCommercial-NoDerivs 3.0 Unported License. + * + * To view a copy of this license, visit http://creativecommons.org/licenses/by-nc-nd/3.0/. + ******************************************************************************/ +package forestry.core.gui; + +import net.minecraft.util.IIcon; +import net.minecraft.util.ResourceLocation; + +import org.lwjgl.opengl.GL11; + +import forestry.core.config.Defaults; +import forestry.core.config.SessionVars; +import forestry.core.proxy.Proxies; +import forestry.core.render.SpriteSheet; +import forestry.core.utils.ForestryResource; + +/** + * Side ledger for guis + */ +public abstract class Ledger { + + private static final int OPEN_SPEED = 8; + private static final ResourceLocation ledgerTexture = new ForestryResource(Defaults.TEXTURE_PATH_GUI + "/ledger.png"); + + protected LedgerManager manager; + + private boolean open; + + protected int overlayColor = 0xffffff; + + public int currentShiftX = 0; + public int currentShiftY = 0; + + protected int limitWidth = 128; + protected int maxWidth = 124; + protected int minWidth = 24; + protected int currentWidth = minWidth; + + protected int maxHeight = 24; + protected int minHeight = 24; + protected int currentHeight = minHeight; + + public Ledger(LedgerManager manager) { + this.manager = manager; + } + + public void update() { + // Width + if (open && currentWidth < maxWidth) + currentWidth += OPEN_SPEED; + else if (!open && currentWidth > minWidth) { + currentWidth -= OPEN_SPEED; + currentWidth = currentWidth > minWidth ? currentWidth : minWidth; + } + + // Height + if (open && currentHeight < maxHeight) + currentHeight += OPEN_SPEED; + else if (!open && currentHeight > minHeight) { + currentHeight -= OPEN_SPEED; + currentHeight = currentHeight > minHeight ? currentHeight : minHeight; + } + } + + public int getHeight() { + return currentHeight; + } + + public abstract void draw(int x, int y); + public abstract String getTooltip(); + + public boolean handleMouseClicked(int x, int y, int mouseButton) { + return false; + } + + public boolean intersectsWith(int mouseX, int mouseY, int shiftX, int shiftY) { + + if (mouseX >= shiftX && mouseX <= shiftX + currentWidth && mouseY >= shiftY && mouseY <= shiftY + getHeight()) + return true; + + return false; + } + + public void setFullyOpen() { + open = true; + currentWidth = maxWidth; + currentHeight = maxHeight; + } + + public void toggleOpen() { + if (open) { + open = false; + SessionVars.setOpenedLedger(null); + } else { + open = true; + SessionVars.setOpenedLedger(this.getClass()); + } + } + + public boolean isVisible() { + return true; + } + + public boolean isOpen() { + return this.open; + } + + protected boolean isFullyOpened() { + return currentWidth >= maxWidth; + } + + protected void drawBackground(int x, int y) { + + float colorR = (overlayColor >> 16 & 255) / 255.0F; + float colorG = (overlayColor >> 8 & 255) / 255.0F; + float colorB = (overlayColor & 255) / 255.0F; + + GL11.glColor4f(colorR, colorG, colorB, 1.0F); + + Proxies.common.bindTexture(ledgerTexture); + + manager.gui.drawTexturedModalRect(x, y, 0, 256 - currentHeight, 4, currentHeight); + manager.gui.drawTexturedModalRect(x + 4, y, 256 - currentWidth + 4, 0, currentWidth - 4, 4); + manager.gui.drawTexturedModalRect(x, y, 0, 0, 4, 4); + + manager.gui.drawTexturedModalRect(x + 4, y + 4, 256 - currentWidth + 4, 256 - currentHeight + 4, currentWidth - 4, currentHeight - 4); + + GL11.glColor4f(1.0f, 1.0f, 1.0f, 1.0F); + } + + protected void drawIcon(IIcon icon, int x, int y) { + + if (icon != null) { + GL11.glDisable(GL11.GL_LIGHTING); + GL11.glColor4f(1.0f, 1.0f, 1.0f, 1.0F); + Proxies.common.bindTexture(SpriteSheet.ITEMS); + manager.gui.drawTexturedModelRectFromIcon(x, y, icon, 16, 16); + GL11.glEnable(GL11.GL_LIGHTING); + } + + } +} diff --git a/forestry_common/core/forestry/core/gui/LedgerManager.java b/forestry_common/core/forestry/core/gui/LedgerManager.java new file mode 100755 index 000000000..6bf09138d --- /dev/null +++ b/forestry_common/core/forestry/core/gui/LedgerManager.java @@ -0,0 +1,117 @@ +/******************************************************************************* + * Copyright 2011-2014 by SirSengir + * + * This work is licensed under a Creative Commons Attribution-NonCommercial-NoDerivs 3.0 Unported License. + * + * To view a copy of this license, visit http://creativecommons.org/licenses/by-nc-nd/3.0/. + ******************************************************************************/ +package forestry.core.gui; + +import java.util.ArrayList; + +import net.minecraft.client.Minecraft; + +import org.lwjgl.opengl.GL11; + +import forestry.core.config.SessionVars; +import forestry.core.gadgets.TileForestry; +import forestry.core.proxy.Proxies; + +public class LedgerManager { + + public GuiForestry gui; + public Minecraft minecraft; + + protected ArrayList ledgers = new ArrayList(); + + public LedgerManager(GuiForestry gui) { + this.gui = gui; + this.minecraft = Proxies.common.getClientInstance(); + } + + public void add(Ledger ledger) { + this.ledgers.add(ledger); + if (SessionVars.getOpenedLedger() != null && ledger.getClass().equals(SessionVars.getOpenedLedger())) + ledger.setFullyOpen(); + } + + /** + * Inserts a ledger into the next-to-last position. + * + * @param ledger + */ + public void insert(Ledger ledger) { + this.ledgers.add(ledgers.size() - 1, ledger); + } + + protected Ledger getAtPosition(int mX, int mY) { + + int xShift = ((gui.width - gui.getSizeX()) / 2) + gui.getSizeX(); + int yShift = ((gui.height - gui.getSizeY()) / 2) + 8; + + for (int i = 0; i < ledgers.size(); i++) { + Ledger ledger = ledgers.get(i); + if (!ledger.isVisible()) + continue; + + ledger.currentShiftX = xShift; + ledger.currentShiftY = yShift; + if (ledger.intersectsWith(mX, mY, xShift, yShift)) + return ledger; + + yShift += ledger.getHeight(); + } + + return null; + } + + protected void drawLedgers() { + + int xPos = 8; + for (Ledger ledger : ledgers) { + + ledger.update(); + if (!ledger.isVisible()) + continue; + + GL11.glColor4f(1.0F, 1.0F, 1.0F, 1.0F); + ledger.draw(gui.getSizeX(), xPos); + xPos += ledger.getHeight(); + } + } + + protected void drawTooltips(int mouseX, int mouseY) { + + Ledger ledger = getAtPosition(mouseX, mouseY); + if (ledger != null) { + int startX = mouseX - ((gui.width - gui.getSizeX()) / 2) + 12; + int startY = mouseY - ((gui.height - gui.getSizeY()) / 2) - 12; + + String tooltip = ledger.getTooltip(); + int textWidth = minecraft.fontRenderer.getStringWidth(tooltip); + gui.drawGradientRect(startX - 3, startY - 3, startX + textWidth + 3, startY + 8 + 3, 0xc0000000, 0xc0000000); + minecraft.fontRenderer.drawStringWithShadow(tooltip, startX, startY, -1); + } + + } + + public void handleMouseClicked(int x, int y, int mouseButton) { + + if (mouseButton == 0) { + + Ledger ledger = this.getAtPosition(x, y); + + // Default action only if the mouse click was not handled by the + // ledger itself. + if (ledger != null && !ledger.handleMouseClicked(x, y, mouseButton)) { + + for (Ledger other : ledgers) + if (other != ledger && other.isOpen()) + other.toggleOpen(); + ledger.toggleOpen(); + } + } + + } + +} diff --git a/forestry_common/core/forestry/core/gui/OwnerLedger.java b/forestry_common/core/forestry/core/gui/OwnerLedger.java new file mode 100755 index 000000000..cf9b78106 --- /dev/null +++ b/forestry_common/core/forestry/core/gui/OwnerLedger.java @@ -0,0 +1,115 @@ +/******************************************************************************* + * Copyright 2011-2014 by SirSengir + * + * This work is licensed under a Creative Commons Attribution-NonCommercial-NoDerivs 3.0 Unported License. + * + * To view a copy of this license, visit http://creativecommons.org/licenses/by-nc-nd/3.0/. + ******************************************************************************/ +package forestry.core.gui; + +import java.util.Locale; + +import net.minecraft.tileentity.TileEntity; +import net.minecraft.util.IIcon; + +import forestry.core.interfaces.IOwnable; +import forestry.core.network.PacketCoordinates; +import forestry.core.network.PacketIds; +import forestry.core.proxy.Proxies; +import forestry.core.render.TextureManager; +import forestry.core.utils.EnumAccess; +import forestry.core.utils.StringUtil; + +/** + * Ledger displaying ownership information + */ +public class OwnerLedger extends Ledger { + + IOwnable tile; + + public OwnerLedger(LedgerManager manager, IOwnable tile) { + super(manager); + this.tile = tile; + } + + public boolean isAccessButton(int mouseX, int mouseY) { + + int shiftX = currentShiftX; + int shiftY = currentShiftY + 44; + + if (mouseX >= shiftX && mouseX <= currentShiftX + currentWidth && mouseY >= shiftY && mouseY <= shiftY + 12) + return true; + return false; + } + + public boolean isOwnerChangeButton(int mouseX, int mouseY) { + return false; + } + + @Override + public void draw(int x, int y) { + + // Update state + boolean playerIsOwner = tile.isOwner(manager.minecraft.thePlayer); + EnumAccess access = tile.getAccess(); + + if (playerIsOwner) + maxHeight = 60; + else + maxHeight = 36; + + // Draw background + drawBackground(x, y); + + // Draw icon + IIcon accessIcon = TextureManager.getInstance().getDefault("misc/access." + access.toString().toLowerCase(Locale.ENGLISH)); + drawIcon(accessIcon, x + 3, y + 4); + + // Draw description + if (!isFullyOpened()) + return; + + manager.minecraft.fontRenderer.drawStringWithShadow(StringUtil.localize("gui.owner"), x + 22, y + 8, manager.gui.fontColor.get("ledger.owner.header")); + + String owner; + if ((owner = tile.getOwnerName()) == null) + owner = StringUtil.localize("gui.derelict"); + + manager.minecraft.fontRenderer.drawString(owner, x + 22, y + 20, manager.gui.fontColor.get("ledger.owner.text")); + + if (!playerIsOwner) + return; + + manager.minecraft.fontRenderer.drawStringWithShadow(StringUtil.localize("gui.access") + ":", x + 22, y + 32, + manager.gui.fontColor.get("ledger.owner.subheader")); + // Access rules + drawIcon(accessIcon, x + 20, y + 40); + manager.minecraft.fontRenderer.drawString(StringUtil.localize(access.getName()), x + 38, y + 44, manager.gui.fontColor.get("ledger.owner.text")); + + } + + @Override + public String getTooltip() { + if (tile.getOwnerName() != null) + return StringUtil.localize("gui.owner") + ": " + tile.getOwnerName(); + else + return StringUtil.localize("gui.derelict"); + } + + @Override + public boolean handleMouseClicked(int x, int y, int mouseButton) { + + if (isAccessButton(x, y)) { + if (!Proxies.common.isSimulating(((TileEntity) tile).getWorldObj())) { + TileEntity te = (TileEntity) tile; + Proxies.net.sendToServer(new PacketCoordinates(PacketIds.ACCESS_SWITCH, te.xCoord, te.yCoord, te.zCoord)); + } + + tile.switchAccessRule(manager.minecraft.thePlayer); + return true; + } + + return false; + } + +} diff --git a/forestry_common/core/forestry/core/gui/PlainLedger.java b/forestry_common/core/forestry/core/gui/PlainLedger.java new file mode 100755 index 000000000..f8d28f9f7 --- /dev/null +++ b/forestry_common/core/forestry/core/gui/PlainLedger.java @@ -0,0 +1,48 @@ +/******************************************************************************* + * Copyright 2011-2014 by SirSengir + * + * This work is licensed under a Creative Commons Attribution-NonCommercial-NoDerivs 3.0 Unported License. + * + * To view a copy of this license, visit http://creativecommons.org/licenses/by-nc-nd/3.0/. + ******************************************************************************/ +package forestry.core.gui; + +import net.minecraft.util.IIcon; + +/** + * A simple ledger displaying an icon and one-line description. + */ +public class PlainLedger extends Ledger { + + private IIcon icon; + private String text; + + public PlainLedger(LedgerManager manager, IIcon icon, String text) { + super(manager); + this.icon = icon; + this.text = text; + } + + @Override + public void draw(int x, int y) { + + // Correct maximum width + int textWidth = manager.minecraft.fontRenderer.getStringWidth(getTooltip()); + this.maxWidth = textWidth + 24 + 4; + + // Draw background + drawBackground(x, y); + + // Draw icon + drawIcon(icon, x + 3, y + 4); + + // Draw description + if (isFullyOpened()) + manager.minecraft.fontRenderer.drawString(getTooltip(), x + 22, y + 8, 0x000000); + } + + @Override + public String getTooltip() { + return text; + } +} diff --git a/forestry_common/core/forestry/core/gui/PowerLedger.java b/forestry_common/core/forestry/core/gui/PowerLedger.java new file mode 100755 index 000000000..e9a237287 --- /dev/null +++ b/forestry_common/core/forestry/core/gui/PowerLedger.java @@ -0,0 +1,57 @@ +/******************************************************************************* + * Copyright 2011-2014 by SirSengir + * + * This work is licensed under a Creative Commons Attribution-NonCommercial-NoDerivs 3.0 Unported License. + * + * To view a copy of this license, visit http://creativecommons.org/licenses/by-nc-nd/3.0/. + ******************************************************************************/ +package forestry.core.gui; + +import buildcraft.api.power.PowerHandler; + +import forestry.core.interfaces.IPowerHandler; +import forestry.core.render.TextureManager; +import forestry.core.utils.StringUtil; + +public class PowerLedger extends Ledger { + + IPowerHandler tile; + + public PowerLedger(LedgerManager manager, IPowerHandler tile) { + super(manager); + this.tile = tile; + maxHeight = 94; + overlayColor = manager.gui.fontColor.get("ledger.power.background"); + } + + @Override + public void draw(int x, int y) { + // Draw background + drawBackground(x, y); + + // Draw icon + drawIcon(TextureManager.getInstance().getDefault("misc/energy"), x + 3, y + 4); + + if (!isFullyOpened()) + return; + + PowerHandler handler = tile.getPowerHandler(); + manager.minecraft.fontRenderer.drawStringWithShadow(StringUtil.localize("gui.energy"), x + 22, y + 8, manager.gui.fontColor.get("ledger.power.header")); + manager.minecraft.fontRenderer.drawStringWithShadow(StringUtil.localize("gui.stored") + ":", x + 22, y + 20, + manager.gui.fontColor.get("ledger.power.subheader")); + manager.minecraft.fontRenderer.drawString(handler.getEnergyStored() + " MJ", x + 22, y + 32, manager.gui.fontColor.get("ledger.power.text")); + manager.minecraft.fontRenderer.drawStringWithShadow(StringUtil.localize("gui.maxenergy") + ":", x + 22, y + 44, + manager.gui.fontColor.get("ledger.power.subheader")); + manager.minecraft.fontRenderer.drawString(handler.getMaxEnergyStored() + " MJ", x + 22, y + 56, manager.gui.fontColor.get("ledger.power.text")); + manager.minecraft.fontRenderer.drawStringWithShadow(StringUtil.localize("gui.maxenergyreceive") + ":", x + 22, y + 68, + manager.gui.fontColor.get("ledger.power.subheader")); + manager.minecraft.fontRenderer.drawString(handler.getMaxEnergyReceived() + " MJ", x + 22, y + 80, manager.gui.fontColor.get("ledger.power.text")); + + } + + @Override + public String getTooltip() { + return tile.getPowerHandler().getEnergyStored() + " MJ"; + } + +} diff --git a/forestry_common/core/forestry/core/gui/WidgetManager.java b/forestry_common/core/forestry/core/gui/WidgetManager.java new file mode 100755 index 000000000..6f2d0144b --- /dev/null +++ b/forestry_common/core/forestry/core/gui/WidgetManager.java @@ -0,0 +1,81 @@ +/******************************************************************************* + * Copyright 2011-2014 by SirSengir + * + * This work is licensed under a Creative Commons Attribution-NonCommercial-NoDerivs 3.0 Unported License. + * + * To view a copy of this license, visit http://creativecommons.org/licenses/by-nc-nd/3.0/. + ******************************************************************************/ +package forestry.core.gui; + +import java.util.ArrayList; + +import net.minecraft.client.Minecraft; + +import org.lwjgl.opengl.GL11; + +import forestry.core.gadgets.TileForestry; +import forestry.core.gui.widgets.Widget; +import forestry.core.proxy.Proxies; + +public class WidgetManager { + + public GuiForestry gui; + public Minecraft minecraft; + protected ArrayList widgets = new ArrayList(); + + public WidgetManager(GuiForestry gui) { + this.gui = gui; + this.minecraft = Proxies.common.getClientInstance(); + } + + public void add(Widget slot) { + this.widgets.add(slot); + } + + public void remove(Widget slot) { + this.widgets.remove(slot); + } + + public void clear() { + this.widgets.clear(); + } + + protected Widget getAtPosition(int mX, int mY) { + for (Widget slot : widgets) { + if (slot.isMouseOver(mX, mY)) + return slot; + } + + return null; + } + + public void drawWidgets() { + gui.setZLevel(100.0F); + GuiForestry.getItemRenderer().zLevel = 100.0F; + for (Widget slot : widgets) { + GL11.glColor4f(1.0F, 1.0F, 1.0F, 1.0F); + slot.draw(0, 0); + } + gui.setZLevel(0.0F); + GuiForestry.getItemRenderer().zLevel = 0.0F; + + } + + public void handleMouseClicked(int mouseX, int mouseY, int mouseButton) { + Widget slot = getAtPosition(mouseX - gui.getGuiLeft(), mouseY - gui.getGuiTop()); + if (slot != null) + slot.handleMouseClick(mouseX, mouseY, mouseButton); + } + + public void handleMouseRelease(int mouseX, int mouseY, int eventType) { + for (Widget slot : widgets) { + slot.handleMouseRelease(mouseX, mouseY, eventType); + } + } + + public void handleMouseMove(int mouseX, int mouseY, int mouseButton, long time) { + for (Widget slot : widgets) { + slot.handleMouseMove(mouseX, mouseY, mouseButton, time); + } + } +} diff --git a/forestry_common/core/forestry/core/gui/buttons/ButtonTextureSet.java b/forestry_common/core/forestry/core/gui/buttons/ButtonTextureSet.java new file mode 100755 index 000000000..485c12ea8 --- /dev/null +++ b/forestry_common/core/forestry/core/gui/buttons/ButtonTextureSet.java @@ -0,0 +1,45 @@ +/******************************************************************************* + * Copyright 2011-2014 by SirSengir + * + * This work is licensed under a Creative Commons Attribution-NonCommercial-NoDerivs 3.0 Unported License. + * + * To view a copy of this license, visit http://creativecommons.org/licenses/by-nc-nd/3.0/. + ******************************************************************************/ +package forestry.core.gui.buttons; + +/** + * + * @author CovertJaguar + */ +public class ButtonTextureSet implements IButtonTextureSet { + + private final int x, y, height, width; + + public ButtonTextureSet(int x, int y, int height, int width) { + this.x = x; + this.y = y; + this.height = height; + this.width = width; + } + + @Override + public int getX() { + return x; + } + + @Override + public int getY() { + return y; + } + + @Override + public int getHeight() { + return height; + } + + @Override + public int getWidth() { + return width; + } + +} diff --git a/forestry_common/core/forestry/core/gui/buttons/GuiBetterButton.java b/forestry_common/core/forestry/core/gui/buttons/GuiBetterButton.java new file mode 100755 index 000000000..5788d34e9 --- /dev/null +++ b/forestry_common/core/forestry/core/gui/buttons/GuiBetterButton.java @@ -0,0 +1,140 @@ +/******************************************************************************* + * Copyright 2011-2014 by SirSengir + * + * This work is licensed under a Creative Commons Attribution-NonCommercial-NoDerivs 3.0 Unported License. + * + * To view a copy of this license, visit http://creativecommons.org/licenses/by-nc-nd/3.0/. + ******************************************************************************/ +package forestry.core.gui.buttons; + +import net.minecraft.client.Minecraft; +import net.minecraft.client.gui.FontRenderer; +import net.minecraft.client.gui.GuiButton; +import net.minecraft.util.ResourceLocation; + +import cpw.mods.fml.relauncher.Side; +import cpw.mods.fml.relauncher.SideOnly; + +import org.lwjgl.opengl.GL11; + +import forestry.core.config.Defaults; +import forestry.core.gui.tooltips.IToolTipProvider; +import forestry.core.gui.tooltips.ToolTip; + +@SideOnly(Side.CLIENT) +public class GuiBetterButton extends GuiButton implements IToolTipProvider{ + + private static final ResourceLocation TEXTURE = new ResourceLocation("forestry", Defaults.TEXTURE_PATH_GUI + "/buttons.png"); + protected IButtonTextureSet texture; + private ToolTip toolTip; + private boolean useTexWidth = false; + + public GuiBetterButton(int id, int x, int y, String label) { + this(id, x, y, 200, StandardButtonTextureSets.LARGE_BUTTON, label); + } + + public GuiBetterButton(int id, int x, int y, int width, String label) { + this(id, x, y, width, StandardButtonTextureSets.LARGE_BUTTON, label); + } + + public GuiBetterButton(int id, int x, int y, int width, IButtonTextureSet texture, String label) { + super(id, x, y, width, texture.getHeight(), label); + this.texture = texture; + } + + public GuiBetterButton(int id, int x, int y, IButtonTextureSet texture) { + super(id, x, y, texture.getWidth(), texture.getHeight(), ""); + this.texture = texture; + useTexWidth = true; + } + + public GuiBetterButton setTexture(IButtonTextureSet texture) { + this.texture = texture; + width = texture.getWidth(); + height = texture.getHeight(); + return this; + } + + public GuiBetterButton setUseTextureWidth() { + useTexWidth = true; + return this; + } + + public GuiBetterButton setWidth(int width) { + this.width = width; + useTexWidth = false; + return this; + } + + public GuiBetterButton setLabel(String label) { + this.displayString = label; + return this; + } + + public int getWidth() { + return width; + } + + public int getHeight() { + return texture.getHeight(); + } + + public int getTextColor(boolean mouseOver) { + if (!enabled) + return 0xffa0a0a0; + else if (mouseOver) + return 0xffffa0; + else + return 0xe0e0e0; + } + + public boolean isMouseOverButton(int mouseX, int mouseY) { + return mouseX >= xPosition && mouseY >= yPosition && mouseX < xPosition + getWidth() && mouseY < yPosition + getHeight(); + } + + protected void bindButtonTextures(Minecraft minecraft) { + minecraft.renderEngine.bindTexture(TEXTURE); + } + + @Override + public void drawButton(Minecraft minecraft, int mouseX, int mouseY) { + if (!visible) + return; + FontRenderer fontrenderer = minecraft.fontRenderer; + bindButtonTextures(minecraft); + GL11.glColor4f(1.0F, 1.0F, 1.0F, 1.0F); + int xOffset = texture.getX(); + int yOffset = texture.getY(); + int h = texture.getHeight(); + int w = texture.getWidth(); + boolean mouseOver = isMouseOverButton(mouseX, mouseY); + int hoverState = getHoverState(mouseOver); + if (useTexWidth) { + drawTexturedModalRect(xPosition, yPosition, xOffset, yOffset + hoverState * h, w, h); + } else { + drawTexturedModalRect(xPosition, yPosition, xOffset, yOffset + hoverState * h, width / 2, h); + drawTexturedModalRect(xPosition + width / 2, yPosition, xOffset + w - width / 2, yOffset + hoverState * h, width / 2, h); + } + mouseDragged(minecraft, mouseX, mouseY); + drawCenteredString(fontrenderer, displayString, xPosition + getWidth() / 2, yPosition + (h - 8) / 2, getTextColor(mouseOver)); + } + + @Override + public ToolTip getToolTip() { + return toolTip; + } + + public void setToolTip(ToolTip tips) { + this.toolTip = tips; + } + + @Override + public boolean isToolTipVisible() { + return visible; + } + + @Override + public boolean isMouseOver(int mouseX, int mouseY) { + return isMouseOverButton(mouseX, mouseY); + } +} diff --git a/forestry_common/core/forestry/core/gui/buttons/GuiButtonSmall.java b/forestry_common/core/forestry/core/gui/buttons/GuiButtonSmall.java new file mode 100755 index 000000000..479de8e43 --- /dev/null +++ b/forestry_common/core/forestry/core/gui/buttons/GuiButtonSmall.java @@ -0,0 +1,24 @@ +/******************************************************************************* + * Copyright 2011-2014 by SirSengir + * + * This work is licensed under a Creative Commons Attribution-NonCommercial-NoDerivs 3.0 Unported License. + * + * To view a copy of this license, visit http://creativecommons.org/licenses/by-nc-nd/3.0/. + ******************************************************************************/ +package forestry.core.gui.buttons; + +import cpw.mods.fml.relauncher.Side; +import cpw.mods.fml.relauncher.SideOnly; + +@SideOnly(Side.CLIENT) +public class GuiButtonSmall extends GuiBetterButton { + + public GuiButtonSmall(int i, int x, int y, String s) { + this(i, x, y, 200, s); + } + + public GuiButtonSmall(int i, int x, int y, int w, String s) { + super(i, x, y, w, StandardButtonTextureSets.SMALL_BUTTON, s); + } + +} diff --git a/forestry_common/core/forestry/core/gui/buttons/GuiMultiButton.java b/forestry_common/core/forestry/core/gui/buttons/GuiMultiButton.java new file mode 100755 index 000000000..3e9813246 --- /dev/null +++ b/forestry_common/core/forestry/core/gui/buttons/GuiMultiButton.java @@ -0,0 +1,98 @@ +/******************************************************************************* + * Copyright 2011-2014 by SirSengir + * + * This work is licensed under a Creative Commons Attribution-NonCommercial-NoDerivs 3.0 Unported License. + * + * To view a copy of this license, visit http://creativecommons.org/licenses/by-nc-nd/3.0/. + ******************************************************************************/ +package forestry.core.gui.buttons; + +import net.minecraft.client.Minecraft; +import net.minecraft.client.gui.FontRenderer; + +import cpw.mods.fml.relauncher.Side; +import cpw.mods.fml.relauncher.SideOnly; + +import org.lwjgl.input.Mouse; +import org.lwjgl.opengl.GL11; + +import forestry.core.gui.tooltips.ToolTip; + +/** + * + * @author CovertJaguar + */ +@SideOnly(Side.CLIENT) +public class GuiMultiButton extends GuiBetterButton { + + private final MultiButtonController control; + public boolean canChange = true; + + public GuiMultiButton(int id, int x, int y, int width, MultiButtonController control) { + super(id, x, y, width, StandardButtonTextureSets.LARGE_BUTTON, ""); + this.control = control; + } + + @Override + public int getHeight() { + return texture.getHeight(); + } + + @Override + public void drawButton(Minecraft minecraft, int x, int y) { + if (!visible) { + return; + } + FontRenderer fontrenderer = minecraft.fontRenderer; + bindButtonTextures(minecraft); + GL11.glColor4f(1.0F, 1.0F, 1.0F, 1.0F); + IMultiButtonState state = control.getButtonState(); + IButtonTextureSet tex = state.getTextureSet(); + int xOffset = tex.getX(); + int yOffset = tex.getY(); + int h = tex.getHeight(); + int w = tex.getWidth(); + boolean flag = x >= xPosition && y >= yPosition && x < xPosition + width && y < yPosition + h; + int hoverState = getHoverState(flag); + drawTexturedModalRect(xPosition, yPosition, xOffset, yOffset + hoverState * h, width / 2, h); + drawTexturedModalRect(xPosition + width / 2, yPosition, xOffset + w - width / 2, yOffset + hoverState * h, width / 2, h); + mouseDragged(minecraft, x, y); + displayString = state.getLabel(); + if (!displayString.equals("")) { + if (!enabled) { + drawCenteredString(fontrenderer, displayString, xPosition + width / 2, yPosition + (h - 8) / 2, 0xffa0a0a0); + } else if (flag) { + drawCenteredString(fontrenderer, displayString, xPosition + width / 2, yPosition + (h - 8) / 2, 0xffffa0); + } else { + drawCenteredString(fontrenderer, displayString, xPosition + width / 2, yPosition + (h - 8) / 2, 0xe0e0e0); + } + } + } + + @Override + public boolean mousePressed(Minecraft minecraft, int mouseX, int mouseY) { + boolean pressed = super.mousePressed(minecraft, mouseX, mouseY); + if (canChange && pressed && enabled) { + if (Mouse.getEventButton() == 0) { + control.incrementState(); + } else { + control.decrementState(); + } + } + return pressed; + } + + public MultiButtonController getController() { + return control; + } + + @Override + public ToolTip getToolTip() { + ToolTip tip = control.getButtonState().getToolTip(); + if (tip != null) { + return tip; + } + return super.getToolTip(); + } + +} diff --git a/forestry_common/core/forestry/core/gui/buttons/GuiToggleButton.java b/forestry_common/core/forestry/core/gui/buttons/GuiToggleButton.java new file mode 100755 index 000000000..3a199ba06 --- /dev/null +++ b/forestry_common/core/forestry/core/gui/buttons/GuiToggleButton.java @@ -0,0 +1,58 @@ +/******************************************************************************* + * Copyright 2011-2014 by SirSengir + * + * This work is licensed under a Creative Commons Attribution-NonCommercial-NoDerivs 3.0 Unported License. + * + * To view a copy of this license, visit http://creativecommons.org/licenses/by-nc-nd/3.0/. + ******************************************************************************/ +package forestry.core.gui.buttons; + +public class GuiToggleButton extends GuiBetterButton { + + public boolean active; + + public GuiToggleButton(int id, int x, int y, String label, boolean active) { + this(id, x, y, 200, StandardButtonTextureSets.LARGE_BUTTON, label, active); + } + + public GuiToggleButton(int id, int x, int y, int width, String s, boolean active) { + super(id, x, y, width, StandardButtonTextureSets.LARGE_BUTTON, s); + this.active = active; + } + + public GuiToggleButton(int id, int x, int y, int width, IButtonTextureSet texture, String s, boolean active) { + super(id, x, y, width, texture, s); + this.active = active; + } + + public void toggle() { + active = !active; + } + + @Override + protected int getHoverState(boolean mouseOver) { + int state = 1; + if (!enabled) { + state = 0; + } else if (mouseOver) { + state = 2; + } else if (!active) { + state = 3; + } + return state; + } + + @Override + public int getTextColor(boolean mouseOver) { + if (!enabled) { + return 0xffa0a0a0; + } else if (mouseOver) { + return 0xffffa0; + } else if (!active) { + return 0x777777; + } else { + return 0xe0e0e0; + } + } + +} diff --git a/forestry_common/core/forestry/core/gui/buttons/GuiToggleButtonSmall.java b/forestry_common/core/forestry/core/gui/buttons/GuiToggleButtonSmall.java new file mode 100755 index 000000000..c9363e0f9 --- /dev/null +++ b/forestry_common/core/forestry/core/gui/buttons/GuiToggleButtonSmall.java @@ -0,0 +1,25 @@ +/******************************************************************************* + * Copyright 2011-2014 by SirSengir + * + * This work is licensed under a Creative Commons Attribution-NonCommercial-NoDerivs 3.0 Unported License. + * + * To view a copy of this license, visit http://creativecommons.org/licenses/by-nc-nd/3.0/. + ******************************************************************************/ +package forestry.core.gui.buttons; + +import cpw.mods.fml.relauncher.Side; +import cpw.mods.fml.relauncher.SideOnly; + +@SideOnly(Side.CLIENT) +public class GuiToggleButtonSmall extends GuiToggleButton { + + public GuiToggleButtonSmall(int i, int j, int k, String s, boolean active) { + this(i, j, k, 200, s, active); + } + + public GuiToggleButtonSmall(int i, int x, int y, int w, String s, boolean active) { + super(i, x, y, w, StandardButtonTextureSets.SMALL_BUTTON, s, active); + this.active = active; + } + +} diff --git a/forestry_common/core/forestry/core/gui/buttons/IButtonTextureSet.java b/forestry_common/core/forestry/core/gui/buttons/IButtonTextureSet.java new file mode 100755 index 000000000..fd151bd11 --- /dev/null +++ b/forestry_common/core/forestry/core/gui/buttons/IButtonTextureSet.java @@ -0,0 +1,24 @@ +/******************************************************************************* + * Copyright 2011-2014 by SirSengir + * + * This work is licensed under a Creative Commons Attribution-NonCommercial-NoDerivs 3.0 Unported License. + * + * To view a copy of this license, visit http://creativecommons.org/licenses/by-nc-nd/3.0/. + ******************************************************************************/ +package forestry.core.gui.buttons; + +/** + * + * @author CovertJaguar + */ +public interface IButtonTextureSet { + + public int getX(); + + public int getY(); + + public int getHeight(); + + public int getWidth(); + +} diff --git a/forestry_common/core/forestry/core/gui/buttons/IMultiButtonState.java b/forestry_common/core/forestry/core/gui/buttons/IMultiButtonState.java new file mode 100755 index 000000000..00490f1b3 --- /dev/null +++ b/forestry_common/core/forestry/core/gui/buttons/IMultiButtonState.java @@ -0,0 +1,27 @@ +/******************************************************************************* + * Copyright 2011-2014 by SirSengir + * + * This work is licensed under a Creative Commons Attribution-NonCommercial-NoDerivs 3.0 Unported License. + * + * To view a copy of this license, visit http://creativecommons.org/licenses/by-nc-nd/3.0/. + ******************************************************************************/ +package forestry.core.gui.buttons; + +import forestry.core.gui.tooltips.ToolTip; + + +/** + * + * @author CovertJaguar + */ +public interface IMultiButtonState { + + public String getLabel(); + + public String name(); + + public IButtonTextureSet getTextureSet(); + + public ToolTip getToolTip(); + +} diff --git a/forestry_common/core/forestry/core/gui/buttons/LockButtonState.java b/forestry_common/core/forestry/core/gui/buttons/LockButtonState.java new file mode 100755 index 000000000..7c9b3648c --- /dev/null +++ b/forestry_common/core/forestry/core/gui/buttons/LockButtonState.java @@ -0,0 +1,42 @@ +/******************************************************************************* + * Copyright 2011-2014 by SirSengir + * + * This work is licensed under a Creative Commons Attribution-NonCommercial-NoDerivs 3.0 Unported License. + * + * To view a copy of this license, visit http://creativecommons.org/licenses/by-nc-nd/3.0/. + ******************************************************************************/ +package forestry.core.gui.buttons; + +import forestry.core.gui.tooltips.ToolTip; + +/** + * + * @author CovertJaguar + */ +public enum LockButtonState implements IMultiButtonState { + + UNLOCKED(new ButtonTextureSet(224, 0, 16, 16)), + LOCKED(new ButtonTextureSet(240, 0, 16, 16)); + public static final LockButtonState[] VALUES = values(); + private final IButtonTextureSet texture; + + private LockButtonState(IButtonTextureSet texture) { + this.texture = texture; + } + + @Override + public String getLabel() { + return ""; + } + + @Override + public IButtonTextureSet getTextureSet() { + return texture; + } + + @Override + public ToolTip getToolTip() { + return null; + } + +} diff --git a/forestry_common/core/forestry/core/gui/buttons/MultiButtonController.java b/forestry_common/core/forestry/core/gui/buttons/MultiButtonController.java new file mode 100755 index 000000000..5c268674d --- /dev/null +++ b/forestry_common/core/forestry/core/gui/buttons/MultiButtonController.java @@ -0,0 +1,98 @@ +/******************************************************************************* + * Copyright 2011-2014 by SirSengir + * + * This work is licensed under a Creative Commons Attribution-NonCommercial-NoDerivs 3.0 Unported License. + * + * To view a copy of this license, visit http://creativecommons.org/licenses/by-nc-nd/3.0/. + ******************************************************************************/ +package forestry.core.gui.buttons; + +import net.minecraft.nbt.NBTTagByte; +import net.minecraft.nbt.NBTTagCompound; +import net.minecraft.nbt.NBTTagString; + +/** + * + * @author CovertJaguar + */ +public class MultiButtonController { + + private int currentState; + private final T[] validStates; + + public MultiButtonController(int startState, T... validStates) { + this.currentState = startState; + this.validStates = validStates; + } + + protected MultiButtonController(MultiButtonController controller) { + this.currentState = controller.currentState; + this.validStates = controller.validStates; + } + + public MultiButtonController copy() { + return new MultiButtonController(this); + } + + public T[] getValidStates() { + return validStates; + } + + public int incrementState() { + int newState = currentState + 1; + if (newState >= validStates.length) { + newState = 0; + } + currentState = newState; + return currentState; + } + + public int decrementState() { + int newState = currentState - 1; + if (newState < 0) { + newState = validStates.length - 1; + } + currentState = newState; + return currentState; + } + + public void setCurrentState(int state) { + currentState = state; + } + + public void setCurrentState(T state) { + for (int i = 0; i < validStates.length; i++) { + if (validStates[i] == state) { + currentState = i; + return; + } + } + } + + public int getCurrentState() { + return currentState; + } + + public T getButtonState() { + return validStates[currentState]; + } + + public void writeToNBT(NBTTagCompound nbt, String tag) { + nbt.setString(tag, getButtonState().name()); + } + + public void readFromNBT(NBTTagCompound nbt, String tag) { + if (nbt.getTag(tag) instanceof NBTTagString) { + String name = nbt.getString(tag); + for (int i = 0; i < validStates.length; i++) { + if (validStates[i].name().equals(name)) { + currentState = i; + break; + } + } + } else if (nbt.getTag(tag) instanceof NBTTagByte) { + currentState = nbt.getByte(tag); + } + } + +} diff --git a/forestry_common/core/forestry/core/gui/buttons/StandardButtonTextureSets.java b/forestry_common/core/forestry/core/gui/buttons/StandardButtonTextureSets.java new file mode 100755 index 000000000..d8158084e --- /dev/null +++ b/forestry_common/core/forestry/core/gui/buttons/StandardButtonTextureSets.java @@ -0,0 +1,53 @@ +/******************************************************************************* + * Copyright 2011-2014 by SirSengir + * + * This work is licensed under a Creative Commons Attribution-NonCommercial-NoDerivs 3.0 Unported License. + * + * To view a copy of this license, visit http://creativecommons.org/licenses/by-nc-nd/3.0/. + ******************************************************************************/ +package forestry.core.gui.buttons; + +/** + * + * @author CovertJaguar + */ +public enum StandardButtonTextureSets implements IButtonTextureSet{ + + LARGE_BUTTON(0, 0, 20, 200), + SMALL_BUTTON(0, 80, 15, 200), + LOCKED_BUTTON(224, 0, 16, 16), + UNLOCKED_BUTTON(240, 0, 16, 16), + LEFT_BUTTON(204, 0, 16, 10), + RIGHT_BUTTON(214, 0, 16, 10), + LEFT_BUTTON_SMALL(238, 220, 12, 9), + RIGHT_BUTTON_SMALL(247, 220, 12, 9); + private final int x, y, height, width; + + private StandardButtonTextureSets(int x, int y, int height, int width) { + this.x = x; + this.y = y; + this.height = height; + this.width = width; + } + + @Override + public int getX() { + return x; + } + + @Override + public int getY() { + return y; + } + + @Override + public int getHeight() { + return height; + } + + @Override + public int getWidth() { + return width; + } + +} diff --git a/forestry_common/core/forestry/core/gui/slots/SlotClosed.java b/forestry_common/core/forestry/core/gui/slots/SlotClosed.java new file mode 100755 index 000000000..5f036049c --- /dev/null +++ b/forestry_common/core/forestry/core/gui/slots/SlotClosed.java @@ -0,0 +1,24 @@ +/******************************************************************************* + * Copyright 2011-2014 by SirSengir + * + * This work is licensed under a Creative Commons Attribution-NonCommercial-NoDerivs 3.0 Unported License. + * + * To view a copy of this license, visit http://creativecommons.org/licenses/by-nc-nd/3.0/. + ******************************************************************************/ +package forestry.core.gui.slots; + +import net.minecraft.inventory.IInventory; +import net.minecraft.item.ItemStack; + +public class SlotClosed extends SlotForestry { + + public SlotClosed(IInventory par1iInventory, int par2, int par3, int par4) { + super(par1iInventory, par2, par3, par4); + } + + @Override + public boolean isItemValid(ItemStack par1ItemStack) { + return false; + } + +} diff --git a/forestry_common/core/forestry/core/gui/slots/SlotCraftAuto.java b/forestry_common/core/forestry/core/gui/slots/SlotCraftAuto.java new file mode 100755 index 000000000..6efca056c --- /dev/null +++ b/forestry_common/core/forestry/core/gui/slots/SlotCraftAuto.java @@ -0,0 +1,35 @@ +/******************************************************************************* + * Copyright 2011-2014 by SirSengir + * + * This work is licensed under a Creative Commons Attribution-NonCommercial-NoDerivs 3.0 Unported License. + * + * To view a copy of this license, visit http://creativecommons.org/licenses/by-nc-nd/3.0/. + ******************************************************************************/ +package forestry.core.gui.slots; + +import net.minecraft.inventory.IInventory; +import net.minecraft.inventory.Slot; + +import forestry.core.interfaces.IContainerCrafting; + +/** + * Informs the passed container of slot changes. + */ +public class SlotCraftAuto extends Slot { + + private IContainerCrafting eventHandler; + private int slot; + + public SlotCraftAuto(IContainerCrafting container, IInventory iinventory, int slotNumber, int x, int y) { + super(iinventory, slotNumber, x, y); + this.eventHandler = container; + this.slot = slotNumber; + } + + @Override + public void onSlotChanged() { + super.onSlotChanged(); + eventHandler.onCraftMatrixChanged(inventory, slot); + } + +} diff --git a/forestry_common/core/forestry/core/gui/slots/SlotCrafter.java b/forestry_common/core/forestry/core/gui/slots/SlotCrafter.java new file mode 100755 index 000000000..ecc13d1ee --- /dev/null +++ b/forestry_common/core/forestry/core/gui/slots/SlotCrafter.java @@ -0,0 +1,58 @@ +/******************************************************************************* + * Copyright 2011-2014 by SirSengir + * + * This work is licensed under a Creative Commons Attribution-NonCommercial-NoDerivs 3.0 Unported License. + * + * To view a copy of this license, visit http://creativecommons.org/licenses/by-nc-nd/3.0/. + ******************************************************************************/ +package forestry.core.gui.slots; + +import net.minecraft.entity.player.EntityPlayer; +import net.minecraft.inventory.IInventory; +import net.minecraft.inventory.Slot; +import net.minecraft.item.ItemStack; + +import forestry.core.interfaces.ICrafter; + +public class SlotCrafter extends Slot { + + ICrafter crafter; + + public SlotCrafter(IInventory inventory, ICrafter crafter, int slot, int xPos, int yPos) { + super(inventory, slot, xPos, yPos); + this.crafter = crafter; + } + + @Override + public boolean isItemValid(ItemStack par1ItemStack) { + return false; + } + + @Override + public ItemStack decrStackSize(int amount) { + if (!this.getHasStack()) + return null; + + return this.getStack(); + } + + @Override + public boolean canTakeStack(EntityPlayer player) { + return crafter.canTakeStack(getSlotIndex()); + } + + @Override + public ItemStack getStack() { + return this.crafter.getResult(); + } + + @Override + public boolean getHasStack() { + return this.getStack() != null && crafter.canTakeStack(getSlotIndex()); + } + + @Override + public void onPickupFromSlot(EntityPlayer player, ItemStack itemStack) { + crafter.takenFromSlot(getSlotIndex(), true, player); + } +} diff --git a/forestry_common/core/forestry/core/gui/slots/SlotCustom.java b/forestry_common/core/forestry/core/gui/slots/SlotCustom.java new file mode 100755 index 000000000..1e10c6708 --- /dev/null +++ b/forestry_common/core/forestry/core/gui/slots/SlotCustom.java @@ -0,0 +1,149 @@ +/******************************************************************************* + * Copyright 2011-2014 by SirSengir + * + * This work is licensed under a Creative Commons Attribution-NonCommercial-NoDerivs 3.0 Unported License. + * + * To view a copy of this license, visit http://creativecommons.org/licenses/by-nc-nd/3.0/. + ******************************************************************************/ +package forestry.core.gui.slots; + +import java.util.Collection; + +import net.minecraft.block.Block; +import net.minecraft.entity.player.EntityPlayer; +import net.minecraft.inventory.IInventory; +import net.minecraft.item.Item; +import net.minecraft.item.ItemStack; +import net.minecraft.util.IIcon; + +import cpw.mods.fml.relauncher.Side; +import cpw.mods.fml.relauncher.SideOnly; + +import forestry.api.genetics.ISpeciesRoot; +import forestry.core.config.Defaults; +import forestry.core.config.ForestryItem; +import forestry.core.interfaces.ICrafter; +import forestry.core.render.TextureManager; +import forestry.core.utils.StackUtils; + +/** + * Slot which only specific items. (With permission by RichardG.) + * + * @author Richard + */ +public class SlotCustom extends SlotForestry { + + protected Object[] items; + private boolean exclusion; + private ICrafter crafter; + private String blockedTexture = "slots/blocked"; + + public SlotCustom(IInventory iinventory, int i, int j, int k, boolean exclusion) { + super(iinventory, i, j, k); + items = new Object[0]; + this.exclusion = exclusion; + } + + /*public SlotCustom(IInventory iinventory, ArrayList items, int i, int j, int k) { + this(iinventory, i, j, k, items.toArray()); + }*/ + + public SlotCustom(IInventory iinventory, Collection items, int i, int j, int k) { + this(iinventory, i, j, k, items.toArray()); + } + + public SlotCustom(IInventory iinventory, int i, int j, int k, boolean exclusion, Object... items) { + this(iinventory, i, j, k, items); + this.exclusion = exclusion; + } + + public SlotCustom(IInventory iinventory, int i, int j, int k, Object... items) { + super(iinventory, i, j, k); + this.items = items; + } + + public SlotCustom setCrafter(ICrafter crafter) { + this.crafter = crafter; + return this; + } + + @Override + public boolean isItemValid(ItemStack itemstack) { + if (itemstack == null) + return false; + if (!inventory.isItemValidForSlot(getSlotIndex(), itemstack)) + return false; + + if (exclusion) + return !determineValidity(itemstack); + else + return determineValidity(itemstack); + } + + @Override + public boolean getHasStack() { + if (crafter != null && !crafter.canTakeStack(getSlotIndex())) + return false; + else + return super.getHasStack(); + } + + @Override + public ItemStack decrStackSize(int i) { + if (crafter != null && !crafter.canTakeStack(getSlotIndex())) + return null; + else + return super.decrStackSize(i); + } + + @Override + public void onPickupFromSlot(EntityPlayer player, ItemStack itemStack) { + if (crafter != null) + crafter.takenFromSlot(getSlotIndex(), true, player); + } + + @SuppressWarnings({ "rawtypes", "unchecked" }) + private boolean determineValidity(ItemStack itemstack) { + for (Object filter : items) { + if (filter == null) + continue; + if (filter instanceof Class) { + Block block = StackUtils.getBlock(itemstack); + + if (block != null && ((Class) filter).isAssignableFrom(block.getClass())) return true; + if (((Class) filter).isAssignableFrom(itemstack.getItem().getClass())) return true; + } else if (filter instanceof ItemStack) { + if (((ItemStack) filter).getItemDamage() == Defaults.WILDCARD && itemstack.getItem() == ((ItemStack) filter).getItem()) + return true; + else if (itemstack.isItemEqual((ItemStack) filter)) + return true; + } else if (filter instanceof Block) { + if (StackUtils.equals((Block) filter, itemstack)) return true; + } else if (filter instanceof Item) { + if (itemstack.getItem() == (Item) filter) return true; + } else if (filter instanceof ForestryItem) { + if (((ForestryItem) filter).isItemEqual(itemstack)) return true; + } else if (filter instanceof ISpeciesRoot) { + if (((ISpeciesRoot) filter).isMember(itemstack)) return true; + } else { + throw new RuntimeException("invalid filter item specified: "+filter+" ("+filter.getClass()+")"); + } + } + + return false; + } + + public SlotCustom setBlockedTexture(String ident) { + blockedTexture = ident; + return this; + } + + @SideOnly(Side.CLIENT) + @Override + public IIcon getBackgroundIconIndex() { + if (!inventory.isItemValidForSlot(getSlotIndex(), null)) + return TextureManager.getInstance().getDefault(blockedTexture); + else + return null; + } +} diff --git a/forestry_common/core/forestry/core/gui/slots/SlotForestry.java b/forestry_common/core/forestry/core/gui/slots/SlotForestry.java new file mode 100755 index 000000000..83d17460a --- /dev/null +++ b/forestry_common/core/forestry/core/gui/slots/SlotForestry.java @@ -0,0 +1,132 @@ +/******************************************************************************* + * Copyright 2011-2014 by SirSengir + * + * This work is licensed under a Creative Commons Attribution-NonCommercial-NoDerivs 3.0 Unported License. + * + * To view a copy of this license, visit http://creativecommons.org/licenses/by-nc-nd/3.0/. + ******************************************************************************/ +package forestry.core.gui.slots; + +import net.minecraft.entity.player.EntityPlayer; +import net.minecraft.inventory.IInventory; +import net.minecraft.inventory.Slot; +import net.minecraft.item.ItemStack; + +import forestry.core.gui.tooltips.IToolTipProvider; +import forestry.core.gui.tooltips.ToolTip; + +public class SlotForestry extends Slot implements IToolTipProvider{ + + protected boolean isPhantom; + protected boolean isInfinite; + protected boolean canAdjustPhantom = true; + protected boolean canShift = true; + protected int stackLimit; + private ToolTip toolTips; + + public SlotForestry(IInventory inventory, int slotIndex, int xPos, int yPos) { + this(inventory, slotIndex, xPos, yPos, -1); + } + + public SlotForestry(IInventory inventory, int slotIndex, int xPos, int yPos, int stackLimit) { + super(inventory, slotIndex, xPos, yPos); + this.stackLimit = stackLimit; + } + + public SlotForestry setInfinite() { + this.isInfinite = true; + return this; + } + + public SlotForestry setPhantom() { + isPhantom = true; + return this; + } + + public SlotForestry blockShift() { + canShift = false; + return this; + } + + public SlotForestry setCanAdjustPhantom(boolean canAdjust) { + this.canAdjustPhantom = canAdjust; + return this; + } + + public SlotForestry setCanShift(boolean canShift) { + this.canShift = canShift; + return this; + } + + public SlotForestry setStackLimit(int limit) { + this.stackLimit = limit; + return this; + } + + public boolean isPhantom() { + return this.isPhantom; + } + + public boolean canAdjustPhantom() { + return canAdjustPhantom; + } + + @Override + public boolean canTakeStack(EntityPlayer stack) { + return !isPhantom(); + } + + public boolean canShift() { + return canShift; + } + + @Override + public int getSlotStackLimit() { + if (stackLimit < 0) + return super.getSlotStackLimit(); + else + return stackLimit; + } + + @Override + public ItemStack decrStackSize(int i) { + if (!isInfinite) + return super.decrStackSize(i); + + ItemStack stack = inventory.getStackInSlot(getSlotIndex()); + if (stack == null) + return null; + + ItemStack result = stack.copy(); + result.stackSize = i; + return result; + } + + public void onSlotClick(int slotIndex, int button, int modifier, EntityPlayer player) { + } + + /** + * @param toolTips the tooltips to set + */ + public void setToolTips(ToolTip toolTips) { + this.toolTips = toolTips; + } + + /** + * @return the toolTips + */ + @Override + public ToolTip getToolTip() { + return toolTips; + } + + @Override + public boolean isToolTipVisible() { + return getStack() == null; + } + + @Override + public boolean isMouseOver(int mouseX, int mouseY) { + return mouseX >= xDisplayPosition && mouseX <= xDisplayPosition + 16 && mouseY >= yDisplayPosition && mouseY <= yDisplayPosition + 16; + } +} diff --git a/forestry_common/core/forestry/core/gui/slots/SlotItemInventory.java b/forestry_common/core/forestry/core/gui/slots/SlotItemInventory.java new file mode 100755 index 000000000..6a4afe5a7 --- /dev/null +++ b/forestry_common/core/forestry/core/gui/slots/SlotItemInventory.java @@ -0,0 +1,34 @@ +/******************************************************************************* + * Copyright 2011-2014 by SirSengir + * + * This work is licensed under a Creative Commons Attribution-NonCommercial-NoDerivs 3.0 Unported License. + * + * To view a copy of this license, visit http://creativecommons.org/licenses/by-nc-nd/3.0/. + ******************************************************************************/ +package forestry.core.gui.slots; + +import net.minecraft.entity.player.EntityPlayer; +import net.minecraft.inventory.IInventory; +import net.minecraft.inventory.Slot; +import net.minecraft.item.ItemStack; + +import forestry.core.gui.ContainerItemInventory; + +public class SlotItemInventory extends Slot { + + private final EntityPlayer player; + private ContainerItemInventory container; + + public SlotItemInventory(ContainerItemInventory container, IInventory inventory, EntityPlayer player, int par2, int par3, int par4) { + super(inventory, par2, par3, par4); + this.container = container; + this.player = player; + } + + @Override + public void onSlotChange(ItemStack par1ItemStack, ItemStack par2ItemStack) { + super.onSlotChange(par1ItemStack, par2ItemStack); + container.saveInventory(player); + } + +} diff --git a/forestry_common/core/forestry/core/gui/slots/SlotLiquidContainer.java b/forestry_common/core/forestry/core/gui/slots/SlotLiquidContainer.java new file mode 100755 index 000000000..eca98b2c8 --- /dev/null +++ b/forestry_common/core/forestry/core/gui/slots/SlotLiquidContainer.java @@ -0,0 +1,57 @@ +/******************************************************************************* + * Copyright 2011-2014 by SirSengir + * + * This work is licensed under a Creative Commons Attribution-NonCommercial-NoDerivs 3.0 Unported License. + * + * To view a copy of this license, visit http://creativecommons.org/licenses/by-nc-nd/3.0/. + ******************************************************************************/ +package forestry.core.gui.slots; + +import java.util.ArrayList; +import java.util.List; + +import net.minecraft.inventory.IInventory; +import net.minecraft.item.ItemStack; +import net.minecraft.util.IIcon; + +import cpw.mods.fml.relauncher.Side; +import cpw.mods.fml.relauncher.SideOnly; + +import net.minecraftforge.fluids.FluidContainerRegistry; +import net.minecraftforge.fluids.FluidContainerRegistry.FluidContainerData; + +import forestry.core.render.TextureManager; + +public class SlotLiquidContainer extends SlotCustom { + + private final boolean isEmpty; + + public SlotLiquidContainer(IInventory iinventory, int i, int j, int k) { + this(iinventory, i, j, k, false); + } + + public SlotLiquidContainer(IInventory iinventory, int i, int j, int k, boolean isEmpty) { + super(iinventory, i, j, k, false); + + this.isEmpty = isEmpty; + List container = new ArrayList(); + + for (FluidContainerData cont : FluidContainerRegistry.getRegisteredFluidContainerData()) + if (isEmpty) + container.add(cont.emptyContainer); + else + container.add(cont.filledContainer); + + this.items = container.toArray(); + } + + @SideOnly(Side.CLIENT) + @Override + public IIcon getBackgroundIconIndex() { + if(isEmpty) + return TextureManager.getInstance().getDefault("slots/container"); + else + return TextureManager.getInstance().getDefault("slots/liquid"); + } + +} diff --git a/forestry_common/core/forestry/core/gui/slots/SlotLocked.java b/forestry_common/core/forestry/core/gui/slots/SlotLocked.java new file mode 100755 index 000000000..eb5068522 --- /dev/null +++ b/forestry_common/core/forestry/core/gui/slots/SlotLocked.java @@ -0,0 +1,40 @@ +/******************************************************************************* + * Copyright 2011-2014 by SirSengir + * + * This work is licensed under a Creative Commons Attribution-NonCommercial-NoDerivs 3.0 Unported License. + * + * To view a copy of this license, visit http://creativecommons.org/licenses/by-nc-nd/3.0/. + ******************************************************************************/ +package forestry.core.gui.slots; + +import net.minecraft.entity.player.EntityPlayer; +import net.minecraft.inventory.IInventory; +import net.minecraft.item.ItemStack; + +public class SlotLocked extends SlotForestry { + + public SlotLocked(IInventory par1iInventory, int par2, int par3, int par4) { + super(par1iInventory, par2, par3, par4); + setCanAdjustPhantom(false); + setCanShift(false); + } + + @Override + public void onPickupFromSlot(EntityPlayer player, ItemStack itemStack) { + } + + @Override + public boolean isItemValid(ItemStack par1ItemStack) { + return false; + } + + @Override + public boolean getHasStack() { + return false; + } + + @Override + public ItemStack decrStackSize(int i) { + return null; + } +} diff --git a/forestry_common/core/forestry/core/gui/slots/SlotOutput.java b/forestry_common/core/forestry/core/gui/slots/SlotOutput.java new file mode 100755 index 000000000..2a116a4dc --- /dev/null +++ b/forestry_common/core/forestry/core/gui/slots/SlotOutput.java @@ -0,0 +1,27 @@ +/******************************************************************************* + * Copyright 2011-2014 by SirSengir + * + * This work is licensed under a Creative Commons Attribution-NonCommercial-NoDerivs 3.0 Unported License. + * + * To view a copy of this license, visit http://creativecommons.org/licenses/by-nc-nd/3.0/. + ******************************************************************************/ +package forestry.core.gui.slots; + +import net.minecraft.inventory.IInventory; +import net.minecraft.item.ItemStack; + +/** + * + * @author CovertJaguar + */ +public class SlotOutput extends SlotForestry { + + public SlotOutput(IInventory iinventory, int slotIndex, int posX, int posY) { + super(iinventory, slotIndex, posX, posY); + } + + @Override + public boolean isItemValid(ItemStack itemstack) { + return false; + } +} diff --git a/forestry_common/core/forestry/core/gui/slots/SlotWorking.java b/forestry_common/core/forestry/core/gui/slots/SlotWorking.java new file mode 100755 index 000000000..dacda5b02 --- /dev/null +++ b/forestry_common/core/forestry/core/gui/slots/SlotWorking.java @@ -0,0 +1,39 @@ +/******************************************************************************* + * Copyright 2011-2014 by SirSengir + * + * This work is licensed under a Creative Commons Attribution-NonCommercial-NoDerivs 3.0 Unported License. + * + * To view a copy of this license, visit http://creativecommons.org/licenses/by-nc-nd/3.0/. + ******************************************************************************/ +package forestry.core.gui.slots; + +import net.minecraft.entity.player.EntityPlayer; +import net.minecraft.inventory.IInventory; +import net.minecraft.item.ItemStack; + +public class SlotWorking extends SlotForestry { + + public SlotWorking(IInventory iinventory, int i, int j, int k) { + super(iinventory, i, j, k); + setCanShift(false); + } + + @Override + public boolean isItemValid(ItemStack itemstack) { + return false; + } + + @Override + public void onPickupFromSlot(EntityPlayer player, ItemStack itemStack) { + } + + @Override + public boolean getHasStack() { + return false; + } + + @Override + public ItemStack decrStackSize(int i) { + return null; + } +} diff --git a/forestry_common/core/forestry/core/gui/tooltips/IToolTipProvider.java b/forestry_common/core/forestry/core/gui/tooltips/IToolTipProvider.java new file mode 100755 index 000000000..4c08b657b --- /dev/null +++ b/forestry_common/core/forestry/core/gui/tooltips/IToolTipProvider.java @@ -0,0 +1,21 @@ +/******************************************************************************* + * Copyright 2011-2014 by SirSengir + * + * This work is licensed under a Creative Commons Attribution-NonCommercial-NoDerivs 3.0 Unported License. + * + * To view a copy of this license, visit http://creativecommons.org/licenses/by-nc-nd/3.0/. + ******************************************************************************/ +package forestry.core.gui.tooltips; + +/** + * + * @author CovertJaguar + */ +public interface IToolTipProvider { + + ToolTip getToolTip(); + + boolean isToolTipVisible(); + + boolean isMouseOver(int mouseX, int mouseY); +} diff --git a/forestry_common/core/forestry/core/gui/tooltips/ToolTip.java b/forestry_common/core/forestry/core/gui/tooltips/ToolTip.java new file mode 100755 index 000000000..b665e6bac --- /dev/null +++ b/forestry_common/core/forestry/core/gui/tooltips/ToolTip.java @@ -0,0 +1,90 @@ +/******************************************************************************* + * Copyright 2011-2014 by SirSengir + * + * This work is licensed under a Creative Commons Attribution-NonCommercial-NoDerivs 3.0 Unported License. + * + * To view a copy of this license, visit http://creativecommons.org/licenses/by-nc-nd/3.0/. + ******************************************************************************/ +package forestry.core.gui.tooltips; + +import java.util.ArrayList; +import java.util.List; + +import com.google.common.collect.ForwardingList; + +import forestry.core.utils.Localization; + +/** + * + * @author CovertJaguar + */ +public class ToolTip extends ForwardingList { + + private final List delegate = new ArrayList(); + private final long delay; + private long mouseOverStart; + + public ToolTip() { + this.delay = 0; + } + + public ToolTip(int delay) { + this.delay = delay; + } + + @Override + protected final List delegate() { + return delegate; + } + + public boolean add(String line) { + return add(new ToolTipLine(line)); + } + + public void onTick(boolean mouseOver) { + if (delay == 0) + return; + if (mouseOver) { + if (mouseOverStart == 0) + mouseOverStart = System.currentTimeMillis(); + } else + mouseOverStart = 0; + } + + public boolean isReady() { + if (delay == 0) + return true; + if (mouseOverStart == 0) + return false; + return System.currentTimeMillis() - mouseOverStart >= delay; + } + + public void refresh() { + } + + public List convertToStrings() { + List tips = new ArrayList(size()); + for (ToolTipLine line : this) { + tips.add(line.text); + } + return tips; + } + + public static ToolTip buildToolTip(String tipTag, String... vars) { + if (!Localization.instance.hasMapping(tipTag)) + return null; + ToolTip toolTip = new ToolTip(750); + String text = Localization.instance.get(tipTag); + for (String var : vars) { + String[] pair = var.split("="); + text = text.replace(pair[0], pair[1]); + } + String[] tips = text.split("\n"); + for (String tip : tips) { + tip = tip.trim(); + toolTip.add(new ToolTipLine(tip)); + } + return toolTip; + } + +} diff --git a/forestry_common/core/forestry/core/gui/tooltips/ToolTipLine.java b/forestry_common/core/forestry/core/gui/tooltips/ToolTipLine.java new file mode 100755 index 000000000..2ba4a5ea4 --- /dev/null +++ b/forestry_common/core/forestry/core/gui/tooltips/ToolTipLine.java @@ -0,0 +1,43 @@ +/******************************************************************************* + * Copyright 2011-2014 by SirSengir + * + * This work is licensed under a Creative Commons Attribution-NonCommercial-NoDerivs 3.0 Unported License. + * + * To view a copy of this license, visit http://creativecommons.org/licenses/by-nc-nd/3.0/. + ******************************************************************************/ +package forestry.core.gui.tooltips; + +import net.minecraft.util.EnumChatFormatting; + +/** + * + * @author CovertJaguar + */ +public class ToolTipLine { + + public String text; + public final EnumChatFormatting color; + public int spacing; + + public ToolTipLine(String text, EnumChatFormatting color) { + this.text = text; + this.color = color; + } + + public ToolTipLine(String text) { + this(text, null); + } + + public ToolTipLine() { + this("", null); + } + + public void setSpacing(int spacing) { + this.spacing = spacing; + } + + public int getSpacing() { + return spacing; + } + +} diff --git a/forestry_common/core/forestry/core/gui/widgets/ReservoirWidget.java b/forestry_common/core/forestry/core/gui/widgets/ReservoirWidget.java new file mode 100755 index 000000000..e53ad00ff --- /dev/null +++ b/forestry_common/core/forestry/core/gui/widgets/ReservoirWidget.java @@ -0,0 +1,64 @@ +/******************************************************************************* + * Copyright 2011-2014 by SirSengir + * + * This work is licensed under a Creative Commons Attribution-NonCommercial-NoDerivs 3.0 Unported License. + * + * To view a copy of this license, visit http://creativecommons.org/licenses/by-nc-nd/3.0/. + ******************************************************************************/ +package forestry.core.gui.widgets; + +import net.minecraft.util.IIcon; + +import net.minecraftforge.fluids.FluidStack; + +import org.lwjgl.opengl.GL11; + +import forestry.core.gui.WidgetManager; +import forestry.core.proxy.Proxies; +import forestry.core.render.SpriteSheet; + +public class ReservoirWidget extends TankWidget { + + public ReservoirWidget(WidgetManager manager, int xPos, int yPos, int slot) { + super(manager, xPos, yPos, slot); + this.height = 16; + } + + @Override + public void draw(int startX, int startY) { + + FluidStack contents = getTank().getFluid(); + if(contents == null || contents.amount <= 0) + return; + IIcon liquidIcon = contents.getFluid().getIcon(contents); + if(liquidIcon == null) + return; + + int squaled = (contents.amount * height) / getTank().getCapacity(); + if (squaled > height) + squaled = height; + + Proxies.common.bindTexture(SpriteSheet.BLOCKS); + int start = 0; + + GL11.glColor4f(1.0f, 1.0f, 1.0f, 1.0F); + while (true) { + int x = 0; + + if (squaled > 16) { + x = 16; + squaled -= 16; + } else { + x = squaled; + squaled = 0; + } + + manager.gui.drawTexturedModelRectFromIcon(startX + xPos, startY + yPos + height - x - start, liquidIcon, 16, 16 - (16 - x)); + start = start + 16; + + if (x == 0 || squaled == 0) + break; + } + + } +} diff --git a/forestry_common/core/forestry/core/gui/widgets/SocketWidget.java b/forestry_common/core/forestry/core/gui/widgets/SocketWidget.java new file mode 100755 index 000000000..e69caac70 --- /dev/null +++ b/forestry_common/core/forestry/core/gui/widgets/SocketWidget.java @@ -0,0 +1,80 @@ +/******************************************************************************* + * Copyright 2011-2014 by SirSengir + * + * This work is licensed under a Creative Commons Attribution-NonCommercial-NoDerivs 3.0 Unported License. + * + * To view a copy of this license, visit http://creativecommons.org/licenses/by-nc-nd/3.0/. + ******************************************************************************/ +package forestry.core.gui.widgets; + +import java.util.List; + +import net.minecraft.item.Item; +import net.minecraft.item.ItemStack; + +import forestry.core.circuits.ISolderingIron; +import forestry.core.circuits.ItemCircuitBoard; +import forestry.core.gui.ContainerSocketed; +import forestry.core.gui.GuiForestry; +import forestry.core.gui.WidgetManager; +import forestry.core.gui.tooltips.ToolTip; +import forestry.core.interfaces.ISocketable; +import forestry.core.proxy.Proxies; +import forestry.core.utils.StringUtil; + +public class SocketWidget extends Widget { + + ISocketable tile; + int slot = 0; + + public SocketWidget(WidgetManager manager, int xPos, int yPos, ISocketable tile, int slot) { + super(manager, xPos, yPos); + this.tile = tile; + this.slot = slot; + } + + @Override + public void draw(int startX, int startY) { + ItemStack socketStack = tile.getSocket(slot); + if (socketStack != null) + GuiForestry.getItemRenderer().renderItemIntoGUI(manager.minecraft.fontRenderer, manager.minecraft.renderEngine, socketStack, startX + xPos, startY + + yPos); + } + + @Override + public ToolTip getToolTip() { + return toolTip; + } + + protected final ToolTip toolTip = new ToolTip(500) { + @SuppressWarnings("unchecked") + @Override + public void refresh() { + toolTip.clear(); + ItemStack stack = tile.getSocket(slot); + if (stack != null) { + for (String line : (List) stack.getTooltip(Proxies.common.getClientInstance().thePlayer, false)) { + toolTip.add(line); + } + } else { + toolTip.add(StringUtil.localize("gui.emptysocket")); + } + } + }; + + @Override + public void handleMouseClick(int mouseX, int mouseY, int mouseButton) { + + ItemStack itemstack = manager.minecraft.thePlayer.inventory.getItemStack(); + if (itemstack == null) + return; + + Item held = itemstack.getItem(); + + // Insert chipsets + if (held instanceof ItemCircuitBoard) + ((ContainerSocketed) manager.gui.inventorySlots).handleChipsetClick(slot, manager.minecraft.thePlayer, itemstack); + else if (held instanceof ISolderingIron) + ((ContainerSocketed) manager.gui.inventorySlots).handleSolderingIronClick(slot, manager.minecraft.thePlayer, itemstack); + } +} diff --git a/forestry_common/core/forestry/core/gui/widgets/TankWidget.java b/forestry_common/core/forestry/core/gui/widgets/TankWidget.java new file mode 100755 index 000000000..d93c21d41 --- /dev/null +++ b/forestry_common/core/forestry/core/gui/widgets/TankWidget.java @@ -0,0 +1,113 @@ +/******************************************************************************* + * Copyright 2011-2014 by SirSengir + * + * This work is licensed under a Creative Commons Attribution-NonCommercial-NoDerivs 3.0 Unported License. + * + * To view a copy of this license, visit http://creativecommons.org/licenses/by-nc-nd/3.0/. + ******************************************************************************/ +package forestry.core.gui.widgets; + +import net.minecraft.item.Item; +import net.minecraft.item.ItemStack; +import net.minecraft.util.IIcon; + +import net.minecraftforge.fluids.FluidStack; + +import buildcraft.api.tools.IToolPipette; +import org.lwjgl.opengl.GL11; + +import forestry.core.gui.ContainerForestry; +import forestry.core.gui.ContainerLiquidTanks; +import forestry.core.gui.WidgetManager; +import forestry.core.gui.tooltips.ToolTip; +import forestry.core.proxy.Proxies; +import forestry.core.render.SpriteSheet; +import forestry.core.utils.ForestryTank; + +/** + * Slot for liquid tanks + */ +public class TankWidget extends Widget { + + protected int overlayTexX = 176; + protected int overlayTexY = 0; + protected int slot = 0; + + public TankWidget(WidgetManager manager, int xPos, int yPos, int slot) { + super(manager, xPos, yPos); + this.slot = slot; + this.height = 58; + } + + public TankWidget setOverlayOrigin(int x, int y) { + overlayTexX = x; + overlayTexY = y; + return this; + } + + public ForestryTank getTank() { + return ((ContainerForestry) manager.gui.inventorySlots).getTank(slot); + } + + @Override + public void draw(int startX, int startY) { + if (getTank() == null) + return; + + FluidStack contents = getTank().getFluid(); + if (contents == null || contents.amount <= 0) + return; + IIcon liquidIcon = contents.getFluid().getIcon(contents); + if (liquidIcon == null) + return; + int squaled = (contents.amount * height) / getTank().getCapacity(); + + Proxies.common.bindTexture(SpriteSheet.BLOCKS); + int start = 0; + + GL11.glPushAttrib(GL11.GL_ENABLE_BIT); + GL11.glDisable(GL11.GL_LIGHTING); + GL11.glColor4f(1.0f, 1.0f, 1.0f, 1.0F); + while (true) { + int x = 0; + + if (squaled > 16) { + x = 16; + squaled -= 16; + } else { + x = squaled; + squaled = 0; + } + + manager.gui.drawTexturedModelRectFromIcon(startX + xPos, startY + yPos + height - x - start, liquidIcon, 16, 16 - (16 - x)); + start = start + 16; + + if (x == 0 || squaled == 0) + break; + } + + Proxies.common.bindTexture(manager.gui.textureFile); + manager.gui.drawTexturedModalRect(startX + xPos, startY + yPos, overlayTexX, overlayTexY, 16, 60); + GL11.glPopAttrib(); + } + + @Override + public ToolTip getToolTip() { + ForestryTank tank = getTank(); + if (tank == null) + return null; + return tank.getToolTip(); + } + + @Override + public void handleMouseClick(int mouseX, int mouseY, int mouseButton) { + ItemStack itemstack = manager.minecraft.thePlayer.inventory.getItemStack(); + if (itemstack == null) + return; + + Item held = itemstack.getItem(); + if (held instanceof IToolPipette && manager.gui.inventorySlots instanceof ContainerLiquidTanks) + ((ContainerLiquidTanks) manager.gui.inventorySlots).handlePipetteClick(slot, manager.minecraft.thePlayer); + + } +} diff --git a/forestry_common/core/forestry/core/gui/widgets/Widget.java b/forestry_common/core/forestry/core/gui/widgets/Widget.java new file mode 100755 index 000000000..acce4a26b --- /dev/null +++ b/forestry_common/core/forestry/core/gui/widgets/Widget.java @@ -0,0 +1,78 @@ +/******************************************************************************* + * Copyright 2011-2014 by SirSengir + * + * This work is licensed under a Creative Commons Attribution-NonCommercial-NoDerivs 3.0 Unported License. + * + * To view a copy of this license, visit http://creativecommons.org/licenses/by-nc-nd/3.0/. + ******************************************************************************/ +package forestry.core.gui.widgets; + +import net.minecraft.entity.player.EntityPlayer; + +import forestry.core.gui.WidgetManager; +import forestry.core.gui.tooltips.IToolTipProvider; +import forestry.core.gui.tooltips.ToolTip; +import forestry.core.proxy.Proxies; + +/** + * Basic non-ItemStack slot + */ +public abstract class Widget implements IToolTipProvider { + + protected WidgetManager manager; + protected int xPos; + protected int yPos; + protected int width = 16; + protected int height = 16; + + public Widget(WidgetManager manager, int xPos, int yPos) { + this.manager = manager; + this.xPos = xPos; + this.yPos = yPos; + } + + public int getWidth() { + return width; + } + + public int getHeight() { + return height; + } + + public abstract void draw(int startX, int startY); + + @Override + public ToolTip getToolTip() { + String line = getLegacyTooltip(Proxies.common.getClientInstance().thePlayer); + if (line != null && !line.isEmpty()) { + ToolTip tip = new ToolTip(); + tip.add(line); + return tip; + } + return null; + } + + protected String getLegacyTooltip(EntityPlayer player) { + return null; + } + + // Not fully implemented + @Override + public boolean isToolTipVisible() { + return true; + } + + @Override + public boolean isMouseOver(int mouseX, int mouseY) { + return mouseX >= xPos && mouseX <= xPos + this.width && mouseY >= yPos && mouseY <= yPos + this.height; + } + + public void handleMouseClick(int mouseX, int mouseY, int mouseButton) { + } + + public void handleMouseRelease(int mouseX, int mouseY, int eventType) { + } + + public void handleMouseMove(int mouseX, int mouseY, int mouseButton, long time) { + } +} diff --git a/forestry_common/core/forestry/core/interfaces/IBlockRenderer.java b/forestry_common/core/forestry/core/interfaces/IBlockRenderer.java new file mode 100755 index 000000000..a14a5e254 --- /dev/null +++ b/forestry_common/core/forestry/core/interfaces/IBlockRenderer.java @@ -0,0 +1,16 @@ +/******************************************************************************* + * Copyright 2011-2014 by SirSengir + * + * This work is licensed under a Creative Commons Attribution-NonCommercial-NoDerivs 3.0 Unported License. + * + * To view a copy of this license, visit http://creativecommons.org/licenses/by-nc-nd/3.0/. + ******************************************************************************/ +package forestry.core.interfaces; + +import net.minecraft.tileentity.TileEntity; + +public interface IBlockRenderer { + public void renderTileEntityAt(TileEntity tileentity, double d, double d1, double d2, float f); + + public void inventoryRender(double x, double y, double z, float f, float f1); +} diff --git a/forestry_common/core/forestry/core/interfaces/IClimatised.java b/forestry_common/core/forestry/core/interfaces/IClimatised.java new file mode 100755 index 000000000..341832b79 --- /dev/null +++ b/forestry_common/core/forestry/core/interfaces/IClimatised.java @@ -0,0 +1,23 @@ +/******************************************************************************* + * Copyright 2011-2014 by SirSengir + * + * This work is licensed under a Creative Commons Attribution-NonCommercial-NoDerivs 3.0 Unported License. + * + * To view a copy of this license, visit http://creativecommons.org/licenses/by-nc-nd/3.0/. + ******************************************************************************/ +package forestry.core.interfaces; + +import forestry.api.core.EnumHumidity; +import forestry.api.core.EnumTemperature; + +public interface IClimatised { + boolean isClimatized(); + + EnumTemperature getTemperature(); + + EnumHumidity getHumidity(); + + float getExactTemperature(); + + float getExactHumidity(); +} diff --git a/forestry_common/core/forestry/core/interfaces/IContainerCrafting.java b/forestry_common/core/forestry/core/interfaces/IContainerCrafting.java new file mode 100755 index 000000000..08363027c --- /dev/null +++ b/forestry_common/core/forestry/core/interfaces/IContainerCrafting.java @@ -0,0 +1,14 @@ +/******************************************************************************* + * Copyright 2011-2014 by SirSengir + * + * This work is licensed under a Creative Commons Attribution-NonCommercial-NoDerivs 3.0 Unported License. + * + * To view a copy of this license, visit http://creativecommons.org/licenses/by-nc-nd/3.0/. + ******************************************************************************/ +package forestry.core.interfaces; + +import net.minecraft.inventory.IInventory; + +public interface IContainerCrafting { + void onCraftMatrixChanged(IInventory iinventory, int slot); +} diff --git a/forestry_common/core/forestry/core/interfaces/ICrafter.java b/forestry_common/core/forestry/core/interfaces/ICrafter.java new file mode 100755 index 000000000..cf4acdefe --- /dev/null +++ b/forestry_common/core/forestry/core/interfaces/ICrafter.java @@ -0,0 +1,21 @@ +/******************************************************************************* + * Copyright 2011-2014 by SirSengir + * + * This work is licensed under a Creative Commons Attribution-NonCommercial-NoDerivs 3.0 Unported License. + * + * To view a copy of this license, visit http://creativecommons.org/licenses/by-nc-nd/3.0/. + ******************************************************************************/ +package forestry.core.interfaces; + +import net.minecraft.entity.player.EntityPlayer; +import net.minecraft.item.ItemStack; + +public interface ICrafter { + + ItemStack takenFromSlot(int slotIndex, boolean consumeRecipe, EntityPlayer player); + + ItemStack getResult(); + + boolean canTakeStack(int slotIndex); + +} diff --git a/forestry_common/core/forestry/core/interfaces/ICraftingPlan.java b/forestry_common/core/forestry/core/interfaces/ICraftingPlan.java new file mode 100755 index 000000000..eea3ea6f8 --- /dev/null +++ b/forestry_common/core/forestry/core/interfaces/ICraftingPlan.java @@ -0,0 +1,14 @@ +/******************************************************************************* + * Copyright 2011-2014 by SirSengir + * + * This work is licensed under a Creative Commons Attribution-NonCommercial-NoDerivs 3.0 Unported License. + * + * To view a copy of this license, visit http://creativecommons.org/licenses/by-nc-nd/3.0/. + ******************************************************************************/ +package forestry.core.interfaces; + +import net.minecraft.item.ItemStack; + +public interface ICraftingPlan { + ItemStack planUsed(ItemStack plan, ItemStack result); +} diff --git a/forestry_common/core/forestry/core/interfaces/IDescriptiveRecipe.java b/forestry_common/core/forestry/core/interfaces/IDescriptiveRecipe.java new file mode 100755 index 000000000..52b8f8646 --- /dev/null +++ b/forestry_common/core/forestry/core/interfaces/IDescriptiveRecipe.java @@ -0,0 +1,19 @@ +/******************************************************************************* + * Copyright 2011-2014 by SirSengir + * + * This work is licensed under a Creative Commons Attribution-NonCommercial-NoDerivs 3.0 Unported License. + * + * To view a copy of this license, visit http://creativecommons.org/licenses/by-nc-nd/3.0/. + ******************************************************************************/ +package forestry.core.interfaces; + +import net.minecraft.item.crafting.IRecipe; + +public interface IDescriptiveRecipe extends IRecipe { + + int getWidth(); + + int getHeight(); + + Object[] getIngredients(); +} diff --git a/forestry_common/core/forestry/core/interfaces/IErrorSource.java b/forestry_common/core/forestry/core/interfaces/IErrorSource.java new file mode 100755 index 000000000..dd8490968 --- /dev/null +++ b/forestry_common/core/forestry/core/interfaces/IErrorSource.java @@ -0,0 +1,18 @@ +/******************************************************************************* + * Copyright 2011-2014 by SirSengir + * + * This work is licensed under a Creative Commons Attribution-NonCommercial-NoDerivs 3.0 Unported License. + * + * To view a copy of this license, visit http://creativecommons.org/licenses/by-nc-nd/3.0/. + ******************************************************************************/ +package forestry.core.interfaces; + +import forestry.core.EnumErrorCode; + +public interface IErrorSource { + + boolean throwsErrors(); + + EnumErrorCode getErrorState(); + +} diff --git a/forestry_common/core/forestry/core/interfaces/IHintSource.java b/forestry_common/core/forestry/core/interfaces/IHintSource.java new file mode 100755 index 000000000..1569740dd --- /dev/null +++ b/forestry_common/core/forestry/core/interfaces/IHintSource.java @@ -0,0 +1,14 @@ +/******************************************************************************* + * Copyright 2011-2014 by SirSengir + * + * This work is licensed under a Creative Commons Attribution-NonCommercial-NoDerivs 3.0 Unported License. + * + * To view a copy of this license, visit http://creativecommons.org/licenses/by-nc-nd/3.0/. + ******************************************************************************/ +package forestry.core.interfaces; + +public interface IHintSource { + boolean hasHints(); + + String[] getHints(); +} diff --git a/forestry_common/core/forestry/core/interfaces/IInventoriedItem.java b/forestry_common/core/forestry/core/interfaces/IInventoriedItem.java new file mode 100755 index 000000000..b0ce2317c --- /dev/null +++ b/forestry_common/core/forestry/core/interfaces/IInventoriedItem.java @@ -0,0 +1,12 @@ +/******************************************************************************* + * Copyright 2011-2014 by SirSengir + * + * This work is licensed under a Creative Commons Attribution-NonCommercial-NoDerivs 3.0 Unported License. + * + * To view a copy of this license, visit http://creativecommons.org/licenses/by-nc-nd/3.0/. + ******************************************************************************/ +package forestry.core.interfaces; + +public interface IInventoriedItem { + +} diff --git a/forestry_common/core/forestry/core/interfaces/ILiquidTankContainer.java b/forestry_common/core/forestry/core/interfaces/ILiquidTankContainer.java new file mode 100755 index 000000000..7c0262994 --- /dev/null +++ b/forestry_common/core/forestry/core/interfaces/ILiquidTankContainer.java @@ -0,0 +1,18 @@ +/******************************************************************************* + * Copyright 2011-2014 by SirSengir + * + * This work is licensed under a Creative Commons Attribution-NonCommercial-NoDerivs 3.0 Unported License. + * + * To view a copy of this license, visit http://creativecommons.org/licenses/by-nc-nd/3.0/. + ******************************************************************************/ +package forestry.core.interfaces; + +import net.minecraftforge.fluids.IFluidHandler; + +import forestry.core.utils.ForestryTank; + +public interface ILiquidTankContainer extends IFluidHandler { + + ForestryTank[] getTanks(); + +} diff --git a/forestry_common/core/forestry/core/interfaces/IOreDictionaryHandler.java b/forestry_common/core/forestry/core/interfaces/IOreDictionaryHandler.java new file mode 100755 index 000000000..a68e48940 --- /dev/null +++ b/forestry_common/core/forestry/core/interfaces/IOreDictionaryHandler.java @@ -0,0 +1,14 @@ +/******************************************************************************* + * Copyright 2011-2014 by SirSengir + * + * This work is licensed under a Creative Commons Attribution-NonCommercial-NoDerivs 3.0 Unported License. + * + * To view a copy of this license, visit http://creativecommons.org/licenses/by-nc-nd/3.0/. + ******************************************************************************/ +package forestry.core.interfaces; + +import net.minecraft.item.ItemStack; + +public interface IOreDictionaryHandler { + void onOreRegistration(String name, ItemStack ore); +} diff --git a/forestry_common/core/forestry/core/interfaces/IOwnable.java b/forestry_common/core/forestry/core/interfaces/IOwnable.java new file mode 100755 index 000000000..73b5c1dbf --- /dev/null +++ b/forestry_common/core/forestry/core/interfaces/IOwnable.java @@ -0,0 +1,33 @@ +/******************************************************************************* + * Copyright 2011-2014 by SirSengir + * + * This work is licensed under a Creative Commons Attribution-NonCommercial-NoDerivs 3.0 Unported License. + * + * To view a copy of this license, visit http://creativecommons.org/licenses/by-nc-nd/3.0/. + ******************************************************************************/ +package forestry.core.interfaces; + +import net.minecraft.entity.player.EntityPlayer; + +import forestry.core.utils.EnumAccess; + +public interface IOwnable { + + boolean isOwnable(); + + boolean isOwned(); + + String getOwnerName(); + + void setOwner(EntityPlayer player); + + boolean isOwner(EntityPlayer player); + + boolean switchAccessRule(EntityPlayer player); + + EnumAccess getAccess(); + + boolean allowsRemoval(EntityPlayer player); + + boolean allowsInteraction(EntityPlayer player); +} diff --git a/forestry_common/core/forestry/core/interfaces/IPacketHandler.java b/forestry_common/core/forestry/core/interfaces/IPacketHandler.java new file mode 100755 index 000000000..d2237d051 --- /dev/null +++ b/forestry_common/core/forestry/core/interfaces/IPacketHandler.java @@ -0,0 +1,18 @@ +/******************************************************************************* + * Copyright 2011-2014 by SirSengir + * + * This work is licensed under a Creative Commons Attribution-NonCommercial-NoDerivs 3.0 Unported License. + * + * To view a copy of this license, visit http://creativecommons.org/licenses/by-nc-nd/3.0/. + ******************************************************************************/ +package forestry.core.interfaces; + +import java.io.DataInputStream; + +import net.minecraft.entity.player.EntityPlayer; + +public interface IPacketHandler { + + void onPacketData(int packetID, DataInputStream data, EntityPlayer player); + +} diff --git a/forestry_common/core/forestry/core/interfaces/IPickupHandler.java b/forestry_common/core/forestry/core/interfaces/IPickupHandler.java new file mode 100755 index 000000000..30b710a71 --- /dev/null +++ b/forestry_common/core/forestry/core/interfaces/IPickupHandler.java @@ -0,0 +1,17 @@ +/******************************************************************************* + * Copyright 2011-2014 by SirSengir + * + * This work is licensed under a Creative Commons Attribution-NonCommercial-NoDerivs 3.0 Unported License. + * + * To view a copy of this license, visit http://creativecommons.org/licenses/by-nc-nd/3.0/. + ******************************************************************************/ +package forestry.core.interfaces; + +import net.minecraft.entity.item.EntityItem; +import net.minecraft.entity.player.EntityPlayer; + +public interface IPickupHandler { + + boolean onItemPickup(EntityPlayer entityPlayer, EntityItem item); + +} diff --git a/forestry_common/core/forestry/core/interfaces/IPowerHandler.java b/forestry_common/core/forestry/core/interfaces/IPowerHandler.java new file mode 100755 index 000000000..d540d9ecc --- /dev/null +++ b/forestry_common/core/forestry/core/interfaces/IPowerHandler.java @@ -0,0 +1,15 @@ +/******************************************************************************* + * Copyright 2011-2014 by SirSengir + * + * This work is licensed under a Creative Commons Attribution-NonCommercial-NoDerivs 3.0 Unported License. + * + * To view a copy of this license, visit http://creativecommons.org/licenses/by-nc-nd/3.0/. + ******************************************************************************/ +package forestry.core.interfaces; + +import buildcraft.api.power.IPowerReceptor; +import buildcraft.api.power.PowerHandler; + +public interface IPowerHandler extends IPowerReceptor { + PowerHandler getPowerHandler(); +} diff --git a/forestry_common/core/forestry/core/interfaces/IRenderableMachine.java b/forestry_common/core/forestry/core/interfaces/IRenderableMachine.java new file mode 100755 index 000000000..7ce9f9d8d --- /dev/null +++ b/forestry_common/core/forestry/core/interfaces/IRenderableMachine.java @@ -0,0 +1,22 @@ +/******************************************************************************* + * Copyright 2011-2014 by SirSengir + * + * This work is licensed under a Creative Commons Attribution-NonCommercial-NoDerivs 3.0 Unported License. + * + * To view a copy of this license, visit http://creativecommons.org/licenses/by-nc-nd/3.0/. + ******************************************************************************/ +package forestry.core.interfaces; + +import net.minecraftforge.common.util.ForgeDirection; + +import forestry.core.utils.EnumTankLevel; + +public interface IRenderableMachine { + + ForgeDirection getOrientation(); + + EnumTankLevel getPrimaryLevel(); + + EnumTankLevel getSecondaryLevel(); + +} diff --git a/forestry_common/core/forestry/core/interfaces/IResupplyHandler.java b/forestry_common/core/forestry/core/interfaces/IResupplyHandler.java new file mode 100755 index 000000000..82c72d15b --- /dev/null +++ b/forestry_common/core/forestry/core/interfaces/IResupplyHandler.java @@ -0,0 +1,16 @@ +/******************************************************************************* + * Copyright 2011-2014 by SirSengir + * + * This work is licensed under a Creative Commons Attribution-NonCommercial-NoDerivs 3.0 Unported License. + * + * To view a copy of this license, visit http://creativecommons.org/licenses/by-nc-nd/3.0/. + ******************************************************************************/ +package forestry.core.interfaces; + +import net.minecraft.entity.player.EntityPlayer; + +public interface IResupplyHandler { + + void resupply(EntityPlayer player); + +} diff --git a/forestry_common/core/forestry/core/interfaces/ISaveEventHandler.java b/forestry_common/core/forestry/core/interfaces/ISaveEventHandler.java new file mode 100755 index 000000000..58d4a8e22 --- /dev/null +++ b/forestry_common/core/forestry/core/interfaces/ISaveEventHandler.java @@ -0,0 +1,20 @@ +/******************************************************************************* + * Copyright 2011-2014 by SirSengir + * + * This work is licensed under a Creative Commons Attribution-NonCommercial-NoDerivs 3.0 Unported License. + * + * To view a copy of this license, visit http://creativecommons.org/licenses/by-nc-nd/3.0/. + ******************************************************************************/ +package forestry.core.interfaces; + +import net.minecraft.world.World; + +public interface ISaveEventHandler { + + void onWorldLoad(World world); + + void onWorldUnload(World world); + + void onWorldSave(World world); + +} diff --git a/forestry_common/core/forestry/core/interfaces/ISocketable.java b/forestry_common/core/forestry/core/interfaces/ISocketable.java new file mode 100755 index 000000000..f4e549c6c --- /dev/null +++ b/forestry_common/core/forestry/core/interfaces/ISocketable.java @@ -0,0 +1,18 @@ +/******************************************************************************* + * Copyright 2011-2014 by SirSengir + * + * This work is licensed under a Creative Commons Attribution-NonCommercial-NoDerivs 3.0 Unported License. + * + * To view a copy of this license, visit http://creativecommons.org/licenses/by-nc-nd/3.0/. + ******************************************************************************/ +package forestry.core.interfaces; + +import net.minecraft.item.ItemStack; + +public interface ISocketable { + int getSocketCount(); + + ItemStack getSocket(int slot); + + void setSocket(int slot, ItemStack stack); +} diff --git a/forestry_common/core/forestry/core/inventory/ITileFilter.java b/forestry_common/core/forestry/core/inventory/ITileFilter.java new file mode 100755 index 000000000..5d53645b7 --- /dev/null +++ b/forestry_common/core/forestry/core/inventory/ITileFilter.java @@ -0,0 +1,20 @@ +/******************************************************************************* + * Copyright 2011-2014 by SirSengir + * + * This work is licensed under a Creative Commons Attribution-NonCommercial-NoDerivs 3.0 Unported License. + * + * To view a copy of this license, visit http://creativecommons.org/licenses/by-nc-nd/3.0/. + ******************************************************************************/ +package forestry.core.inventory; + +import net.minecraft.tileentity.TileEntity; + +/** + * + * @author CovertJaguar + */ +public interface ITileFilter { + + public boolean matches(TileEntity tile); + +} diff --git a/forestry_common/core/forestry/core/inventory/InvTools.java b/forestry_common/core/forestry/core/inventory/InvTools.java new file mode 100755 index 000000000..aa54d67f3 --- /dev/null +++ b/forestry_common/core/forestry/core/inventory/InvTools.java @@ -0,0 +1,796 @@ +/******************************************************************************* + * Copyright 2011-2014 by SirSengir + * + * This work is licensed under a Creative Commons Attribution-NonCommercial-NoDerivs 3.0 Unported License. + * + * To view a copy of this license, visit http://creativecommons.org/licenses/by-nc-nd/3.0/. + ******************************************************************************/ +package forestry.core.inventory; + +import java.util.ArrayList; +import java.util.Collection; +import java.util.LinkedList; +import java.util.List; +import java.util.Map; +import java.util.TreeMap; + +import net.minecraft.block.Block; +import net.minecraft.entity.item.EntityItem; +import net.minecraft.inventory.IInventory; +import net.minecraft.inventory.ISidedInventory; +import net.minecraft.item.ItemStack; +import net.minecraft.nbt.NBTTagCompound; +import net.minecraft.nbt.NBTTagList; +import net.minecraft.tileentity.TileEntity; +import net.minecraft.tileentity.TileEntityChest; +import net.minecraft.world.IBlockAccess; +import net.minecraft.world.World; + +import net.minecraftforge.common.util.ForgeDirection; +import net.minecraftforge.oredict.OreDictionary; + +import buildcraft.api.inventory.ISpecialInventory; +import buildcraft.api.transport.PipeManager; + +import forestry.core.inventory.filters.ArrayStackFilter; +import forestry.core.inventory.filters.IStackFilter; +import forestry.core.inventory.filters.InvertedStackFilter; +import forestry.core.inventory.filters.StackFilter; +import forestry.core.inventory.manipulators.InventoryManipulator; +import forestry.core.inventory.wrappers.ChestWrapper; +import forestry.core.inventory.wrappers.IInvSlot; +import forestry.core.inventory.wrappers.InventoryIterator; +import forestry.core.inventory.wrappers.InventoryMapper; +import forestry.core.inventory.wrappers.SidedInventoryMapper; +import forestry.core.inventory.wrappers.SpecialInventoryMapper; +import forestry.core.utils.PlainInventory; + +public abstract class InvTools { + + /*private static final String TAG_ID = "id"; + private static final String TAG_SIZE = "stackSize"; + private static final String TAG_DAMAGE = "Damage"; + private static final String TAG_COUNT = "Count";*/ + private static final String TAG_SLOT = "Slot"; + + public static int getXOnSide(int x, ForgeDirection side) { + return x + side.offsetX; + } + + public static int getYOnSide(int y, ForgeDirection side) { + return y + side.offsetY; + } + + public static int getZOnSide(int z, ForgeDirection side) { + return z + side.offsetZ; + } + + public static boolean blockExistsOnSide(World world, int x, int y, int z, ForgeDirection side) { + return world.blockExists(getXOnSide(x, side), getYOnSide(y, side), getZOnSide(z, side)); + } + + public static int getBlockMetadataOnSide(IBlockAccess world, int i, int j, int k, ForgeDirection side) { + return world.getBlockMetadata(getXOnSide(i, side), getYOnSide(j, side), getZOnSide(k, side)); + } + + public static Block getBlockOnSide(IBlockAccess world, int x, int y, int z, ForgeDirection side) { + return world.getBlock(getXOnSide(x, side), getYOnSide(y, side), getZOnSide(z, side)); + } + + public static TileEntity getBlockTileEntityOnSide(World world, int x, int y, int z, ForgeDirection side) { + int sx = getXOnSide(x, side); + int sy = getYOnSide(y, side); + int sz = getZOnSide(z, side); + if (world.blockExists(sx, sy, sz)) + return world.getTileEntity(sx, sy, sz); + return null; + } + + public static TileEntity getBlockTileEntityOnSide(IBlockAccess world, int x, int y, int z, ForgeDirection side) { + int sx = getXOnSide(x, side); + int sy = getYOnSide(y, side); + int sz = getZOnSide(z, side); + return world.getTileEntity(sx, sy, sz); + } + + public static List getAdjacentInventories(World world, int i, int j, int k) { + return getAdjacentInventories(world, i, j, k, null); + } + + public static List getAdjacentInventories(World world, int i, int j, int k, Class type) { + List list = new ArrayList(5); + for (int side = 0; side < 6; side++) { + IInventory inv = getInventoryFromSide(world, i, j, k, ForgeDirection.getOrientation(side), type, null); + if (inv != null) + list.add(inv); + } + return list; + } + + public static Map getAdjacentInventoryMap(World world, int i, int j, int k) { + return getAdjacentInventoryMap(world, i, j, k, null); + } + + public static Map getAdjacentInventoryMap(World world, int i, int j, int k, Class type) { + Map map = new TreeMap(); + for (int side = 0; side < 6; side++) { + IInventory inv = getInventoryFromSide(world, i, j, k, ForgeDirection.getOrientation(side), type, null); + if (inv != null) + map.put(side, inv); + } + return map; + } + + public static IInventory getInventoryFromSide(World world, int x, int y, int z, ForgeDirection side, final Class type, final Class exclude) { + return getInventoryFromSide(world, x, y, z, side, new ITileFilter() { + @Override + public boolean matches(TileEntity tile) { + if (type != null && !type.isAssignableFrom(tile.getClass())) + return false; + if (exclude != null && exclude.isAssignableFrom(tile.getClass())) + return false; + return true; + } + }); + } + + public static IInventory getInventoryFromSide(World world, int x, int y, int z, ForgeDirection side, ITileFilter filter) { + TileEntity tile = getBlockTileEntityOnSide(world, x, y, z, side); + if (tile == null || !(tile instanceof IInventory) || !filter.matches(tile)) + return null; + return getInventoryFromTile(tile, side.getOpposite()); + } + + public static IInventory getInventoryFromTile(TileEntity tile, ForgeDirection side) { + if (tile == null || !(tile instanceof IInventory)) + return null; + + if (!PipeManager.canExtractItems(null, tile.getWorldObj(), tile.xCoord, tile.yCoord, tile.zCoord)) + return null; + + if (tile instanceof TileEntityChest) { + TileEntityChest chest = (TileEntityChest) tile; + return new ChestWrapper(chest); + } + return getInventory((IInventory) tile, side); + } + + public static IInventory getInventory(IInventory inv, ForgeDirection side) { + if (inv == null) + return null; + + if (inv instanceof ISpecialInventory) + inv = new SpecialInventoryMapper((ISpecialInventory) inv, side); + else if (inv instanceof ISidedInventory) + inv = new SidedInventoryMapper((ISidedInventory) inv, side); + return inv; + } + + public static int[] buildSlotArray(int start, int size) { + int[] slots = new int[size]; + for (int i = 0; i < size; i++) { + slots[i] = start + i; + } + return slots; + } + + /*public static void addItemToolTip(ItemStack stack, String tag, String msg) { + NBTTagCompound nbt = getItemData(stack); + NBTTagCompound display = nbt.getCompoundTag("display"); + nbt.setTag("display", display); + NBTTagList lore = display.getTagList("Lore", 8); // 8 = String + display.setTag("Lore", lore); + //lore.appendTag(new NBTTagString(tag, msg)); + lore.appendTag(new NBTTagString(msg)); + }*/ + + public static NBTTagCompound getItemData(ItemStack stack) { + NBTTagCompound nbt = stack.getTagCompound(); + if (nbt == null) { + nbt = new NBTTagCompound(); + stack.setTagCompound(nbt); + } + return nbt; + } + + public static ItemStack depleteItem(ItemStack stack) { + if (stack.stackSize == 1) + return stack.getItem().getContainerItem(stack); + else { + stack.splitStack(1); + return stack; + } + } + + public static ItemStack damageItem(ItemStack stack, int damage) { + if (!stack.isItemStackDamageable()) + return stack; + int curDamage = stack.getItemDamage(); + curDamage += damage; + stack.setItemDamage(curDamage); + if (stack.getItemDamage() > stack.getMaxDamage()) { + stack.stackSize--; + stack.setItemDamage(0); + } + if (stack.stackSize <= 0) + stack = null; + return stack; + } + + public static void dropItem(ItemStack stack, World world, double x, double y, double z) { + if (stack == null || stack.stackSize < 1) + return; + EntityItem entityItem = new EntityItem(world, x, y + 1.5, z, stack); + entityItem.delayBeforeCanPickup = 10; + world.spawnEntityInWorld(entityItem); + } + + public static boolean isInventoryEmpty(IInventory inv, ForgeDirection side) { + return isInventoryEmpty(getInventory(inv, side)); + } + + public static boolean isInventoryEmpty(IInventory inv) { + ItemStack stack = null; + for (IInvSlot slot : InventoryIterator.getIterable(inv)) { + stack = slot.getStackInSlot(); + if (stack != null) + break; + } + return stack == null; + } + + public static boolean isInventoryFull(IInventory inv, ForgeDirection side) { + return isInventoryFull(getInventory(inv, side)); + } + + public static boolean isInventoryFull(IInventory inv) { + ItemStack stack = null; + for (IInvSlot slot : InventoryIterator.getIterable(inv)) { + stack = slot.getStackInSlot(); + if (stack == null) + break; + } + return stack != null; + } + + /** + * Counts the number of items. + * + * @param inv + * @return + */ + public static int countItems(IInventory inv) { + int count = 0; + for (IInvSlot slot : InventoryIterator.getIterable(inv)) { + ItemStack stack = slot.getStackInSlot(); + if (stack != null) + count += stack.stackSize; + } + return count; + } + + public static int countItems(IInventory inv, IStackFilter filter) { + int count = 0; + for (IInvSlot slot : InventoryIterator.getIterable(inv)) { + ItemStack stack = slot.getStackInSlot(); + if (stack != null && filter.matches(stack)) + count += stack.stackSize; + } + return count; + } + + public static boolean numItemsMoreThan(IInventory inv, int amount) { + int count = 0; + for (IInvSlot slot : InventoryIterator.getIterable(inv)) { + ItemStack stack = slot.getStackInSlot(); + if (stack != null) + count += stack.stackSize; + if (count >= amount) + return true; + } + return false; + } + + /** + * Counts the number of items that match the filter. Ignores + * ISpecialInventory and ISidedInventory, and bypasses InventoryMapper to + * count from the base IInventory. + * + * @param inv + * @param filters + * @return + */ + public static int countItems(IInventory inv, ItemStack... filters) { + if (inv instanceof InventoryMapper) + inv = ((InventoryMapper) inv).getBaseInventory(); + boolean hasFilter = false; + for (ItemStack filter : filters) { + if (filter != null) { + hasFilter = true; + break; + } + } + + if (!hasFilter) + return countItems(inv); + + int count = 0; + ItemStack stack = null; + for (int slot = 0; slot < inv.getSizeInventory(); slot++) { + stack = inv.getStackInSlot(slot); + if (stack != null) + for (ItemStack filter : filters) { + if (filter != null && isItemEqual(stack, filter)) { + count += stack.stackSize; + break; + } + } + } + return count; + } + + public static int countItems(Collection inventories, ItemStack... filter) { + int count = 0; + for (IInventory inv : inventories) { + count += InvTools.countItems(inv, filter); + } + return count; + } + + /** + * Returns true if the inventory contains the specified item. + * + * @param inv The IIinventory to check + * @param item The ItemStack to look for + * @return true is exists + */ + public static boolean containsItem(IInventory inv, ItemStack item) { + return countItems(inv, item) > 0; + } + + /** + * Returns a map backed by an + * ItemStackMap that lists the total number of each type of + * item in the inventory. + * + * @param inv The IInventory to generate the manifest for + * @return A Map that lists how many of each item is in * * * + * the IInventory + * @see ItemStackMap + */ + public static Map getManifest(IInventory inv) { + Map manifest = new ItemStackMap(); + for (int i = 0; i < inv.getSizeInventory(); i++) { + ItemStack slot = inv.getStackInSlot(i); + if (slot != null) { + Integer count = manifest.get(slot); + if (count == null) + count = 0; + count += slot.stackSize; + manifest.put(slot, count); + } + } + return manifest; + } + + /** + * Attempts to move a single item from one inventory to another. + * + * @param source + * @param dest + * @return null if nothing was moved, the stack moved otherwise + */ + public static ItemStack moveOneItem(IInventory source, IInventory dest) { + return moveOneItem(source, dest, StackFilter.ALL); + } + + /** + * Attempts to move a single item from one inventory to another. + * + * @param source + * @param dest + * @param filer an ItemStack[] to match against + * @return null if nothing was moved, the stack moved otherwise + */ + public static ItemStack moveOneItem(IInventory source, IInventory dest, ItemStack... filters) { + return moveOneItem(source, dest, new ArrayStackFilter(filters)); + } + + /** + * Attempts to move a single item from one inventory to another. + * + * @param source + * @param dest + * @param filer an IItemType to match against + * @return null if nothing was moved, the stack moved otherwise + */ + public static ItemStack moveOneItem(IInventory source, IInventory dest, IStackFilter filter) { + InventoryManipulator imSource = InventoryManipulator.get(source); + return imSource.moveItem(dest, filter); + } + + /** + * Attempts to move one item from a collection of inventories. + * + * @param sources + * @param dest + * @param filters + * @return + */ + public static ItemStack moveOneItem(Collection sources, IInventory dest, ItemStack... filters) { + for (IInventory inv : sources) { + ItemStack moved = InvTools.moveOneItem(inv, dest, filters); + if (moved != null) + return moved; + } + return null; + } + + /** + * Attempts to move one item from a collection of inventories. + * + * @param sources + * @param dest + * @param filters + * @return + */ + public static ItemStack moveOneItem(Collection sources, IInventory dest, IStackFilter filter) { + for (IInventory inv : sources) { + ItemStack moved = InvTools.moveOneItem(inv, dest, filter); + if (moved != null) + return moved; + } + return null; + } + + /** + * Attempts to move one item to a collection of inventories. + * + * @param sources + * @param dest + * @param filters + * @return + */ + public static ItemStack moveOneItem(IInventory source, Collection destinations, ItemStack... filters) { + for (IInventory dest : destinations) { + ItemStack moved = InvTools.moveOneItem(source, dest, filters); + if (moved != null) + return moved; + } + return null; + } + + /** + * Attempts to move a single item from one inventory to another. + * + * Will not move any items in the filter. + * + * @param source + * @param dest + * @param filer an ItemStack[] to exclude + * @return null if nothing was moved, the stack moved otherwise + */ + public static ItemStack moveOneItemExcept(IInventory source, IInventory dest, ItemStack... filters) { + return moveOneItem(source, dest, new InvertedStackFilter(new ArrayStackFilter(filters))); + } + + /** + * Attempts to move one item from a collection of inventories. + * + * @param sources + * @param dest + * @param filters + * @return + */ + public static ItemStack moveOneItemExcept(Collection sources, IInventory dest, ItemStack... filters) { + for (IInventory inv : sources) { + ItemStack moved = InvTools.moveOneItemExcept(inv, dest, filters); + if (moved != null) + return moved; + } + return null; + } + + /** + * Attempts to move one item to a collection of inventories. + * + * @param sources + * @param dest + * @param filters + * @return + */ + public static ItemStack moveOneItemExcept(IInventory source, Collection destinations, ItemStack... filters) { + for (IInventory dest : destinations) { + ItemStack moved = InvTools.moveOneItemExcept(source, dest, filters); + if (moved != null) + return moved; + } + return null; + } + + public static boolean isWildcard(ItemStack stack) { + return isWildcard(stack.getItemDamage()); + } + + public static boolean isWildcard(int damage) { + return damage == -1 || damage == OreDictionary.WILDCARD_VALUE; + } + + /** + * A more robust item comparison function. + * + * Compares stackSize as well. + * + * Two null stacks will return true, unlike the other functions. + * + * This function is primarily intended to be used to track changes to an + * ItemStack. + * + * @param a An ItemStack + * @param b An ItemStack + * @return True if equal + */ + public static boolean isItemEqualStrict(ItemStack a, ItemStack b) { + if (a == null && b == null) + return true; + if (a == null || b == null) + return false; + if (a.getItem() != b.getItem()) + return false; + if (a.stackSize != b.stackSize) + return false; + if (a.getItemDamage() != b.getItemDamage()) + return false; + if (a.stackTagCompound != null && !a.stackTagCompound.equals(b.stackTagCompound)) + return false; + return true; + } + + /** + * A more robust item comparison function. + * + * Compares stackSize as well. + * + * Two null stacks will return true, unlike the other functions. + * + * This function is primarily intended to be used to track changes to an + * ItemStack. + * + * @param a An ItemStack + * @param b An ItemStack + * @return True if equal + */ + public static boolean isItemEqualSemiStrict(ItemStack a, ItemStack b) { + if (a == null && b == null) + return true; + if (a == null || b == null) + return false; + if (a.getItem() != b.getItem()) + return false; + if (a.getItemDamage() != b.getItemDamage()) + return false; + if (a.stackTagCompound != null && !a.stackTagCompound.equals(b.stackTagCompound)) + return false; + return true; + } + + /** + * A more robust item comparison function. Supports items with damage = -1 + * matching any sub-type. + * + * @param a An ItemStack + * @param b An ItemStack + * @return True if equal + */ + public static boolean isItemEqual(ItemStack a, ItemStack b) { + return isItemEqual(a, b, true, true); + } + + /** + * A more robust item comparison function. Supports items with damage = -1 + * matching any sub-type. + * + * @param a An ItemStack + * @param b An ItemStack + * @return True if equal + */ + public static boolean isItemEqualIgnoreNBT(ItemStack a, ItemStack b) { + return isItemEqual(a, b, true, false); + } + + public static boolean isItemEqual(final ItemStack a, final ItemStack b, final boolean matchDamage, final boolean matchNBT) { + if (a == null || b == null) + return false; + if (a.getItem() != b.getItem()) + return false; + if (matchNBT && !ItemStack.areItemStackTagsEqual(a, b)) + return false; + if (matchDamage && a.getHasSubtypes()) { + if (isWildcard(a) || isWildcard(b)) + return true; + if (a.getItemDamage() != b.getItemDamage()) + return false; + } + return true; + } + + /** + * Returns true if the item is equal to any one of several possible matches. + * + * @param stack + * @param matches + * @return + */ + public static boolean isItemEqual(ItemStack stack, ItemStack... matches) { + for (ItemStack match : matches) { + if (isItemEqual(stack, match)) + return true; + } + return false; + } + + /** + * Returns true if the item is equal to any one of several possible matches. + * + * @param stack + * @param matches + * @return + */ + public static boolean isItemEqual(ItemStack stack, Collection matches) { + for (ItemStack match : matches) { + if (isItemEqual(stack, match)) + return true; + } + return false; + } + + /** + * Places an ItemStack in a destination IInventory. Will attempt to move as + * much of the stack as possible, returning any remainder. + * + * @param stack The ItemStack to put in the inventory. + * @param dest The destination IInventory. + * @return Null if itemStack was completely moved, a new itemStack with + * remaining stackSize if part or none of the stack was moved. + */ + public static ItemStack moveItemStack(ItemStack stack, IInventory dest) { + InventoryManipulator im = InventoryManipulator.get(dest); + return im.addStack(stack); + } + + /** + * Checks if there is room for the ItemStack in the inventory. + * + * @param stack The ItemStack + * @param dest The IInventory + * @return true if room for stack + */ + public static boolean isRoomForStack(ItemStack stack, IInventory dest) { + if (stack == null || dest == null) + return false; + InventoryManipulator im = InventoryManipulator.get(dest); + return im.canAddStack(stack); + } + + /** + * Removes a up to numItems worth of items from the inventory, not caring + * about what the items are. + * + * @param inv + * @param numItems + * @return + */ + public static ItemStack[] removeItems(IInventory inv, int numItems) { + if (inv instanceof ISpecialInventory) + return ((ISpecialInventory) inv).extractItem(true, ForgeDirection.UNKNOWN, numItems); + PlainInventory output = new PlainInventory(27, "temp"); + for (int i = 0; i < inv.getSizeInventory(); i++) { + if (numItems <= 0) + break; + ItemStack slot = inv.getStackInSlot(i); + if (slot == null) + continue; + ItemStack removed = inv.decrStackSize(i, numItems); + numItems -= removed.stackSize; + ItemStack remainder = moveItemStack(removed, output); + if (remainder != null) { + moveItemStack(remainder, inv); + numItems += remainder.stackSize; + break; + } + } + + List list = new LinkedList(); + for (ItemStack stack : output.getContents()) { + if (stack != null) + list.add(stack); + } + return list.toArray(new ItemStack[0]); + } + + /** + * Removes and returns a single item from the inventory. + * + * @param inv The inventory + * @return An ItemStack + */ + public static ItemStack removeOneItem(IInventory inv) { + return removeOneItem(inv, StackFilter.ALL); + } + + /** + * Removes and returns a single item from the inventory that matches the + * filter. + * + * @param inv The inventory + * @param filter ItemStack to match against + * @return An ItemStack + */ + public static ItemStack removeOneItem(IInventory inv, ItemStack... filter) { + return removeOneItem(inv, new ArrayStackFilter(filter)); + } + + /** + * Removes and returns a single item from the inventory that matches the + * filter. + * + * @param inv The inventory + * @param filter EnumItemType to match against + * @return An ItemStack + */ + public static ItemStack removeOneItem(IInventory inv, IStackFilter filter) { + InventoryManipulator im = InventoryManipulator.get(inv); + return im.removeItem(filter); + } + + /** + * Removes and returns a single item from the inventory that matches the + * filter. + * + * @param inv The inventory + * @param filter EnumItemType to match against + * @return An ItemStack + */ + public static ItemStack removeOneItem(Collection invs, IStackFilter filter) { + for (IInventory inv : invs) { + ItemStack stack = removeOneItem(inv, filter); + if (stack != null) + return stack; + } + return null; + } + + public static void writeInvToNBT(IInventory inv, String tag, NBTTagCompound data) { + NBTTagList list = new NBTTagList(); + for (byte slot = 0; slot < inv.getSizeInventory(); slot++) { + ItemStack stack = inv.getStackInSlot(slot); + if (stack != null) { + NBTTagCompound itemTag = new NBTTagCompound(); + itemTag.setByte(TAG_SLOT, slot); + writeItemToNBT(stack, itemTag); + list.appendTag(itemTag); + } + } + data.setTag(tag, list); + } + + public static void readInvFromNBT(IInventory inv, String tag, NBTTagCompound data) { + NBTTagList list = data.getTagList(tag, 10); + for (byte entry = 0; entry < list.tagCount(); entry++) { + NBTTagCompound itemTag = list.getCompoundTagAt(entry); + int slot = itemTag.getByte(TAG_SLOT); + if (slot >= 0 && slot < inv.getSizeInventory()) { + ItemStack stack = ItemStack.loadItemStackFromNBT(itemTag); + inv.setInventorySlotContents(slot, stack); + } + } + } + + public static void writeItemToNBT(ItemStack stack, NBTTagCompound data) { + if (stack == null || stack.stackSize <= 0) + return; + if (stack.stackSize > 127) + stack.stackSize = 127; + stack.writeToNBT(data); + } +} diff --git a/forestry_common/core/forestry/core/inventory/InventoryConcatenator.java b/forestry_common/core/forestry/core/inventory/InventoryConcatenator.java new file mode 100755 index 000000000..bec307dc0 --- /dev/null +++ b/forestry_common/core/forestry/core/inventory/InventoryConcatenator.java @@ -0,0 +1,103 @@ +/******************************************************************************* + * Copyright 2011-2014 by SirSengir + * + * This work is licensed under a Creative Commons Attribution-NonCommercial-NoDerivs 3.0 Unported License. + * + * To view a copy of this license, visit http://creativecommons.org/licenses/by-nc-nd/3.0/. + ******************************************************************************/ +package forestry.core.inventory; + +import java.util.ArrayList; +import java.util.List; + +import net.minecraft.entity.player.EntityPlayer; +import net.minecraft.inventory.IInventory; +import net.minecraft.item.ItemStack; + +/** + * Allows you to deal with multiple inventories through a single interface. + * + * @author CovertJaguar + */ +public class InventoryConcatenator implements IInventory { + + private final List slotMap = new ArrayList(); + private final List invMap = new ArrayList(); + + private InventoryConcatenator() { + } + + public static InventoryConcatenator make() { + return new InventoryConcatenator(); + } + + public InventoryConcatenator add(IInventory inv) { + for (int slot = 0; slot < inv.getSizeInventory(); slot++) { + slotMap.add(slot); + invMap.add(inv); + } + return this; + } + + @Override + public int getSizeInventory() { + return slotMap.size(); + } + + @Override + public ItemStack getStackInSlot(int slot) { + return invMap.get(slot).getStackInSlot(slotMap.get(slot)); + } + + @Override + public ItemStack decrStackSize(int slot, int amount) { + return invMap.get(slot).decrStackSize(slotMap.get(slot), amount); + } + + @Override + public ItemStack getStackInSlotOnClosing(int slot) { + return invMap.get(slot).getStackInSlotOnClosing(slotMap.get(slot)); + } + + @Override + public void setInventorySlotContents(int slot, ItemStack stack) { + invMap.get(slot).setInventorySlotContents(slotMap.get(slot), stack); + } + + @Override + public String getInventoryName() { + return ""; + } + + @Override + public boolean hasCustomInventoryName() { + return false; + } + + @Override + public int getInventoryStackLimit() { + return 64; + } + + @Override + public void markDirty() { + } + + @Override + public boolean isUseableByPlayer(EntityPlayer entityplayer) { + return true; + } + + @Override + public void openInventory() { + } + + @Override + public void closeInventory() { + } + + @Override + public boolean isItemValidForSlot(int slot, ItemStack stack) { + return invMap.get(slot).isItemValidForSlot(slotMap.get(slot), stack); + } +} diff --git a/forestry_common/core/forestry/core/inventory/InventorySorter.java b/forestry_common/core/forestry/core/inventory/InventorySorter.java new file mode 100755 index 000000000..311735138 --- /dev/null +++ b/forestry_common/core/forestry/core/inventory/InventorySorter.java @@ -0,0 +1,27 @@ +/******************************************************************************* + * Copyright 2011-2014 by SirSengir + * + * This work is licensed under a Creative Commons Attribution-NonCommercial-NoDerivs 3.0 Unported License. + * + * To view a copy of this license, visit http://creativecommons.org/licenses/by-nc-nd/3.0/. + ******************************************************************************/ +package forestry.core.inventory; + +import java.util.Comparator; + +import net.minecraft.inventory.IInventory; + +/** + * + * @author CovertJaguar + */ +public enum InventorySorter implements Comparator { + + SIZE_DECENDING { + @Override + public int compare(IInventory inv1, IInventory inv2) { + return inv2.getSizeInventory() - inv1.getSizeInventory(); + } + + }; +} diff --git a/forestry_common/core/forestry/core/inventory/ItemStackMap.java b/forestry_common/core/forestry/core/inventory/ItemStackMap.java new file mode 100755 index 000000000..52ce0d192 --- /dev/null +++ b/forestry_common/core/forestry/core/inventory/ItemStackMap.java @@ -0,0 +1,219 @@ +/******************************************************************************* + * Copyright 2011-2014 by SirSengir + * + * This work is licensed under a Creative Commons Attribution-NonCommercial-NoDerivs 3.0 Unported License. + * + * To view a copy of this license, visit http://creativecommons.org/licenses/by-nc-nd/3.0/. + ******************************************************************************/ +package forestry.core.inventory; + +import java.util.Collection; +import java.util.HashMap; +import java.util.HashSet; +import java.util.Map; +import java.util.Set; + +import net.minecraft.item.ItemStack; + +/** + * This is a custom data structure designed specifically + * for using ItemStacks as keys in a Map. + * + * The keys index on the itemID and damage of the ItemStacks, + * ignoring any other differences (NBT Tags, stackSize, etc...). + * + * @author CovertJaguar + * @see Map + * @param + */ +public class ItemStackMap implements Map +{ + + private class EntryWrapper implements Map.Entry + { + + private final Map.Entry entry; + + public EntryWrapper(Map.Entry e) + { + entry = e; + } + + @Override + public ItemStack getKey() + { + return entry.getKey().getStack(); + } + + @Override + public V getValue() + { + return entry.getValue(); + } + + @Override + public V setValue(V value) + { + return entry.setValue(value); + } + + @Override + public String toString() + { + return getKey().getItem().getUnlocalizedName() + "=" + getValue().toString(); + } + } + + private static class KeyWrapper + { + + private final ItemStack stack; + + public KeyWrapper(ItemStack stack) + { + this.stack = stack.copy(); + } + + @Override + public boolean equals(Object obj) + { + if(obj == null) { + return false; + } + if(getClass() != obj.getClass()) { + return false; + } + final KeyWrapper other = (KeyWrapper)obj; + if(stack.getItem() != other.stack.getItem()) { + return false; + } + if(stack.getItemDamage() != other.stack.getItemDamage()) { + return false; + } + return true; + } + + @Override + public int hashCode() + { + int hash = 5; + hash = 23 * hash + stack.getItem().hashCode(); + hash = 23 * hash + stack.getItemDamage(); + return hash; + } + + public ItemStack getStack() + { + return stack.copy(); + } + } + private final Map map = new HashMap(); + + @Override + public V put(ItemStack stack, V value) + { + return map.put(new KeyWrapper(stack), value); + } + + @Override + public Collection values() + { + return map.values(); + } + + @Override + public int size() + { + return map.size(); + } + + @Override + public V remove(Object key) + { + if(key instanceof ItemStack) { + return map.remove(new KeyWrapper((ItemStack)key)); + } + return null; + } + + @Override + public boolean isEmpty() + { + return map.isEmpty(); + } + + @Override + public int hashCode() + { + return map.hashCode(); + } + + @Override + public V get(Object key) + { + if(key instanceof ItemStack) { + return map.get(new KeyWrapper((ItemStack)key)); + } + return null; + } + + @SuppressWarnings("unchecked") + @Override + public boolean equals(Object o) + { + if(o instanceof ItemStackMap) { + return map.equals(((ItemStackMap)o).map); + } + return false; + } + + @Override + public boolean containsValue(Object value) + { + return map.containsValue(value); + } + + @Override + public boolean containsKey(Object key) + { + if(key instanceof ItemStack) { + return map.containsKey(new KeyWrapper((ItemStack)key)); + } + return false; + } + + @Override + public void clear() + { + map.clear(); + } + + @Override + public void putAll(Map m) + { + for(Map.Entry e : m.entrySet()) { + put(e.getKey(), e.getValue()); + } + } + + @Override + public Set keySet() + { + Set keySet = new HashSet(); + for(KeyWrapper w : map.keySet()) { + keySet.add(w.getStack()); + } + return keySet; + } + + @Override + public Set> entrySet() + { + Set> entrySet = new HashSet>(); + + for(Map.Entry entry : map.entrySet()) { + entrySet.add(new EntryWrapper(entry)); + } + return entrySet; + } +} diff --git a/forestry_common/core/forestry/core/inventory/ItemStackSet.java b/forestry_common/core/forestry/core/inventory/ItemStackSet.java new file mode 100755 index 000000000..e7de833fb --- /dev/null +++ b/forestry_common/core/forestry/core/inventory/ItemStackSet.java @@ -0,0 +1,151 @@ +/******************************************************************************* + * Copyright 2011-2014 by SirSengir + * + * This work is licensed under a Creative Commons Attribution-NonCommercial-NoDerivs 3.0 Unported License. + * + * To view a copy of this license, visit http://creativecommons.org/licenses/by-nc-nd/3.0/. + ******************************************************************************/ +package forestry.core.inventory; + +import java.util.ArrayList; +import java.util.Collection; +import java.util.Iterator; +import java.util.List; +import java.util.Set; + +import net.minecraft.item.ItemStack; + +/** + * This is a custom data structure designed specifically for using ItemStacks as + * elements of a Set. + * + * Its backed by an ArrayList, so as expected, most operations result in + * traversing the list one or more times. + * + * @author CovertJaguar + */ +public class ItemStackSet implements Set { + + private final List set = new ArrayList(); + + @Override + public int size() { + return set.size(); + } + + @Override + public boolean isEmpty() { + return set.isEmpty(); + } + + @Override + public boolean contains(Object obj) { + if (!(obj instanceof ItemStack)) { + return false; + } + ItemStack check = (ItemStack) obj; + for (ItemStack stack : set) { + if (InvTools.isItemEqual(stack, check)) { + return true; + } + } + return false; + } + + @Override + public Iterator iterator() { + return set.iterator(); + } + + @Override + public Object[] toArray() { + return set.toArray(); + } + + @Override + public T[] toArray(T[] a) { + return set.toArray(a); + } + + @Override + public boolean add(ItemStack e) { + if (contains(e)) { + return false; + } + set.add(e); + return true; + } + + @Override + public boolean remove(Object obj) { + if (!(obj instanceof ItemStack)) { + return false; + } + boolean changed = false; + ItemStack check = (ItemStack) obj; + Iterator it = set.iterator(); + while (it.hasNext()) { + ItemStack stack = it.next(); + if (InvTools.isItemEqual(stack, check)) { + it.remove(); + changed = true; + } + } + return changed; + } + + @Override + public boolean containsAll(Collection c) { + for (Object obj : c) { + if (!(obj instanceof ItemStack)) { + return false; + } + if (!contains(obj)) { + return false; + } + } + return true; + } + + @Override + public boolean addAll(Collection c) { + boolean changed = false; + for (ItemStack stack : c) { + changed |= add(stack); + } + return changed; + } + + @Override + public boolean retainAll(Collection c) { + boolean changed = false; + Iterator it = set.iterator(); + while (it.hasNext()) { + ItemStack stack = it.next(); + if (!c.contains(stack)) { + it.remove(); + changed = true; + } + } + return changed; + } + + @Override + public boolean removeAll(Collection c) { + boolean changed = false; + Iterator it = set.iterator(); + while (it.hasNext()) { + ItemStack stack = it.next(); + if (c.contains(stack)) { + it.remove(); + changed = true; + } + } + return changed; + } + + @Override + public void clear() { + set.clear(); + } +} diff --git a/forestry_common/core/forestry/core/inventory/ItemStackSizeSorter.java b/forestry_common/core/forestry/core/inventory/ItemStackSizeSorter.java new file mode 100755 index 000000000..b82dec423 --- /dev/null +++ b/forestry_common/core/forestry/core/inventory/ItemStackSizeSorter.java @@ -0,0 +1,36 @@ +/******************************************************************************* + * Copyright 2011-2014 by SirSengir + * + * This work is licensed under a Creative Commons Attribution-NonCommercial-NoDerivs 3.0 Unported License. + * + * To view a copy of this license, visit http://creativecommons.org/licenses/by-nc-nd/3.0/. + ******************************************************************************/ +package forestry.core.inventory; + +import java.util.Collections; +import java.util.Comparator; +import java.util.List; + +import net.minecraft.item.ItemStack; + +public class ItemStackSizeSorter implements Comparator { + + private static ItemStackSizeSorter instance; + + private static ItemStackSizeSorter getInstance() { + if (instance == null) { + instance = new ItemStackSizeSorter(); + } + return instance; + } + + public static void sort(List list) { + Collections.sort(list, getInstance()); + } + + @Override + public int compare(ItemStack o1, ItemStack o2) { + return o1.stackSize - o2.stackSize; + } + +} diff --git a/forestry_common/core/forestry/core/inventory/filters/ArrayStackFilter.java b/forestry_common/core/forestry/core/inventory/filters/ArrayStackFilter.java new file mode 100755 index 000000000..d6c0ce7f7 --- /dev/null +++ b/forestry_common/core/forestry/core/inventory/filters/ArrayStackFilter.java @@ -0,0 +1,46 @@ +/******************************************************************************* + * Copyright 2011-2014 by SirSengir + * + * This work is licensed under a Creative Commons Attribution-NonCommercial-NoDerivs 3.0 Unported License. + * + * To view a copy of this license, visit http://creativecommons.org/licenses/by-nc-nd/3.0/. + ******************************************************************************/ +package forestry.core.inventory.filters; + +import net.minecraft.item.ItemStack; + +import forestry.core.inventory.InvTools; + +/** + * + * @author CovertJaguar + */ +public class ArrayStackFilter implements IStackFilter { + + private final ItemStack[] stacks; + + public ArrayStackFilter(ItemStack... stacks) { + this.stacks = stacks; + } + + @Override + public boolean matches(ItemStack stack) { + if (stacks.length == 0 || !hasFilter()) { + return true; + } + return InvTools.isItemEqual(stack, stacks); + } + + public ItemStack[] getStacks() { + return stacks; + } + + public boolean hasFilter() { + for (ItemStack filter : stacks) { + if (filter != null) { + return true; + } + } + return false; + } +} diff --git a/forestry_common/core/forestry/core/inventory/filters/IStackFilter.java b/forestry_common/core/forestry/core/inventory/filters/IStackFilter.java new file mode 100755 index 000000000..36858c31a --- /dev/null +++ b/forestry_common/core/forestry/core/inventory/filters/IStackFilter.java @@ -0,0 +1,22 @@ +/******************************************************************************* + * Copyright 2011-2014 by SirSengir + * + * This work is licensed under a Creative Commons Attribution-NonCommercial-NoDerivs 3.0 Unported License. + * + * To view a copy of this license, visit http://creativecommons.org/licenses/by-nc-nd/3.0/. + ******************************************************************************/ +package forestry.core.inventory.filters; + +import net.minecraft.item.ItemStack; + +/** + * This interface is used with several of the functions in IItemTransfer to + * provide a convenient means of dealing with entire classes of items without + * having to specify each item individually. + * + * @author CovertJaguar + */ +public interface IStackFilter { + + public boolean matches(ItemStack stack); +} diff --git a/forestry_common/core/forestry/core/inventory/filters/InvertedStackFilter.java b/forestry_common/core/forestry/core/inventory/filters/InvertedStackFilter.java new file mode 100755 index 000000000..9c3214757 --- /dev/null +++ b/forestry_common/core/forestry/core/inventory/filters/InvertedStackFilter.java @@ -0,0 +1,31 @@ +/******************************************************************************* + * Copyright 2011-2014 by SirSengir + * + * This work is licensed under a Creative Commons Attribution-NonCommercial-NoDerivs 3.0 Unported License. + * + * To view a copy of this license, visit http://creativecommons.org/licenses/by-nc-nd/3.0/. + ******************************************************************************/ +package forestry.core.inventory.filters; + +import net.minecraft.item.ItemStack; + +/** + * + * @author CovertJaguar + */ +public class InvertedStackFilter implements IStackFilter { + + private final IStackFilter filter; + + public InvertedStackFilter(IStackFilter filter) { + this.filter = filter; + } + + @Override + public boolean matches(ItemStack stack) { + if (stack == null) { + return false; + } + return !filter.matches(stack); + } +} diff --git a/forestry_common/core/forestry/core/inventory/filters/StackFilter.java b/forestry_common/core/forestry/core/inventory/filters/StackFilter.java new file mode 100755 index 000000000..020282e01 --- /dev/null +++ b/forestry_common/core/forestry/core/inventory/filters/StackFilter.java @@ -0,0 +1,46 @@ +/******************************************************************************* + * Copyright 2011-2014 by SirSengir + * + * This work is licensed under a Creative Commons Attribution-NonCommercial-NoDerivs 3.0 Unported License. + * + * To view a copy of this license, visit http://creativecommons.org/licenses/by-nc-nd/3.0/. + ******************************************************************************/ +package forestry.core.inventory.filters; + +import net.minecraft.init.Items; +import net.minecraft.item.ItemFood; +import net.minecraft.item.ItemSeeds; +import net.minecraft.item.ItemStack; +import net.minecraft.tileentity.TileEntityFurnace; + +/** + * This interface is used with several of the functions in IItemTransfer to + * provide a convenient means of dealing with entire classes of items without + * having to specify each item individually. + * + * @author CovertJaguar + */ +public enum StackFilter implements IStackFilter { + + ALL { + @Override + public boolean matches(ItemStack stack) { + return true; + } + }, + FUEL { + @Override + public boolean matches(ItemStack stack) { + return TileEntityFurnace.getItemBurnTime(stack) > 0; + } + }, + FEED { + @Override + public boolean matches(ItemStack stack) { + return stack.getItem() instanceof ItemFood || stack.getItem() == Items.wheat || stack.getItem() instanceof ItemSeeds; + } + }; + + @Override + public abstract boolean matches(ItemStack stack); +} diff --git a/forestry_common/core/forestry/core/inventory/manipulators/InventoryManipulator.java b/forestry_common/core/forestry/core/inventory/manipulators/InventoryManipulator.java new file mode 100755 index 000000000..bf3df6c3e --- /dev/null +++ b/forestry_common/core/forestry/core/inventory/manipulators/InventoryManipulator.java @@ -0,0 +1,194 @@ +/******************************************************************************* + * Copyright 2011-2014 by SirSengir + * + * This work is licensed under a Creative Commons Attribution-NonCommercial-NoDerivs 3.0 Unported License. + * + * To view a copy of this license, visit http://creativecommons.org/licenses/by-nc-nd/3.0/. + ******************************************************************************/ +package forestry.core.inventory.manipulators; + +import java.util.ArrayList; +import java.util.List; + +import net.minecraft.inventory.IInventory; +import net.minecraft.item.ItemStack; + +import buildcraft.api.inventory.ISpecialInventory; + +import forestry.core.inventory.InvTools; +import forestry.core.inventory.filters.IStackFilter; +import forestry.core.inventory.wrappers.IInvSlot; +import forestry.core.inventory.wrappers.InventoryIterator; + +/** + * + * @author CovertJaguar + */ +public class InventoryManipulator { + + private final IInventory inv; + + public static InventoryManipulator get(IInventory inv) { + if (inv instanceof ISpecialInventory) { + return new SpecialManipulator((ISpecialInventory) inv); + } + return new InventoryManipulator(inv); + } + + protected InventoryManipulator(IInventory inv) { + this.inv = inv; + } + + protected Iterable getSlots() { + return InventoryIterator.getIterable(inv); + } + + public boolean canAddStack(ItemStack stack) { + return tryAddStack(stack) == null; + } + + public ItemStack tryAddStack(ItemStack stack) { + return addStack(stack, false); + } + + /** + * Attempt to add the stack to the inventory. + * + * @param stack + * @return The remainder + */ + public ItemStack addStack(ItemStack stack) { + return addStack(stack, true); + } + + private ItemStack addStack(ItemStack stack, boolean doAdd) { + if (stack == null || stack.stackSize <= 0) { + return null; + } + stack = stack.copy(); + List filledSlots = new ArrayList(inv.getSizeInventory()); + List emptySlots = new ArrayList(inv.getSizeInventory()); + for (IInvSlot slot : InventoryIterator.getIterable(inv)) { + if (slot.canPutStackInSlot(stack)) { + if (slot.getStackInSlot() == null) { + emptySlots.add(slot); + } else { + filledSlots.add(slot); + } + } + } + + int injected = 0; + injected = tryPut(filledSlots, stack, injected, doAdd); + injected = tryPut(emptySlots, stack, injected, doAdd); + stack.stackSize -= injected; + if (stack.stackSize <= 0) { + return null; + } + return stack; + } + + private int tryPut(List slots, ItemStack stack, int injected, boolean doAdd) { + if (injected >= stack.stackSize) { + return injected; + } + for (IInvSlot slot : slots) { + ItemStack stackInSlot = slot.getStackInSlot(); + if (stackInSlot == null || InvTools.isItemEqual(stackInSlot, stack)) { + int used = addToSlot(slot, stack, stack.stackSize - injected, doAdd); + if (used > 0) { + injected += used; + if (injected >= stack.stackSize) { + return injected; + } + } + } + } + return injected; + } + + /** + * + * @param slot + * @param stack + * @param available Amount we can move + * @param doAdd + * @return Return the number of items moved. + */ + private int addToSlot(IInvSlot slot, ItemStack stack, int available, boolean doAdd) { + int max = Math.min(stack.getMaxStackSize(), inv.getInventoryStackLimit()); + + ItemStack stackInSlot = slot.getStackInSlot(); + if (stackInSlot == null) { + int wanted = Math.min(available, max); + if (doAdd) { + stackInSlot = stack.copy(); + stackInSlot.stackSize = wanted; + slot.setStackInSlot(stackInSlot); + } + return wanted; + } + + if (!InvTools.isItemEqual(stack, stackInSlot)) { + return 0; + } + + int wanted = max - stackInSlot.stackSize; + if (wanted <= 0) { + return 0; + } + + if (wanted > available) { + wanted = available; + } + + if (doAdd) { + stackInSlot.stackSize += wanted; + slot.setStackInSlot(stackInSlot); + } + return wanted; + } + + public boolean canRemoveItem(IStackFilter filter) { + return tryRemoveItem(filter) == null; + } + + public ItemStack tryRemoveItem(IStackFilter filter) { + for (IInvSlot slot : getSlots()) { + ItemStack stack = slot.getStackInSlot(); + if (stack != null && slot.canTakeStackFromSlot(stack) && filter.matches(stack)) { + ItemStack output = stack.copy(); + output.stackSize = 1; + return output; + } + } + return null; + } + + public ItemStack removeItem(IStackFilter filter) { + for (IInvSlot slot : getSlots()) { + ItemStack stack = slot.getStackInSlot(); + if (stack != null && slot.canTakeStackFromSlot(stack) && filter.matches(stack)) { + return slot.decreaseStackInSlot(); + } + } + return null; + } + + public ItemStack moveItem(IInventory dest, IStackFilter filter) { + InventoryManipulator imDest = InventoryManipulator.get(dest); + for (IInvSlot slot : getSlots()) { + ItemStack stack = slot.getStackInSlot(); + if (stack != null && slot.canTakeStackFromSlot(stack) && filter.matches(stack)) { + stack = stack.copy(); + stack.stackSize = 1; + stack = imDest.addStack(stack); + if (stack == null) { + return slot.decreaseStackInSlot(); + } + } + } + return null; + } + +} diff --git a/forestry_common/core/forestry/core/inventory/manipulators/SpecialManipulator.java b/forestry_common/core/forestry/core/inventory/manipulators/SpecialManipulator.java new file mode 100755 index 000000000..4d5565102 --- /dev/null +++ b/forestry_common/core/forestry/core/inventory/manipulators/SpecialManipulator.java @@ -0,0 +1,99 @@ +/******************************************************************************* + * Copyright 2011-2014 by SirSengir + * + * This work is licensed under a Creative Commons Attribution-NonCommercial-NoDerivs 3.0 Unported License. + * + * To view a copy of this license, visit http://creativecommons.org/licenses/by-nc-nd/3.0/. + ******************************************************************************/ +package forestry.core.inventory.manipulators; + +import net.minecraft.inventory.IInventory; +import net.minecraft.item.ItemStack; + +import net.minecraftforge.common.util.ForgeDirection; + +import buildcraft.api.inventory.ISpecialInventory; + +import forestry.core.inventory.filters.IStackFilter; + +/** + * + * @author CovertJaguar + */ +public class SpecialManipulator extends InventoryManipulator { + + private final ISpecialInventory inv; + protected ForgeDirection side = ForgeDirection.UNKNOWN; + + protected SpecialManipulator(ISpecialInventory inv) { + super(inv); + this.inv = inv; + } + + public void setSide(ForgeDirection side) { + this.side = side; + } + + @Override + public ItemStack tryAddStack(ItemStack stack) { + return addStackInternal(stack, false); + } + + @Override + public ItemStack addStack(ItemStack stack) { + return addStackInternal(stack, true); + } + + private ItemStack addStackInternal(ItemStack stack, boolean doAdd) { + if (stack == null) { + return null; + } + stack = stack.copy(); + int used = inv.addItem(stack.copy(), doAdd, side); + if (used >= stack.stackSize) { + return null; + } + stack.stackSize -= used; + return stack; + } + + @Override + public boolean canRemoveItem(IStackFilter filter) { + return tryRemoveItem(filter) == null; + } + + @Override + public ItemStack tryRemoveItem(IStackFilter filter) { + return removeStackInternal(filter, false); + } + + @Override + public ItemStack removeItem(IStackFilter filter) { + return removeStackInternal(filter, true); + } + + protected ItemStack removeStackInternal(IStackFilter filter, boolean doRemove) { + ItemStack[] extracted = inv.extractItem(false, side, 1); + if (extracted != null && extracted.length > 0 && filter.matches(extracted[0])) { + if (doRemove) { + inv.extractItem(true, side, 1); + } + return extracted[0]; + } + return null; + } + + @Override + public ItemStack moveItem(IInventory dest, IStackFilter filter) { + InventoryManipulator imDest = InventoryManipulator.get(dest); + ItemStack stack = tryRemoveItem(filter); + if (stack != null) { + ItemStack result = imDest.addStack(stack); + if (result == null) { + return removeItem(filter); + } + } + return null; + } + +} diff --git a/forestry_common/core/forestry/core/inventory/wrappers/ChestWrapper.java b/forestry_common/core/forestry/core/inventory/wrappers/ChestWrapper.java new file mode 100755 index 000000000..0e9ee049f --- /dev/null +++ b/forestry_common/core/forestry/core/inventory/wrappers/ChestWrapper.java @@ -0,0 +1,190 @@ +/******************************************************************************* + * Copyright 2011-2014 by SirSengir + * + * This work is licensed under a Creative Commons Attribution-NonCommercial-NoDerivs 3.0 Unported License. + * + * To view a copy of this license, visit http://creativecommons.org/licenses/by-nc-nd/3.0/. + ******************************************************************************/ +package forestry.core.inventory.wrappers; + +import net.minecraft.entity.player.EntityPlayer; +import net.minecraft.inventory.IInventory; +import net.minecraft.item.ItemStack; +import net.minecraft.tileentity.TileEntityChest; + +/** + * + * @author CovertJaguar + */ +public class ChestWrapper implements IInventory { + + /** + * Inventory object corresponding to double chest upper part + */ + private final TileEntityChest upperChest; + /** + * Inventory object corresponding to double chest lower part + */ + private TileEntityChest lowerChest; + + public ChestWrapper(TileEntityChest tile) { + this.upperChest = tile; + checkChest(); + } + + private void checkChest() { + if (lowerChest == null || lowerChest.isInvalid()) { + if (upperChest.adjacentChestXNeg != null) { + lowerChest = upperChest.adjacentChestXNeg; + } else if (upperChest.adjacentChestXPos != null) { + lowerChest = upperChest.adjacentChestXPos; + } else if (upperChest.adjacentChestZNeg != null) { + lowerChest = upperChest.adjacentChestZNeg; + } else if (upperChest.adjacentChestZPos != null) { + lowerChest = upperChest.adjacentChestZPos; + } else { + lowerChest = null; + } + } + } + + /** + * Returns the number of slots in the inventory. + */ + @Override + public int getSizeInventory() { + checkChest(); + int size = upperChest.getSizeInventory(); + if (lowerChest != null) { + size += lowerChest.getSizeInventory(); + } + return size; + } + + /** + * Return whether the given inventory is part of this large chest. + */ + public boolean isPartOfLargeChest(IInventory inv) { + return this.upperChest == inv || this.lowerChest == inv; + } + + /** + * Returns the name of the inventory. + */ + @Override + public String getInventoryName() { + return ""; + } + + /** + * If this returns false, the inventory name will be used as an unlocalized + * name, and translated into the player's language. Otherwise it will be + * used directly. + */ + @Override + public boolean hasCustomInventoryName() { + return false; + } + + /** + * Returns the stack in slot i + */ + @Override + public ItemStack getStackInSlot(int slot) { + checkChest(); + if (slot >= upperChest.getSizeInventory() && lowerChest != null) { + return lowerChest.getStackInSlot(slot - upperChest.getSizeInventory()); + } + return upperChest.getStackInSlot(slot); + } + + /** + * Removes from an inventory slot (first arg) up to a specified number + * (second arg) of items and returns them in a new stack. + */ + @Override + public ItemStack decrStackSize(int slot, int amout) { + checkChest(); + if (slot >= upperChest.getSizeInventory() && lowerChest != null) { + return lowerChest.decrStackSize(slot - upperChest.getSizeInventory(), amout); + } + return upperChest.decrStackSize(slot, amout); + } + + /** + * When some containers are closed they call this on each slot, then drop + * whatever it returns as an EntityItem - like when you close a workbench + * GUI. + */ + @Override + public ItemStack getStackInSlotOnClosing(int slot) { + checkChest(); + if (slot >= upperChest.getSizeInventory() && lowerChest != null) { + return lowerChest.getStackInSlotOnClosing(slot - upperChest.getSizeInventory()); + } + return upperChest.getStackInSlotOnClosing(slot); + } + + /** + * Sets the given item stack to the specified slot in the inventory (can be + * crafting or armor sections). + */ + @Override + public void setInventorySlotContents(int slot, ItemStack stack) { + checkChest(); + if (slot >= this.upperChest.getSizeInventory() && lowerChest != null) { + lowerChest.setInventorySlotContents(slot - upperChest.getSizeInventory(), stack); + } else { + upperChest.setInventorySlotContents(slot, stack); + } + } + + /** + * Returns the maximum stack size for a inventory slot. Seems to always be + * 64, possibly will be extended. *Isn't this more of a set than a get?* + */ + @Override + public int getInventoryStackLimit() { + return this.upperChest.getInventoryStackLimit(); + } + + /** + * Called when an the contents of an Inventory change, usually + */ + @Override + public void markDirty() { + this.upperChest.markDirty(); + if (lowerChest != null) lowerChest.markDirty(); + } + + /** + * Do not make give this method the name canInteractWith because it clashes + * with Container + */ + @Override + public boolean isUseableByPlayer(EntityPlayer player) { + return this.upperChest.isUseableByPlayer(player) && (lowerChest == null || lowerChest.isUseableByPlayer(player)); + } + + @Override + public void openInventory() { + this.upperChest.openInventory(); + if (lowerChest != null) lowerChest.openInventory(); + } + + @Override + public void closeInventory() { + this.upperChest.closeInventory(); + if (lowerChest != null) lowerChest.closeInventory(); + } + + /** + * Returns true if automation is allowed to insert the given stack (ignoring + * stack size) into the given slot. + */ + @Override + public boolean isItemValidForSlot(int slot, ItemStack stack) { + return true; + } + +} diff --git a/forestry_common/core/forestry/core/inventory/wrappers/IInvSlot.java b/forestry_common/core/forestry/core/inventory/wrappers/IInvSlot.java new file mode 100755 index 000000000..95f7eb1fe --- /dev/null +++ b/forestry_common/core/forestry/core/inventory/wrappers/IInvSlot.java @@ -0,0 +1,30 @@ +/******************************************************************************* + * Copyright 2011-2014 by SirSengir + * + * This work is licensed under a Creative Commons Attribution-NonCommercial-NoDerivs 3.0 Unported License. + * + * To view a copy of this license, visit http://creativecommons.org/licenses/by-nc-nd/3.0/. + ******************************************************************************/ +package forestry.core.inventory.wrappers; + +import net.minecraft.item.ItemStack; + +/** + * + * @author CovertJaguar + */ +public interface IInvSlot { + + boolean canPutStackInSlot(ItemStack stack); + + boolean canTakeStackFromSlot(ItemStack stack); + + ItemStack decreaseStackInSlot(); + + ItemStack getStackInSlot(); + + void setStackInSlot(ItemStack stack); + + int getIndex(); + +} diff --git a/forestry_common/core/forestry/core/inventory/wrappers/InventoryCopy.java b/forestry_common/core/forestry/core/inventory/wrappers/InventoryCopy.java new file mode 100755 index 000000000..48010826f --- /dev/null +++ b/forestry_common/core/forestry/core/inventory/wrappers/InventoryCopy.java @@ -0,0 +1,118 @@ +/******************************************************************************* + * Copyright 2011-2014 by SirSengir + * + * This work is licensed under a Creative Commons Attribution-NonCommercial-NoDerivs 3.0 Unported License. + * + * To view a copy of this license, visit http://creativecommons.org/licenses/by-nc-nd/3.0/. + ******************************************************************************/ +package forestry.core.inventory.wrappers; + +import net.minecraft.entity.player.EntityPlayer; +import net.minecraft.inventory.IInventory; +import net.minecraft.item.ItemStack; + +/** + * Creates a deep copy of an existing IInventory. + * + * Useful for performing inventory manipulations and then examining the results + * without affecting the original inventory. + * + * @author CovertJaguar + */ +public class InventoryCopy implements IInventory { + + private final IInventory orignal; + private final ItemStack contents[]; + + public InventoryCopy(IInventory orignal) { + this.orignal = orignal; + contents = new ItemStack[orignal.getSizeInventory()]; + for (int i = 0; i < contents.length; i++) { + ItemStack stack = orignal.getStackInSlot(i); + if (stack != null) { + contents[i] = stack.copy(); + } + } + } + + @Override + public int getSizeInventory() { + return contents.length; + } + + @Override + public ItemStack getStackInSlot(int i) { + return contents[i]; + } + + @Override + public ItemStack decrStackSize(int i, int j) { + if (contents[i] != null) { + if (contents[i].stackSize <= j) { + ItemStack itemstack = contents[i]; + contents[i] = null; + markDirty(); + return itemstack; + } + ItemStack itemstack1 = contents[i].splitStack(j); + if (contents[i].stackSize <= 0) { + contents[i] = null; + } + markDirty(); + return itemstack1; + } else { + return null; + } + } + + @Override + public void setInventorySlotContents(int i, ItemStack itemstack) { + contents[i] = itemstack; + if (itemstack != null && itemstack.stackSize > getInventoryStackLimit()) { + itemstack.stackSize = getInventoryStackLimit(); + } + markDirty(); + } + + @Override + public String getInventoryName() { + return orignal.getInventoryName(); + } + + @Override + public int getInventoryStackLimit() { + return orignal.getInventoryStackLimit(); + } + + @Override + public void markDirty() { + } + + @Override + public boolean isUseableByPlayer(EntityPlayer entityplayer) { + return true; + } + + @Override + public void openInventory() { + } + + @Override + public void closeInventory() { + } + + @Override + public ItemStack getStackInSlotOnClosing(int slot) { + return orignal.getStackInSlotOnClosing(slot); + } + + @Override + public boolean hasCustomInventoryName() { + return orignal.hasCustomInventoryName(); + } + + @Override + public boolean isItemValidForSlot(int slot, ItemStack stack) { + return orignal.isItemValidForSlot(slot, stack); + } +} diff --git a/forestry_common/core/forestry/core/inventory/wrappers/InventoryIterator.java b/forestry_common/core/forestry/core/inventory/wrappers/InventoryIterator.java new file mode 100755 index 000000000..12ee251a9 --- /dev/null +++ b/forestry_common/core/forestry/core/inventory/wrappers/InventoryIterator.java @@ -0,0 +1,97 @@ +/******************************************************************************* + * Copyright 2011-2014 by SirSengir + * + * This work is licensed under a Creative Commons Attribution-NonCommercial-NoDerivs 3.0 Unported License. + * + * To view a copy of this license, visit http://creativecommons.org/licenses/by-nc-nd/3.0/. + ******************************************************************************/ +package forestry.core.inventory.wrappers; + +import java.util.Iterator; + +import net.minecraft.inventory.IInventory; +import net.minecraft.inventory.ISidedInventory; +import net.minecraft.item.ItemStack; + +/** + * @author CovertJaguar + */ +public class InventoryIterator implements Iterable { + + public static Iterable getIterable(IInventory inv) { + if (inv instanceof ISidedInventory) + return new SidedInventoryIterator((ISidedInventory) inv); + return new InventoryIterator(inv); + } + + private final IInventory inv; + private final int invSize; + + private InventoryIterator(IInventory inv) { + this.inv = inv; + this.invSize = inv.getSizeInventory(); + } + + @Override + public Iterator iterator() { + return new Iterator() { + int slot = 0; + + @Override + public boolean hasNext() { + return slot < invSize; + } + + @Override + public IInvSlot next() { + return new InvSlot(slot++); + } + + @Override + public void remove() { + throw new UnsupportedOperationException("Remove not supported."); + } + + }; + } + + private class InvSlot implements IInvSlot { + + private int slot; + + public InvSlot(int slot) { + this.slot = slot; + } + + @Override + public ItemStack getStackInSlot() { + return inv.getStackInSlot(slot); + } + + @Override + public void setStackInSlot(ItemStack stack) { + inv.setInventorySlotContents(slot, stack); + } + + @Override + public boolean canPutStackInSlot(ItemStack stack) { + return inv.isItemValidForSlot(slot, stack); + } + + @Override + public boolean canTakeStackFromSlot(ItemStack stack) { + return true; + } + + @Override + public ItemStack decreaseStackInSlot() { + return inv.decrStackSize(slot, 1); + } + + @Override + public int getIndex() { + return slot; + } + + } +} diff --git a/forestry_common/core/forestry/core/inventory/wrappers/InventoryMapper.java b/forestry_common/core/forestry/core/inventory/wrappers/InventoryMapper.java new file mode 100755 index 000000000..0b0859e6b --- /dev/null +++ b/forestry_common/core/forestry/core/inventory/wrappers/InventoryMapper.java @@ -0,0 +1,145 @@ +/******************************************************************************* + * Copyright 2011-2014 by SirSengir + * + * This work is licensed under a Creative Commons Attribution-NonCommercial-NoDerivs 3.0 Unported License. + * + * To view a copy of this license, visit http://creativecommons.org/licenses/by-nc-nd/3.0/. + ******************************************************************************/ +package forestry.core.inventory.wrappers; + +import net.minecraft.entity.player.EntityPlayer; +import net.minecraft.inventory.IInventory; +import net.minecraft.item.ItemStack; + +import net.minecraftforge.common.util.ForgeDirection; + +/** + * Wrapper class used to specify part of an existing inventory to be treated as + * a complete inventory. Used primarily to map a side of an ISidedInventory, but + * it is also helpful for complex inventories such as the Tunnel Bore. + * + * @author CovertJaguar + */ +public class InventoryMapper implements IInventory { + + private final IInventory inv; + private final int start; + private final int size; + private int stackSizeLimit = -1; + private boolean checkItems = true; + + public InventoryMapper(IInventory inv, ForgeDirection side) { + this(inv, getInventoryStart(inv, side), getInventorySize(inv, side)); + } + + public InventoryMapper(IInventory inv) { + this(inv, 0, inv.getSizeInventory(), true); + } + + public InventoryMapper(IInventory inv, boolean checkItems) { + this(inv, 0, inv.getSizeInventory(), checkItems); + } + + /** + * Creates a new InventoryMapper + * + * @param inv The backing inventory + * @param start The starting index + * @param size The size of the new inventory, take care not to exceed the + * end of the backing inventory + */ + public InventoryMapper(IInventory inv, int start, int size) { + this(inv, start, size, true); + } + + public InventoryMapper(IInventory inv, int start, int size, boolean checkItems) { + this.inv = inv; + this.start = start; + this.size = size; + this.checkItems = checkItems; + } + + protected static int getInventorySize(IInventory inv, ForgeDirection side) { + return inv.getSizeInventory(); + } + + protected static int getInventoryStart(IInventory inv, ForgeDirection side) { + return 0; + } + + public IInventory getBaseInventory() { + return inv; + } + + @Override + public int getSizeInventory() { + return size; + } + + @Override + public ItemStack getStackInSlot(int slot) { + return inv.getStackInSlot(start + slot); + } + + @Override + public ItemStack decrStackSize(int slot, int amount) { + return inv.decrStackSize(start + slot, amount); + } + + @Override + public void setInventorySlotContents(int slot, ItemStack itemstack) { + inv.setInventorySlotContents(start + slot, itemstack); + } + + @Override + public String getInventoryName() { + return inv.getInventoryName(); + } + + public void setStackSizeLimit(int limit) { + stackSizeLimit = limit; + } + + @Override + public int getInventoryStackLimit() { + return stackSizeLimit > 0 ? stackSizeLimit : inv.getInventoryStackLimit(); + } + + @Override + public void markDirty() { + inv.markDirty(); + } + + @Override + public boolean isUseableByPlayer(EntityPlayer entityplayer) { + return inv.isUseableByPlayer(entityplayer); + } + + @Override + public void openInventory() { + inv.openInventory(); + } + + @Override + public void closeInventory() { + inv.closeInventory(); + } + + @Override + public ItemStack getStackInSlotOnClosing(int slot) { + return inv.getStackInSlotOnClosing(start + slot); + } + + @Override + public boolean hasCustomInventoryName() { + return inv.hasCustomInventoryName(); + } + + @Override + public boolean isItemValidForSlot(int slot, ItemStack stack) { + if (checkItems) + return inv.isItemValidForSlot(start + slot, stack); + return true; + } + +} diff --git a/forestry_common/core/forestry/core/inventory/wrappers/SidedInventoryIterator.java b/forestry_common/core/forestry/core/inventory/wrappers/SidedInventoryIterator.java new file mode 100755 index 000000000..eb2a4c675 --- /dev/null +++ b/forestry_common/core/forestry/core/inventory/wrappers/SidedInventoryIterator.java @@ -0,0 +1,89 @@ +/******************************************************************************* + * Copyright 2011-2014 by SirSengir + * + * This work is licensed under a Creative Commons Attribution-NonCommercial-NoDerivs 3.0 Unported License. + * + * To view a copy of this license, visit http://creativecommons.org/licenses/by-nc-nd/3.0/. + ******************************************************************************/ +package forestry.core.inventory.wrappers; + +import java.util.Iterator; + +import net.minecraft.inventory.ISidedInventory; +import net.minecraft.item.ItemStack; + +/** + * @author CovertJaguar + */ +public class SidedInventoryIterator implements Iterable { + + private final ISidedInventory inv; + + SidedInventoryIterator(ISidedInventory inv) { + this.inv = inv; + } + + @Override + public Iterator iterator() { + return new Iterator() { + int[] slots = inv.getAccessibleSlotsFromSide(0); + int index = 0; + + @Override + public boolean hasNext() { + return slots != null && index < slots.length; + } + + @Override + public IInvSlot next() { + return new InvSlot(slots[index++]); + } + + @Override + public void remove() { + throw new UnsupportedOperationException("Remove not supported."); + } + + }; + } + + private class InvSlot implements IInvSlot { + + private int slot; + + public InvSlot(int slot) { + this.slot = slot; + } + + @Override + public ItemStack getStackInSlot() { + return inv.getStackInSlot(slot); + } + + @Override + public void setStackInSlot(ItemStack stack) { + inv.setInventorySlotContents(slot, stack); + } + + @Override + public boolean canPutStackInSlot(ItemStack stack) { + return inv.canInsertItem(slot, stack, 0); + } + + @Override + public boolean canTakeStackFromSlot(ItemStack stack) { + return inv.canExtractItem(slot, stack, 0); + } + + @Override + public ItemStack decreaseStackInSlot() { + return inv.decrStackSize(slot, 1); + } + + @Override + public int getIndex(){ + return slot; + } + + } +} diff --git a/forestry_common/core/forestry/core/inventory/wrappers/SidedInventoryMapper.java b/forestry_common/core/forestry/core/inventory/wrappers/SidedInventoryMapper.java new file mode 100755 index 000000000..73a982148 --- /dev/null +++ b/forestry_common/core/forestry/core/inventory/wrappers/SidedInventoryMapper.java @@ -0,0 +1,123 @@ +/******************************************************************************* + * Copyright 2011-2014 by SirSengir + * + * This work is licensed under a Creative Commons Attribution-NonCommercial-NoDerivs 3.0 Unported License. + * + * To view a copy of this license, visit http://creativecommons.org/licenses/by-nc-nd/3.0/. + ******************************************************************************/ +package forestry.core.inventory.wrappers; + +import net.minecraft.entity.player.EntityPlayer; +import net.minecraft.inventory.IInventory; +import net.minecraft.inventory.ISidedInventory; +import net.minecraft.item.ItemStack; + +import net.minecraftforge.common.util.ForgeDirection; + +/** + * Wrapper class used to bake the side variable into the object itself instead + * of passing it around to all the inventory tools. + * + * @author CovertJaguar + */ +public class SidedInventoryMapper implements ISidedInventory { + + private final ISidedInventory inv; + private final int side; + private boolean checkItems = true; + + public SidedInventoryMapper(ISidedInventory inv, ForgeDirection side) { + this(inv, side, true); + } + + public SidedInventoryMapper(ISidedInventory inv, ForgeDirection side, boolean checkItems) { + this.inv = inv; + this.side = side.ordinal(); + this.checkItems = checkItems; + } + + public IInventory getBaseInventory() { + return inv; + } + + @Override + public int getSizeInventory() { + return inv.getSizeInventory(); + } + + @Override + public ItemStack getStackInSlot(int slot) { + return inv.getStackInSlot(slot); + } + + @Override + public ItemStack decrStackSize(int slot, int amount) { + return inv.decrStackSize(slot, amount); + } + + @Override + public void setInventorySlotContents(int slot, ItemStack itemstack) { + inv.setInventorySlotContents(slot, itemstack); + } + + @Override + public String getInventoryName() { + return inv.getInventoryName(); + } + + @Override + public int getInventoryStackLimit() { + return inv.getInventoryStackLimit(); + } + + @Override + public void markDirty() { + inv.markDirty(); + } + + @Override + public boolean isUseableByPlayer(EntityPlayer entityplayer) { + return inv.isUseableByPlayer(entityplayer); + } + + @Override + public void openInventory() { + inv.openInventory(); + } + + @Override + public void closeInventory() { + inv.closeInventory(); + } + + @Override + public ItemStack getStackInSlotOnClosing(int slot) { + return inv.getStackInSlotOnClosing(slot); + } + + @Override + public boolean hasCustomInventoryName() { + return inv.hasCustomInventoryName(); + } + + @Override + public boolean isItemValidForSlot(int slot, ItemStack stack) { + return !checkItems || inv.isItemValidForSlot(slot, stack); + } + + @Override + public int[] getAccessibleSlotsFromSide(int s) { + return inv.getAccessibleSlotsFromSide(side); + } + + @Override + public boolean canInsertItem(int slot, ItemStack stack, int s) { + return !checkItems || inv.canInsertItem(slot, stack, side); + } + + @Override + public boolean canExtractItem(int slot, ItemStack stack, int s) { + return !checkItems || inv.canExtractItem(slot, stack, side); + } + +} diff --git a/forestry_common/core/forestry/core/inventory/wrappers/SpecialInventoryMapper.java b/forestry_common/core/forestry/core/inventory/wrappers/SpecialInventoryMapper.java new file mode 100755 index 000000000..a44c0361d --- /dev/null +++ b/forestry_common/core/forestry/core/inventory/wrappers/SpecialInventoryMapper.java @@ -0,0 +1,44 @@ +/******************************************************************************* + * Copyright 2011-2014 by SirSengir + * + * This work is licensed under a Creative Commons Attribution-NonCommercial-NoDerivs 3.0 Unported License. + * + * To view a copy of this license, visit http://creativecommons.org/licenses/by-nc-nd/3.0/. + ******************************************************************************/ +package forestry.core.inventory.wrappers; + +import net.minecraft.item.ItemStack; + +import net.minecraftforge.common.util.ForgeDirection; + +import buildcraft.api.inventory.ISpecialInventory; + +/** + * + * @author CovertJaguar + */ +public class SpecialInventoryMapper extends InventoryMapper implements ISpecialInventory +{ + + private final ISpecialInventory inv; + protected final ForgeDirection side; + + public SpecialInventoryMapper(ISpecialInventory inv, ForgeDirection side) + { + super(inv, side); + this.inv = inv; + this.side = side; + } + + @Override + public int addItem(ItemStack stack, boolean doAdd, ForgeDirection from) + { + return inv.addItem(stack, doAdd, side); + } + + @Override + public ItemStack[] extractItem(boolean doRemove, ForgeDirection from, int maxItemCount) + { + return inv.extractItem(doRemove, side, maxItemCount); + } +} diff --git a/forestry_common/core/forestry/core/items/ItemArmorNaturalist.java b/forestry_common/core/forestry/core/items/ItemArmorNaturalist.java new file mode 100755 index 000000000..7a4939350 --- /dev/null +++ b/forestry_common/core/forestry/core/items/ItemArmorNaturalist.java @@ -0,0 +1,75 @@ +/******************************************************************************* + * Copyright 2011-2014 by SirSengir + * + * This work is licensed under a Creative Commons Attribution-NonCommercial-NoDerivs 3.0 Unported License. + * + * To view a copy of this license, visit http://creativecommons.org/licenses/by-nc-nd/3.0/. + ******************************************************************************/ +package forestry.core.items; + +import net.minecraft.client.renderer.texture.IIconRegister; +import net.minecraft.entity.Entity; +import net.minecraft.entity.player.EntityPlayer; +import net.minecraft.item.ItemArmor; +import net.minecraft.item.ItemStack; +import net.minecraft.util.IIcon; + +import cpw.mods.fml.relauncher.Side; +import cpw.mods.fml.relauncher.SideOnly; + +import forestry.api.core.IArmorNaturalist; +import forestry.core.CreativeTabForestry; +import forestry.core.config.Defaults; +import forestry.core.render.TextureManager; +import forestry.core.utils.StringUtil; + +public class ItemArmorNaturalist extends ItemArmor implements IArmorNaturalist { + + public ItemArmorNaturalist(int slot) { + super(ArmorMaterial.CLOTH, 0, slot); + this.setMaxDamage(100); + setCreativeTab(CreativeTabForestry.tabForestry); + } + + public String getArmorTexture(ItemStack stack, Entity entity, int slot, int layer) { + return Defaults.ID + ":" + Defaults.TEXTURE_NATURALIST_ARMOR_PRIMARY; + } + + @Override + public String getItemStackDisplayName(ItemStack itemstack) { + return StringUtil.localize(getUnlocalizedName(itemstack)); + } + + @SideOnly(Side.CLIENT) + @Override + public void registerIcons(IIconRegister register) { + itemIcon = TextureManager.getInstance().registerTex(register, getUnlocalizedName().replace("item.", "")); + } + + @SideOnly(Side.CLIENT) + @Override + public IIcon getIconFromDamageForRenderPass(int par1, int par2) { + return itemIcon; + } + + @Override + public boolean requiresMultipleRenderPasses() { + return false; + } + + @Override + public int getColorFromItemStack(ItemStack itemstack, int renderPass) { + return 0xffffff; + } + + @Override + public boolean hasColor(ItemStack itemstack) { + return false; + } + + @Override + public boolean canSeePollination(EntityPlayer player, ItemStack armor, boolean doSee) { + return armorType == 0; + } + +} diff --git a/forestry_common/core/forestry/core/items/ItemAssemblyKit.java b/forestry_common/core/forestry/core/items/ItemAssemblyKit.java new file mode 100755 index 000000000..2a7f68a53 --- /dev/null +++ b/forestry_common/core/forestry/core/items/ItemAssemblyKit.java @@ -0,0 +1,59 @@ +/******************************************************************************* + * Copyright 2011-2014 by SirSengir + * + * This work is licensed under a Creative Commons Attribution-NonCommercial-NoDerivs 3.0 Unported License. + * + * To view a copy of this license, visit http://creativecommons.org/licenses/by-nc-nd/3.0/. + ******************************************************************************/ +package forestry.core.items; + +import net.minecraft.entity.item.EntityItem; +import net.minecraft.entity.player.EntityPlayer; +import net.minecraft.item.ItemStack; +import net.minecraft.util.MathHelper; +import net.minecraft.world.World; + +import forestry.core.proxy.Proxies; + +public class ItemAssemblyKit extends ItemForestry { + private final ItemStack assembled; + private final boolean motionOnOpen; + + public ItemAssemblyKit(ItemStack assembled) { + this(assembled, false); + } + + public ItemAssemblyKit(ItemStack assembled, boolean motionOnOpen) { + super(); + maxStackSize = 24; + this.assembled = assembled; + this.motionOnOpen = motionOnOpen; + } + + @Override + public ItemStack onItemRightClick(ItemStack itemstack, World world, EntityPlayer entityplayer) { + if (Proxies.common.isSimulating(world)) { + itemstack.stackSize--; + EntityItem entity = new EntityItem(world, entityplayer.posX, entityplayer.posY, entityplayer.posZ, assembled.copy()); + + if (motionOnOpen) { + float f1 = 0.3F; + entity.motionX = -MathHelper.sin((entityplayer.rotationYaw / 180F) * 3.141593F) + * MathHelper.cos((entityplayer.rotationPitch / 180F) * 3.141593F) * f1; + entity.motionZ = MathHelper.cos((entityplayer.rotationYaw / 180F) * 3.141593F) + * MathHelper.cos((entityplayer.rotationPitch / 180F) * 3.141593F) * f1; + entity.motionY = -MathHelper.sin((entityplayer.rotationPitch / 180F) * 3.141593F) * f1 + 0.1F; + f1 = 0.02F; + float f3 = world.rand.nextFloat() * 3.141593F * 2.0F; + f1 *= world.rand.nextFloat(); + entity.motionX += Math.cos(f3) * f1; + entity.motionY += (world.rand.nextFloat() - world.rand.nextFloat()) * 0.1F; + entity.motionZ += Math.sin(f3) * f1; + } + + world.spawnEntityInWorld(entity); + } + return itemstack; + } + +} diff --git a/forestry_common/core/forestry/core/items/ItemCrated.java b/forestry_common/core/forestry/core/items/ItemCrated.java new file mode 100755 index 000000000..8ceae8c6a --- /dev/null +++ b/forestry_common/core/forestry/core/items/ItemCrated.java @@ -0,0 +1,95 @@ +/******************************************************************************* + * Copyright 2011-2014 by SirSengir + * + * This work is licensed under a Creative Commons Attribution-NonCommercial-NoDerivs 3.0 Unported License. + * + * To view a copy of this license, visit http://creativecommons.org/licenses/by-nc-nd/3.0/. + ******************************************************************************/ +package forestry.core.items; + +import java.util.Locale; + +import net.minecraft.client.renderer.texture.IIconRegister; +import net.minecraft.entity.item.EntityItem; +import net.minecraft.entity.player.EntityPlayer; +import net.minecraft.item.Item; +import net.minecraft.item.ItemStack; +import net.minecraft.util.MathHelper; +import net.minecraft.world.World; + +import cpw.mods.fml.relauncher.Side; +import cpw.mods.fml.relauncher.SideOnly; + +import forestry.api.recipes.IGenericCrate; +import forestry.core.proxy.Proxies; +import forestry.core.render.TextureManager; +import forestry.core.utils.StringUtil; + +public class ItemCrated extends Item implements IGenericCrate { + + private ItemStack contained; + + public ItemCrated() { + this(null); + } + + public ItemCrated(ItemStack contained) { + super(); + this.contained = contained; + } + + @Override + public void setContained(ItemStack crated, ItemStack contained) { + this.contained = contained; + } + + @Override + public ItemStack getContained(ItemStack crate) { + return contained; + } + + @Override + public ItemStack onItemRightClick(ItemStack itemstack, World world, EntityPlayer entityplayer) { + + if (Proxies.common.isSimulating(world)) { + if (contained == null) + return itemstack; + + itemstack.stackSize--; + EntityItem entity = new EntityItem(world, entityplayer.posX, entityplayer.posY, entityplayer.posZ, new ItemStack(contained.getItem(), 9, + contained.getItemDamage())); + entity.delayBeforeCanPickup = 40; + + float f1 = 0.3F; + entity.motionX = -MathHelper.sin((entityplayer.rotationYaw / 180F) * 3.141593F) * MathHelper.cos((entityplayer.rotationPitch / 180F) * 3.141593F) + * f1; + entity.motionZ = MathHelper.cos((entityplayer.rotationYaw / 180F) * 3.141593F) * MathHelper.cos((entityplayer.rotationPitch / 180F) * 3.141593F) + * f1; + entity.motionY = -MathHelper.sin((entityplayer.rotationPitch / 180F) * 3.141593F) * f1 + 0.1F; + f1 = 0.02F; + float f3 = world.rand.nextFloat() * 3.141593F * 2.0F; + f1 *= world.rand.nextFloat(); + entity.motionX += Math.cos(f3) * f1; + entity.motionY += (world.rand.nextFloat() - world.rand.nextFloat()) * 0.1F; + entity.motionZ += Math.sin(f3) * f1; + + world.spawnEntityInWorld(entity); + } + return itemstack; + } + + @Override + public String getItemStackDisplayName(ItemStack itemstack) { + if (contained != null) + return StringUtil.localize("item.crated.adj") + " " + Proxies.common.getDisplayName(contained); + else + return StringUtil.localize("item.crated.unknown"); + } + + @SideOnly(Side.CLIENT) + @Override + public void registerIcons(IIconRegister register) { + itemIcon = TextureManager.getInstance().registerTex(register, "crates/" + getUnlocalizedName().replace("item.crated", "").toLowerCase(Locale.ENGLISH)); + } + +} diff --git a/forestry_common/core/forestry/core/items/ItemForestry.java b/forestry_common/core/forestry/core/items/ItemForestry.java new file mode 100755 index 000000000..869bf0eee --- /dev/null +++ b/forestry_common/core/forestry/core/items/ItemForestry.java @@ -0,0 +1,63 @@ +/******************************************************************************* + * Copyright 2011-2014 by SirSengir + * + * This work is licensed under a Creative Commons Attribution-NonCommercial-NoDerivs 3.0 Unported License. + * + * To view a copy of this license, visit http://creativecommons.org/licenses/by-nc-nd/3.0/. + ******************************************************************************/ +package forestry.core.items; + +import net.minecraft.client.renderer.texture.IIconRegister; +import net.minecraft.entity.player.EntityPlayer; +import net.minecraft.item.Item; +import net.minecraft.item.ItemDye; +import net.minecraft.item.ItemStack; +import net.minecraft.world.World; + +import cpw.mods.fml.relauncher.Side; +import cpw.mods.fml.relauncher.SideOnly; + +import forestry.core.CreativeTabForestry; +import forestry.core.proxy.Proxies; +import forestry.core.render.TextureManager; +import forestry.core.utils.StringUtil; + +public class ItemForestry extends Item { + + private boolean isBonemeal = false; + + public ItemForestry() { + super(); + maxStackSize = 64; + setCreativeTab(CreativeTabForestry.tabForestry); + } + + public ItemForestry setBonemeal(boolean isBonemeal) { + this.isBonemeal = isBonemeal; + return this; + } + + @Override + public boolean onItemUse(ItemStack itemstack, EntityPlayer player, World world, int x, int y, int z, int par7, float par8, float par9, float par10) { + if(isBonemeal) { + if(ItemDye.applyBonemeal(itemstack, world, x, y, z, player)) { + if(Proxies.common.isSimulating(world)) + world.playAuxSFX(2005, x, y, z, 0); + + return true; + } + } + return super.onItemUse(itemstack, player, world, x, y, z, par7, par8, par9, par10); + } + + @Override + public String getItemStackDisplayName(ItemStack itemstack) { + return StringUtil.localize(getUnlocalizedName(itemstack)); + } + + @SideOnly(Side.CLIENT) + @Override + public void registerIcons(IIconRegister register) { + itemIcon = TextureManager.getInstance().registerTex(register, getUnlocalizedName().replace("item.", "")); + } +} diff --git a/forestry_common/core/forestry/core/items/ItemForestryBlock.java b/forestry_common/core/forestry/core/items/ItemForestryBlock.java new file mode 100755 index 000000000..115b01fa4 --- /dev/null +++ b/forestry_common/core/forestry/core/items/ItemForestryBlock.java @@ -0,0 +1,44 @@ +/******************************************************************************* + * Copyright 2011-2014 by SirSengir + * + * This work is licensed under a Creative Commons Attribution-NonCommercial-NoDerivs 3.0 Unported License. + * + * To view a copy of this license, visit http://creativecommons.org/licenses/by-nc-nd/3.0/. + ******************************************************************************/ +package forestry.core.items; + +import net.minecraft.block.Block; +import net.minecraft.item.ItemBlock; +import net.minecraft.item.ItemStack; + +import forestry.core.utils.StringUtil; + +public class ItemForestryBlock extends ItemBlock { + + + public ItemForestryBlock(Block block) { + super(block); + setMaxDamage(0); + setHasSubtypes(true); + } + + @Override + public int getMetadata(int i) { + return i; + } + + protected Block getBlock() { + return field_150939_a; + } + + @Override + public String getItemStackDisplayName(ItemStack itemstack) { + return StringUtil.localize(getUnlocalizedName(itemstack)); + } + + @Override + public String getUnlocalizedName(ItemStack itemstack) { + return getBlock().getUnlocalizedName() + "." + itemstack.getItemDamage(); + } + +} diff --git a/forestry_common/core/forestry/core/items/ItemForestryFood.java b/forestry_common/core/forestry/core/items/ItemForestryFood.java new file mode 100755 index 000000000..158da86ee --- /dev/null +++ b/forestry_common/core/forestry/core/items/ItemForestryFood.java @@ -0,0 +1,109 @@ +/******************************************************************************* + * Copyright 2011-2014 by SirSengir + * + * This work is licensed under a Creative Commons Attribution-NonCommercial-NoDerivs 3.0 Unported License. + * + * To view a copy of this license, visit http://creativecommons.org/licenses/by-nc-nd/3.0/. + ******************************************************************************/ +package forestry.core.items; + +import net.minecraft.client.renderer.texture.IIconRegister; +import net.minecraft.entity.player.EntityPlayer; +import net.minecraft.item.EnumAction; +import net.minecraft.item.Item; +import net.minecraft.item.ItemStack; +import net.minecraft.potion.PotionEffect; +import net.minecraft.world.World; + +import cpw.mods.fml.relauncher.Side; +import cpw.mods.fml.relauncher.SideOnly; + +import forestry.core.CreativeTabForestry; +import forestry.core.render.TextureManager; +import forestry.core.utils.StringUtil; + +public class ItemForestryFood extends Item { + + private boolean isAlwaysEdible = false; + private boolean isDrink = false; + + private int healAmount = 0; + private final float saturationModifier; + + private int potionId; + private int potionDuration; + private int potionAmplifier; + private float potionEffectProbability; + + public ItemForestryFood(int heal) { + this(heal, 0.6f); + } + + public ItemForestryFood(int heal, float saturation) { + super(); + healAmount = heal; + saturationModifier = saturation; + setCreativeTab(CreativeTabForestry.tabForestry); + } + + @Override + public ItemStack onEaten(ItemStack itemstack, World world, EntityPlayer entityplayer) { + itemstack.stackSize--; + entityplayer.getFoodStats().addStats(healAmount, saturationModifier); + world.playSoundAtEntity(entityplayer, "random.burp", 0.5F, world.rand.nextFloat() * 0.1F + 0.9F); + if (!world.isRemote && potionId > 0 && world.rand.nextFloat() < potionEffectProbability) + entityplayer.addPotionEffect(new PotionEffect(potionId, potionDuration * 20, potionAmplifier)); + + return itemstack; + } + + @Override + public int getMaxItemUseDuration(ItemStack itemstack) { + return 32; + } + + @Override + public EnumAction getItemUseAction(ItemStack itemstack) { + if (isDrink) + return EnumAction.drink; + else + return EnumAction.eat; + } + + @Override + public ItemStack onItemRightClick(ItemStack itemstack, World world, EntityPlayer entityplayer) { + if (entityplayer.canEat(isAlwaysEdible)) + entityplayer.setItemInUse(itemstack, getMaxItemUseDuration(itemstack)); + return itemstack; + } + + public ItemForestryFood setIsDrink() { + isDrink = true; + return this; + } + + public ItemForestryFood setPotionEffect(int i, int j, int k, float f) { + potionId = i; + potionDuration = j; + potionAmplifier = k; + potionEffectProbability = f; + return this; + } + + public ItemForestryFood setAlwaysEdible() { + isAlwaysEdible = true; + return this; + } + + @Override + public String getItemStackDisplayName(ItemStack itemstack) { + return StringUtil.localize(getUnlocalizedName(itemstack)); + } + + @SideOnly(Side.CLIENT) + @Override + public void registerIcons(IIconRegister register) { + itemIcon = TextureManager.getInstance().registerTex(register, getUnlocalizedName().replace("item.", "")); + } + +} diff --git a/forestry_common/core/forestry/core/items/ItemForestryPickaxe.java b/forestry_common/core/forestry/core/items/ItemForestryPickaxe.java new file mode 100755 index 000000000..d59d0c857 --- /dev/null +++ b/forestry_common/core/forestry/core/items/ItemForestryPickaxe.java @@ -0,0 +1,31 @@ +/******************************************************************************* + * Copyright 2011-2014 by SirSengir + * + * This work is licensed under a Creative Commons Attribution-NonCommercial-NoDerivs 3.0 Unported License. + * + * To view a copy of this license, visit http://creativecommons.org/licenses/by-nc-nd/3.0/. + ******************************************************************************/ +package forestry.core.items; + +import net.minecraft.block.Block; +import net.minecraft.init.Blocks; +import net.minecraft.item.ItemStack; + +import forestry.core.config.ForestryBlock; + +public class ItemForestryPickaxe extends ItemForestryTool { + + private static Block blocksEffectiveAgainst[]; + + static { + blocksEffectiveAgainst = (new Block[] { Blocks.cobblestone, Blocks.stone, Blocks.sandstone, Blocks.mossy_cobblestone, Blocks.iron_ore, Blocks.iron_block, + Blocks.coal_ore, Blocks.gold_block, Blocks.brick_block, Blocks.nether_brick, Blocks.netherrack, Blocks.gold_ore, Blocks.diamond_ore, Blocks.diamond_block, + Blocks.ice, Blocks.netherrack, Blocks.lapis_ore, Blocks.lapis_block, ForestryBlock.resources, ForestryBlock.beehives, ForestryBlock.engine, + ForestryBlock.factoryTESR, ForestryBlock.factoryPlain }); + } + + public ItemForestryPickaxe(ItemStack remnants) { + super(blocksEffectiveAgainst, remnants); + } + +} diff --git a/forestry_common/core/forestry/core/items/ItemForestryShovel.java b/forestry_common/core/forestry/core/items/ItemForestryShovel.java new file mode 100755 index 000000000..925028b22 --- /dev/null +++ b/forestry_common/core/forestry/core/items/ItemForestryShovel.java @@ -0,0 +1,29 @@ +/******************************************************************************* + * Copyright 2011-2014 by SirSengir + * + * This work is licensed under a Creative Commons Attribution-NonCommercial-NoDerivs 3.0 Unported License. + * + * To view a copy of this license, visit http://creativecommons.org/licenses/by-nc-nd/3.0/. + ******************************************************************************/ +package forestry.core.items; + +import net.minecraft.block.Block; +import net.minecraft.init.Blocks; +import net.minecraft.item.ItemStack; + +import forestry.core.config.ForestryBlock; + +public class ItemForestryShovel extends ItemForestryTool { + + private static Block blocksEffectiveAgainst[]; + + static { + blocksEffectiveAgainst = (new Block[] { Blocks.grass, Blocks.dirt, Blocks.sand, Blocks.gravel, Blocks.snow_layer, Blocks.snow, Blocks.clay, + Blocks.farmland, ForestryBlock.soil }); + } + + public ItemForestryShovel( ItemStack remnants) { + super(blocksEffectiveAgainst, remnants); + } + +} diff --git a/forestry_common/core/forestry/core/items/ItemForestryTool.java b/forestry_common/core/forestry/core/items/ItemForestryTool.java new file mode 100755 index 000000000..c5a8cf264 --- /dev/null +++ b/forestry_common/core/forestry/core/items/ItemForestryTool.java @@ -0,0 +1,81 @@ +/******************************************************************************* + * Copyright 2011-2014 by SirSengir + * + * This work is licensed under a Creative Commons Attribution-NonCommercial-NoDerivs 3.0 Unported License. + * + * To view a copy of this license, visit http://creativecommons.org/licenses/by-nc-nd/3.0/. + ******************************************************************************/ +package forestry.core.items; + +import net.minecraft.block.Block; +import net.minecraft.entity.EntityLivingBase; +import net.minecraft.entity.item.EntityItem; +import net.minecraft.item.ItemStack; +import net.minecraft.world.World; + +import cpw.mods.fml.common.eventhandler.SubscribeEvent; + +import net.minecraftforge.common.ForgeHooks; +import net.minecraftforge.event.entity.player.PlayerDestroyItemEvent; + +import forestry.core.proxy.Proxies; + +public class ItemForestryTool extends ItemForestry { + + private final ItemStack remnants; + private final float efficiencyOnProperMaterial; + private final Block[] blocksEffectiveAgainst; + + public ItemForestryTool(Block[] blocksEffectiveAgainst, ItemStack remnants) { + super(); + this.blocksEffectiveAgainst = blocksEffectiveAgainst; + this.maxStackSize = 1; + efficiencyOnProperMaterial = 6F; + setMaxDamage(200); + this.remnants = remnants; + } + + @Override + public float func_150893_a(ItemStack itemstack, Block block) { + for (int i = 0; i < blocksEffectiveAgainst.length; i++) + if (blocksEffectiveAgainst[i] == block) + return efficiencyOnProperMaterial; + return 1.0F; + } + + @Override + public float getDigSpeed(ItemStack itemstack, Block block, int md) { + if (ForgeHooks.isToolEffective(itemstack, block, md)) + return efficiencyOnProperMaterial; + return func_150893_a(itemstack, block); + } + + @SubscribeEvent + public void onDestroyCurrentItem(PlayerDestroyItemEvent event) { + if (event.original == null || event.original.getItem() != this) + return; + + if (Proxies.common.isSimulating(event.entityPlayer.worldObj)) { + EntityItem entity = new EntityItem(event.entityPlayer.worldObj, event.entityPlayer.posX, event.entityPlayer.posY, event.entityPlayer.posZ, + remnants.copy()); + event.entityPlayer.worldObj.spawnEntityInWorld(entity); + } + } + + @Override + public boolean onBlockDestroyed(ItemStack itemstack, World world, Block block, int j, int k, int l, EntityLivingBase entityliving) { + itemstack.damageItem(1, entityliving); + return true; + } + + /*@Override + public float getDamageVsEntity(Entity entity, ItemStack itemstack) { + return 1; + }*/ + + @Override + public boolean isFull3D() { + return true; + } + +} diff --git a/forestry_common/core/forestry/core/items/ItemFruit.java b/forestry_common/core/forestry/core/items/ItemFruit.java new file mode 100755 index 000000000..4a3c0460c --- /dev/null +++ b/forestry_common/core/forestry/core/items/ItemFruit.java @@ -0,0 +1,100 @@ +/******************************************************************************* + * Copyright 2011-2014 by SirSengir + * + * This work is licensed under a Creative Commons Attribution-NonCommercial-NoDerivs 3.0 Unported License. + * + * To view a copy of this license, visit http://creativecommons.org/licenses/by-nc-nd/3.0/. + ******************************************************************************/ +package forestry.core.items; + +import java.util.List; +import java.util.Locale; + +import net.minecraft.client.renderer.texture.IIconRegister; +import net.minecraft.creativetab.CreativeTabs; +import net.minecraft.item.Item; +import net.minecraft.item.ItemStack; +import net.minecraft.util.IIcon; + +import cpw.mods.fml.relauncher.Side; +import cpw.mods.fml.relauncher.SideOnly; + +import net.minecraftforge.oredict.OreDictionary; + +import forestry.core.render.TextureManager; +import forestry.core.utils.StringUtil; + +public class ItemFruit extends ItemForestryFood { + + public static enum EnumFruit { + CHERRY("cropCherry"), WALNUT("cropWalnut"), CHESTNUT("cropChestnut"), LEMON("cropLemon"), PLUM("cropPlum"), DATES("cropDate"), PAPAYA("cropPapaya");//, COCONUT("cropCoconut"); + + final String oreDict; + + private EnumFruit(String oreDict) { + this.oreDict = oreDict; + } + + private static IIcon[] icons; + + public static void registerIcons(IIconRegister register) { + icons = new IIcon[values().length]; + for (int i = 0; i < values().length; i++) + icons[i] = TextureManager.getInstance().registerTex(register, "fruits/" + values()[i].toString().toLowerCase(Locale.ENGLISH)); + } + + public IIcon getIcon() { + return icons[ordinal()]; + } + } + + public ItemFruit() { + super(1, 0.2f); + setMaxDamage(0); + setHasSubtypes(true); + registerOreDictionary(); + } + + private void registerOreDictionary() { + for (EnumFruit def : EnumFruit.values()) + OreDictionary.registerOre(def.oreDict, new ItemStack(this, 1, def.ordinal())); + } + + @Override + public boolean isDamageable() { + return false; + } + + @Override + public boolean isRepairable() { + return false; + } + + @SideOnly(Side.CLIENT) + @Override + public void registerIcons(IIconRegister register) { + EnumFruit.registerIcons(register); + } + + @SideOnly(Side.CLIENT) + @Override + public IIcon getIconFromDamage(int meta) { + return EnumFruit.values()[meta].getIcon(); + } + + @SuppressWarnings({ "rawtypes", "unchecked" }) + @Override + public void getSubItems(Item item, CreativeTabs par2CreativeTabs, List itemList) { + for (int i = 0; i < EnumFruit.values().length; i++) + itemList.add(new ItemStack(this, 1, i)); + } + + @Override + public String getItemStackDisplayName(ItemStack itemstack) { + if (itemstack.getItemDamage() < 0 || itemstack.getItemDamage() >= EnumFruit.values().length) + return null; + + return StringUtil.localize("item.fruit." + EnumFruit.values()[itemstack.getItemDamage()].toString().toLowerCase(Locale.ENGLISH)); + } + +} diff --git a/forestry_common/core/forestry/core/items/ItemInventoried.java b/forestry_common/core/forestry/core/items/ItemInventoried.java new file mode 100755 index 000000000..3b92b0b7a --- /dev/null +++ b/forestry_common/core/forestry/core/items/ItemInventoried.java @@ -0,0 +1,32 @@ +/******************************************************************************* + * Copyright 2011-2014 by SirSengir + * + * This work is licensed under a Creative Commons Attribution-NonCommercial-NoDerivs 3.0 Unported License. + * + * To view a copy of this license, visit http://creativecommons.org/licenses/by-nc-nd/3.0/. + ******************************************************************************/ +package forestry.core.items; + +import net.minecraft.entity.player.EntityPlayer; +import net.minecraft.entity.player.EntityPlayerMP; +import net.minecraft.item.ItemStack; + +import forestry.core.gui.ContainerItemInventory; +import forestry.core.interfaces.IInventoriedItem; + +public abstract class ItemInventoried extends ItemForestry implements IInventoriedItem { + + public ItemInventoried() { + super(); + } + + @Override + public boolean onDroppedByPlayer(ItemStack itemstack, EntityPlayer player) { + if (itemstack != null && + player instanceof EntityPlayerMP && + player.openContainer instanceof ContainerItemInventory) + ((EntityPlayerMP) player).closeScreen(); + + return super.onDroppedByPlayer(itemstack, player); + } +} diff --git a/forestry_common/core/forestry/core/items/ItemLiquidContainer.java b/forestry_common/core/forestry/core/items/ItemLiquidContainer.java new file mode 100755 index 000000000..5e4b725a2 --- /dev/null +++ b/forestry_common/core/forestry/core/items/ItemLiquidContainer.java @@ -0,0 +1,236 @@ +/******************************************************************************* + * Copyright 2011-2014 by SirSengir + * + * This work is licensed under a Creative Commons Attribution-NonCommercial-NoDerivs 3.0 Unported License. + * + * To view a copy of this license, visit http://creativecommons.org/licenses/by-nc-nd/3.0/. + ******************************************************************************/ +package forestry.core.items; + +import java.util.Locale; + +import net.minecraft.block.Block; +import net.minecraft.client.renderer.texture.IIconRegister; +import net.minecraft.entity.player.EntityPlayer; +import net.minecraft.item.EnumAction; +import net.minecraft.item.Item; +import net.minecraft.item.ItemStack; +import net.minecraft.util.IIcon; +import net.minecraft.util.MovingObjectPosition; +import net.minecraft.util.MovingObjectPosition.MovingObjectType; +import net.minecraft.world.World; + +import cpw.mods.fml.relauncher.Side; +import cpw.mods.fml.relauncher.SideOnly; + +import net.minecraftforge.fluids.FluidContainerRegistry.FluidContainerData; +import net.minecraftforge.fluids.FluidStack; +import net.minecraftforge.fluids.IFluidBlock; + +import forestry.core.CreativeTabForestry; +import forestry.core.proxy.Proxies; +import forestry.core.render.TextureManager; +import forestry.core.utils.LiquidHelper; +import forestry.core.utils.StringUtil; + +public class ItemLiquidContainer extends Item { + + public static enum EnumContainerType { + GLASS, JAR, CAN, CAPSULE, REFRACTORY + } + + private boolean isDrink = false; + private boolean isAlwaysEdible = false; + + private int healAmount = 0; + private float saturationModifier = 0.0f; + + private final EnumContainerType type; + private final int colour; + + public ItemLiquidContainer(EnumContainerType type, int colour) { + super(); + this.type = type; + this.colour = colour; + setCreativeTab(CreativeTabForestry.tabForestry); + setMaxStackSize(16); + } + + private int getMatchingSlot(EntityPlayer player, ItemStack stack) { + + for (int slot = 0; slot < player.inventory.getSizeInventory(); slot++) { + ItemStack slotStack = player.inventory.getStackInSlot(slot); + + if (slotStack == null) + return slot; + + if (!slotStack.isItemEqual(stack)) + continue; + + int space = slotStack.getMaxStackSize() - slotStack.stackSize; + if (space >= stack.stackSize) + return slot; + } + + return -1; + } + + @Override + public ItemStack onEaten(ItemStack itemstack, World world, EntityPlayer entityplayer) { + if (!isDrink) + return itemstack; + + itemstack.stackSize--; + entityplayer.getFoodStats().addStats(this.getHealAmount(), this.getSaturationModifier()); + world.playSoundAtEntity(entityplayer, "random.burp", 0.5F, world.rand.nextFloat() * 0.1F + 0.9F); + /* + * if (!world.isRemote && potionId > 0 && world.rand.nextFloat() < potionEffectProbability) entityplayer.addPotionEffect(new PotionEffect(potionId, + * potionDuration * 20, potionAmplifier)); + */ + + return itemstack; + } + + @Override + public int getMaxItemUseDuration(ItemStack itemstack) { + if (isDrink) + return 32; + else + return super.getMaxItemUseDuration(itemstack); + } + + @Override + public EnumAction getItemUseAction(ItemStack itemstack) { + if (isDrink) + return EnumAction.drink; + else + return EnumAction.none; + } + + @Override + public ItemStack onItemRightClick(ItemStack itemstack, World world, EntityPlayer entityplayer) { + + if (!Proxies.common.isSimulating(world)) + return itemstack; + + // / DRINKS can be drunk + if (isDrink) { + if (entityplayer.canEat(isAlwaysEdible)) + entityplayer.setItemInUse(itemstack, getMaxItemUseDuration(itemstack)); + return itemstack; + } + + // / Otherwise check empty container + MovingObjectPosition movingobjectposition = this.getMovingObjectPositionFromPlayer(world, entityplayer, true); + if (movingobjectposition != null && movingobjectposition.typeOfHit == MovingObjectType.BLOCK) { + + int i = movingobjectposition.blockX; + int j = movingobjectposition.blockY; + int k = movingobjectposition.blockZ; + Block targetedBlock = world.getBlock(i, j, k); + //int targetedMeta = world.getBlockMetadata(i, j, k); + + if(!(targetedBlock instanceof IFluidBlock)) + return itemstack; + IFluidBlock fluidBlock = (IFluidBlock) targetedBlock; + FluidStack drainable = fluidBlock.drain(world, i, j, k, false); + if(drainable == null || drainable.amount <= 0) + return itemstack; + + // Check whether there is valid container for the liquid. + FluidContainerData container = LiquidHelper.getEmptyContainer(itemstack, drainable); + if (container == null) + return itemstack; + + // Search for a slot to stow a filled container in player's + // inventory + int slot = getMatchingSlot(entityplayer, container.filledContainer); + if (slot < 0) + return itemstack; + + if (entityplayer.inventory.getStackInSlot(slot) == null) + entityplayer.inventory.setInventorySlotContents(slot, container.filledContainer.copy()); + else + entityplayer.inventory.getStackInSlot(slot).stackSize++; + + // Remove consumed liquid block in world + world.setBlockToAir(i, j, k); + // Remove consumed empty container + itemstack.stackSize--; + + // Notify player that his inventory has changed. + Proxies.net.inventoryChangeNotify(entityplayer); + + return itemstack; + } + + return itemstack; + + } + + public int getHealAmount() { + return healAmount; + } + + public float getSaturationModifier() { + return saturationModifier; + } + + public ItemLiquidContainer setDrink(int healAmount, float saturationModifier) { + isDrink = true; + this.healAmount = healAmount; + this.saturationModifier = saturationModifier; + return this; + } + + /* + * public ItemLiquidContainer setPotionEffect(int i, int j, int k, float f) { potionId = i; potionDuration = j; potionAmplifier = k; potionEffectProbability + * = f; return this; } + */ + + public ItemLiquidContainer setAlwaysEdible() { + isAlwaysEdible = true; + return this; + } + + @Override + public String getItemStackDisplayName(ItemStack itemstack) { + return StringUtil.localize(getUnlocalizedName(itemstack)); + } + + /* ICONS */ + @SideOnly(Side.CLIENT) + private IIcon[] icons; + + @SideOnly(Side.CLIENT) + @Override + public void registerIcons(IIconRegister register) { + icons = new IIcon[2]; + icons[0] = TextureManager.getInstance().registerTex(register, "liquids/" + type.toString().toLowerCase(Locale.ENGLISH) + ".bottle"); + icons[1] = TextureManager.getInstance().registerTex(register, "liquids/" + type.toString().toLowerCase(Locale.ENGLISH) + ".contents"); + } + + @SideOnly(Side.CLIENT) + @Override + public IIcon getIconFromDamageForRenderPass(int i, int j) { + if (j > 0 && colour >= 0) + return icons[1]; + else + return icons[0]; + } + + // Return true to enable color overlay + @Override + public boolean requiresMultipleRenderPasses() { + return true; + } + + @Override + public int getColorFromItemStack(ItemStack itemstack, int j) { + if (j > 0 && colour >= 0) + return colour; + else + return 0xffffff; + } + +} diff --git a/forestry_common/core/forestry/core/items/ItemLiquids.java b/forestry_common/core/forestry/core/items/ItemLiquids.java new file mode 100755 index 000000000..6e7060639 --- /dev/null +++ b/forestry_common/core/forestry/core/items/ItemLiquids.java @@ -0,0 +1,35 @@ +/******************************************************************************* + * Copyright 2011-2014 by SirSengir + * + * This work is licensed under a Creative Commons Attribution-NonCommercial-NoDerivs 3.0 Unported License. + * + * To view a copy of this license, visit http://creativecommons.org/licenses/by-nc-nd/3.0/. + ******************************************************************************/ +package forestry.core.items; + +public class ItemLiquids extends ItemForestry { + + public ItemLiquids() { + super(); + setCreativeTab(null); + } + + @Override + public boolean isDamageable() { + return false; + } + + @Override + public boolean isRepairable() { + return false; + } + + /* + * //@Override Client side only public String getItemStackDisplayName(ItemStack itemstack) { switch(itemstack.getItemDamage()) { case 0: return "Liquid Honey"; + * case 1: return "Liquid Mead"; default: return "Unknown Item"; } } + * + * //@Override Client side only public int getIconFromDamage(int damage) { switch(damage) { case 0: return 76; case 1: return 77; default: return 0; } } + * + * @Override public void addCreativeItems(ArrayList itemList) { //for(int i = 0; i < 2; i++) // itemList.add(new ItemStack(this, 1, i)); } + */ +} diff --git a/forestry_common/core/forestry/core/items/ItemMisc.java b/forestry_common/core/forestry/core/items/ItemMisc.java new file mode 100755 index 000000000..31c0a8501 --- /dev/null +++ b/forestry_common/core/forestry/core/items/ItemMisc.java @@ -0,0 +1,81 @@ +/******************************************************************************* + * Copyright 2011-2014 by SirSengir + * + * This work is licensed under a Creative Commons Attribution-NonCommercial-NoDerivs 3.0 Unported License. + * + * To view a copy of this license, visit http://creativecommons.org/licenses/by-nc-nd/3.0/. + ******************************************************************************/ +package forestry.core.items; + +import java.util.List; + +import net.minecraft.client.renderer.texture.IIconRegister; +import net.minecraft.creativetab.CreativeTabs; +import net.minecraft.item.Item; +import net.minecraft.item.ItemStack; +import net.minecraft.util.IIcon; + +import cpw.mods.fml.relauncher.Side; +import cpw.mods.fml.relauncher.SideOnly; + +import forestry.core.render.TextureManager; +import forestry.core.utils.StringUtil; + +public class ItemMisc extends ItemForestry { + + String[] definition = new String[] { "pulsatingDust", "pulsatingMesh", "silkWisp", "wovenSilk", "dissipationCharge", "iceShard", "scentedPaneling" }; + + public ItemMisc() { + super(); + setMaxDamage(0); + setHasSubtypes(true); + } + + @Override + public boolean isDamageable() { + return false; + } + + @Override + public boolean isRepairable() { + return false; + } + + @Override + public String getItemStackDisplayName(ItemStack itemstack) { + if (itemstack.getItemDamage() >= definition.length || itemstack.getItemDamage() < 0) + return StringUtil.localize("item.unknown"); + else + return StringUtil.localize("item." + definition[itemstack.getItemDamage()]); + } + + /* ICONS */ + @SideOnly(Side.CLIENT) + private IIcon[] icons; + + @SideOnly(Side.CLIENT) + @Override + public void registerIcons(IIconRegister register) { + + icons = new IIcon[definition.length]; + for (int i = 0; i < definition.length; i++) + icons[i] = TextureManager.getInstance().registerTex(register, definition[i]); + + } + + @Override + public IIcon getIconFromDamage(int damage) { + if (damage >= definition.length || damage < 0) + return icons[0]; + else + return icons[damage]; + } + + @SuppressWarnings({ "rawtypes", "unchecked" }) + @Override + public void getSubItems(Item item, CreativeTabs par2CreativeTabs, List itemList) { + for (int i = 0; i < 7; i++) + itemList.add(new ItemStack(this, 1, i)); + } + +} diff --git a/forestry_common/core/forestry/core/items/ItemNBTTile.java b/forestry_common/core/forestry/core/items/ItemNBTTile.java new file mode 100755 index 000000000..df64fb5fa --- /dev/null +++ b/forestry_common/core/forestry/core/items/ItemNBTTile.java @@ -0,0 +1,30 @@ +/******************************************************************************* + * Copyright 2011-2014 by SirSengir + * + * This work is licensed under a Creative Commons Attribution-NonCommercial-NoDerivs 3.0 Unported License. + * + * To view a copy of this license, visit http://creativecommons.org/licenses/by-nc-nd/3.0/. + ******************************************************************************/ +package forestry.core.items; + +import java.util.List; + +import net.minecraft.block.Block; +import net.minecraft.entity.player.EntityPlayer; +import net.minecraft.item.ItemStack; + +public class ItemNBTTile extends ItemForestryBlock { + + public ItemNBTTile(Block block) { + super(block); + } + + @SuppressWarnings({ "rawtypes", "unchecked" }) + @Override + public void addInformation(ItemStack itemstack, EntityPlayer player, List info, boolean par4) { + if (!itemstack.hasTagCompound()) + return; + + info.add("There are still some scribbles on this."); + } +} diff --git a/forestry_common/core/forestry/core/items/ItemOverlay.java b/forestry_common/core/forestry/core/items/ItemOverlay.java new file mode 100755 index 000000000..dbfd29c78 --- /dev/null +++ b/forestry_common/core/forestry/core/items/ItemOverlay.java @@ -0,0 +1,129 @@ +/******************************************************************************* + * Copyright 2011-2014 by SirSengir + * + * This work is licensed under a Creative Commons Attribution-NonCommercial-NoDerivs 3.0 Unported License. + * + * To view a copy of this license, visit http://creativecommons.org/licenses/by-nc-nd/3.0/. + ******************************************************************************/ +package forestry.core.items; + +import java.util.List; + +import net.minecraft.client.renderer.texture.IIconRegister; +import net.minecraft.creativetab.CreativeTabs; +import net.minecraft.item.Item; +import net.minecraft.item.ItemStack; +import net.minecraft.util.IIcon; + +import cpw.mods.fml.relauncher.Side; +import cpw.mods.fml.relauncher.SideOnly; + +import forestry.core.config.Config; +import forestry.core.render.TextureManager; +import forestry.core.utils.StringUtil; + +public class ItemOverlay extends ItemForestry { + + public static class OverlayInfo { + + public String name; + public int primaryColor = 0; + public int secondaryColor = 0; + public boolean isSecret = false; + + public OverlayInfo(String name, int primaryColor, int secondaryColor) { + this.name = name; + this.primaryColor = primaryColor; + this.secondaryColor = secondaryColor; + } + + public OverlayInfo(String name, int primaryColor) { + this(name, primaryColor, 0); + } + + public OverlayInfo setIsSecret() { + isSecret = true; + return this; + } + } + + private final OverlayInfo[] overlays; + + public ItemOverlay(CreativeTabs tab, OverlayInfo... overlays) { + super(); + setMaxDamage(0); + setHasSubtypes(true); + setCreativeTab(tab); + + this.overlays = overlays; + } + + @Override + public boolean isDamageable() { + return false; + } + + @Override + public boolean isRepairable() { + return false; + } + + @SuppressWarnings({ "rawtypes", "unchecked" }) + @Override + public void getSubItems(Item item, CreativeTabs par2CreativeTabs, List itemList) { + for (int i = 0; i < overlays.length; i++) + if (Config.isDebug || !overlays[i].isSecret) + itemList.add(new ItemStack(this, 1, i)); + } + + /* ICONS */ + @SideOnly(Side.CLIENT) + private IIcon primaryIcon; + @SideOnly(Side.CLIENT) + private IIcon secondaryIcon; + + @SideOnly(Side.CLIENT) + @Override + public void registerIcons(IIconRegister register) { + primaryIcon = TextureManager.getInstance().registerTex(register, getUnlocalizedName().replace("item.", "") + ".0"); + if(overlays[0].secondaryColor != 0) + secondaryIcon = TextureManager.getInstance().registerTex(register, getUnlocalizedName().replace("item.", "") + ".1"); + } + + @Override + @SideOnly(Side.CLIENT) + public IIcon getIconFromDamageForRenderPass(int i, int j) { + if (j > 0 && overlays[i].secondaryColor != 0) + return secondaryIcon; + else + return primaryIcon; + } + + @Override + public int getRenderPasses(int metadata) { + return overlays[metadata].secondaryColor != 0 ? 2 : 1; + } + + @Override + public boolean requiresMultipleRenderPasses() { + return true; + } + + @Override + public String getItemStackDisplayName(ItemStack itemstack) { + if (itemstack.getItemDamage() < 0 || itemstack.getItemDamage() >= overlays.length) + return null; + + return StringUtil.localize(getUnlocalizedName() + "." + overlays[itemstack.getItemDamage()].name); + } + + @Override + public int getColorFromItemStack(ItemStack itemstack, int j) { + + if (j == 0 || overlays[itemstack.getItemDamage()].secondaryColor == 0) + return overlays[itemstack.getItemDamage()].primaryColor; + else + return overlays[itemstack.getItemDamage()].secondaryColor; + } + +} diff --git a/forestry_common/core/forestry/core/items/ItemPipette.java b/forestry_common/core/forestry/core/items/ItemPipette.java new file mode 100755 index 000000000..705b5aea6 --- /dev/null +++ b/forestry_common/core/forestry/core/items/ItemPipette.java @@ -0,0 +1,195 @@ +/******************************************************************************* + * Copyright 2011-2014 by SirSengir + * + * This work is licensed under a Creative Commons Attribution-NonCommercial-NoDerivs 3.0 Unported License. + * + * To view a copy of this license, visit http://creativecommons.org/licenses/by-nc-nd/3.0/. + ******************************************************************************/ +package forestry.core.items; + +import java.util.List; + +import net.minecraft.client.renderer.texture.IIconRegister; +import net.minecraft.entity.player.EntityPlayer; +import net.minecraft.item.ItemStack; +import net.minecraft.nbt.NBTTagCompound; +import net.minecraft.util.IIcon; + +import cpw.mods.fml.relauncher.Side; +import cpw.mods.fml.relauncher.SideOnly; + +import net.minecraftforge.fluids.FluidStack; + +import buildcraft.api.tools.IToolPipette; + +import forestry.api.core.INBTTagable; +import forestry.core.config.Config; +import forestry.core.config.Defaults; +import forestry.core.render.TextureManager; + +public class ItemPipette extends ItemForestry implements IToolPipette { + + class PipetteContents implements INBTTagable { + + FluidStack contents; + + public PipetteContents(NBTTagCompound nbttagcompound) { + if (nbttagcompound != null) + readFromNBT(nbttagcompound); + } + + @Override + public void readFromNBT(NBTTagCompound nbttagcompound) { + contents = FluidStack.loadFluidStackFromNBT(nbttagcompound); + } + + @Override + public void writeToNBT(NBTTagCompound nbttagcompound) { + if (contents != null) + contents.writeToNBT(nbttagcompound); + } + + public boolean isFull(int limit) { + if (contents == null) + return false; + + return contents.fluidID > 0 && contents.amount >= limit; + } + + public void addTooltip(List list) { + if (contents == null) + return; + + String descr = contents.getFluid().getLocalizedName(); + if (Config.isDebug) + descr += " (" + contents.amount + ")"; + + list.add(descr); + } + } + + public ItemPipette() { + super(); + setMaxStackSize(1); + setFull3D(); + } + + /** + * @return true if the item's stackTagCompound needs to be synchronized over SMP. + */ + @Override + public boolean getShareTag() { + return true; + } + + @Override + public boolean canPipette(ItemStack itemstack) { + PipetteContents contained = new PipetteContents(itemstack.getTagCompound()); + return !contained.isFull(1000); + } + + @Override + public int fill(ItemStack itemstack, FluidStack liquid, boolean doFill) { + PipetteContents contained = new PipetteContents(itemstack.getTagCompound()); + + int limit = getCapacity(itemstack); + int filled = 0; + + if (contained.contents == null) { + + if (liquid.amount > limit) + filled = limit; + else + filled = liquid.amount; + + contained.contents = new FluidStack(liquid.fluidID, filled); + filled = liquid.amount; + + } else { + + if (contained.contents.amount >= limit) + return 0; + if (!contained.contents.isFluidEqual(liquid)) + return 0; + + int space = limit - contained.contents.amount; + + if (liquid.amount > space) + filled = space; + else + filled = liquid.amount; + + contained.contents.amount += filled; + } + + if (doFill) { + NBTTagCompound nbttagcompound = new NBTTagCompound(); + contained.writeToNBT(nbttagcompound); + itemstack.setTagCompound(nbttagcompound); + itemstack.setItemDamage(1); + } + + return filled; + } + + @SuppressWarnings({ "rawtypes", "unchecked" }) + @Override + public void addInformation(ItemStack itemstack, EntityPlayer player, List list, boolean flag) { + PipetteContents contained = new PipetteContents(itemstack.getTagCompound()); + contained.addTooltip(list); + } + + /* ICONS */ + @SideOnly(Side.CLIENT) + private IIcon primaryIcon; + @SideOnly(Side.CLIENT) + private IIcon secondaryIcon; + + @SideOnly(Side.CLIENT) + @Override + public void registerIcons(IIconRegister register) { + primaryIcon = TextureManager.getInstance().registerTex(register, getUnlocalizedName().replace("item.", "") + ".0"); + secondaryIcon = TextureManager.getInstance().registerTex(register, getUnlocalizedName().replace("item.", "") + ".1"); + } + + @SideOnly(Side.CLIENT) + @Override + public IIcon getIconFromDamage(int damage) { + + if (damage <= 0) + return primaryIcon; + else + return secondaryIcon; + } + + @Override + public FluidStack drain(ItemStack pipette, int maxDrain, boolean doDrain) { + PipetteContents contained = new PipetteContents(pipette.getTagCompound()); + if (contained.contents == null || contained.contents.fluidID <= 0) + return null; + + int drained = maxDrain; + if (contained.contents.amount < drained) + drained = contained.contents.amount; + + if (doDrain) { + contained.contents.amount -= drained; + + if (contained.contents.amount <= 0) { + pipette.setTagCompound(null); + pipette.setItemDamage(0); + } else { + NBTTagCompound nbttagcompound = new NBTTagCompound(); + contained.writeToNBT(nbttagcompound); + pipette.setTagCompound(nbttagcompound); + } + } + + return new FluidStack(contained.contents.fluidID, drained); + } + + @Override + public int getCapacity(ItemStack pipette) { + return Defaults.BUCKET_VOLUME; + } +} diff --git a/forestry_common/core/forestry/core/items/ItemScoop.java b/forestry_common/core/forestry/core/items/ItemScoop.java new file mode 100755 index 000000000..bdf01eea7 --- /dev/null +++ b/forestry_common/core/forestry/core/items/ItemScoop.java @@ -0,0 +1,62 @@ +/******************************************************************************* + * Copyright 2011-2014 by SirSengir + * + * This work is licensed under a Creative Commons Attribution-NonCommercial-NoDerivs 3.0 Unported License. + * + * To view a copy of this license, visit http://creativecommons.org/licenses/by-nc-nd/3.0/. + ******************************************************************************/ +package forestry.core.items; + +import net.minecraft.block.Block; +import net.minecraft.entity.EntityLivingBase; +import net.minecraft.item.ItemStack; +import net.minecraft.world.World; + +import net.minecraftforge.common.ForgeHooks; + +import forestry.api.core.IToolScoop; +import forestry.api.core.Tabs; + +public class ItemScoop extends ItemForestry implements IToolScoop { + + private final float efficiencyOnProperMaterial; + + public ItemScoop() { + super(); + this.maxStackSize = 1; + efficiencyOnProperMaterial = 4.0F; + setMaxDamage(10); + setCreativeTab(Tabs.tabApiculture); + setMaxStackSize(1); + } + + @Override + public float func_150893_a(ItemStack itemstack, Block block) { + return 1.0F; + } + + @Override + public float getDigSpeed(ItemStack itemstack, Block block, int md) { + if (ForgeHooks.isToolEffective(itemstack, block, md)) + return efficiencyOnProperMaterial; + + return func_150893_a(itemstack, block); + } + + @Override + public boolean onBlockDestroyed(ItemStack itemstack, World world, Block block, int j, int k, int l, EntityLivingBase entityliving) { + itemstack.damageItem(1, entityliving); + return true; + } + + /*@Override + public float getDamageVsEntity(Entity entity, ItemStack itemstack) { + return 1; + }*/ + + @Override + public boolean isFull3D() { + return true; + } + +} diff --git a/forestry_common/core/forestry/core/items/ItemWrench.java b/forestry_common/core/forestry/core/items/ItemWrench.java new file mode 100755 index 000000000..ee5838195 --- /dev/null +++ b/forestry_common/core/forestry/core/items/ItemWrench.java @@ -0,0 +1,44 @@ +/******************************************************************************* + * Copyright 2011-2014 by SirSengir + * + * This work is licensed under a Creative Commons Attribution-NonCommercial-NoDerivs 3.0 Unported License. + * + * To view a copy of this license, visit http://creativecommons.org/licenses/by-nc-nd/3.0/. + ******************************************************************************/ +package forestry.core.items; + +import net.minecraft.block.Block; +import net.minecraft.entity.player.EntityPlayer; +import net.minecraft.item.ItemStack; +import net.minecraft.world.World; + +import net.minecraftforge.common.util.ForgeDirection; + +import buildcraft.api.tools.IToolWrench; + +public class ItemWrench extends ItemForestry implements IToolWrench { + + public ItemWrench() { + super(); + } + + @Override + public boolean onItemUseFirst(ItemStack stack, EntityPlayer player, World world, int x, int y, int z, int side, float hitX, float hitY, float hitZ) { + Block block = world.getBlock(x, y, z); + if (block.rotateBlock(world, x, y, z, ForgeDirection.getOrientation(side))) { + player.swingItem(); + return !world.isRemote; + } + return false; + } + + @Override + public boolean canWrench(EntityPlayer player, int x, int y, int z) { + return true; + } + + @Override + public void wrenchUsed(EntityPlayer player, int x, int y, int z) { + } + +} diff --git a/forestry_common/core/forestry/core/network/ClassMap.java b/forestry_common/core/forestry/core/network/ClassMap.java new file mode 100755 index 000000000..e0cc057db --- /dev/null +++ b/forestry_common/core/forestry/core/network/ClassMap.java @@ -0,0 +1,198 @@ +/******************************************************************************* + * Copyright 2011-2014 by SirSengir + * + * This work is licensed under a Creative Commons Attribution-NonCommercial-NoDerivs 3.0 Unported License. + * + * To view a copy of this license, visit http://creativecommons.org/licenses/by-nc-nd/3.0/. + ******************************************************************************/ +package forestry.core.network; + +import java.lang.reflect.Field; +import java.lang.reflect.Type; +import java.util.HashMap; +import java.util.LinkedList; + +import forestry.core.gadgets.TileForestry; + +public class ClassMap { + + @SuppressWarnings("rawtypes") + public static HashMap classMappers = new HashMap(); + + private LinkedList intMember = new LinkedList(); + private LinkedList floatMember = new LinkedList(); + private LinkedList booleanMember = new LinkedList(); + private LinkedList stringMember = new LinkedList(); + private LinkedList enumMember = new LinkedList(); + private LinkedList objectMember = new LinkedList(); + + public int intSize; + public int floatSize; + public int stringSize; + + private Field field; + + /** + * Writes the actual data to the packet payload + * + * @param obj + * {@link TileForestry} to write to packet + * @param intPayload + * @param floatPayload + * @param stringPayload + * @param index + */ + @SuppressWarnings("rawtypes") + public void setData(Object obj, int[] intPayload, float[] floatPayload, String[] stringPayload, IndexInPayload index) throws IllegalAccessException { + for (Field member : intMember) { + intPayload[index.intIndex] = member.getInt(obj); + index.intIndex++; + } + for (Field member : floatMember) { + floatPayload[index.floatIndex] = member.getFloat(obj); + index.floatIndex++; + } + for (Field member : booleanMember) { + if (member.getBoolean(obj)) + floatPayload[index.intIndex] = 1; + else + floatPayload[index.intIndex] = 0; + index.intIndex++; + } + for (Field member : stringMember) { + stringPayload[index.stringIndex] = (String) member.get(obj); + index.stringIndex++; + } + for (Field member : enumMember) { + intPayload[index.intIndex] = ((Enum) member.get(obj)).ordinal(); + index.intIndex++; + } + + // Handle subobjects + for (ClassMap submap : objectMember) { + Object source = submap.field.get(obj); + + if (source == null) { + intPayload[index.intIndex] = 0; + index.intIndex++; + + index.intIndex += submap.intSize; + index.floatIndex += submap.floatSize; + index.stringIndex += submap.stringSize; + } else { + intPayload[index.intIndex] = 1; + index.intIndex++; + submap.setData(source, intPayload, floatPayload, stringPayload, index); + } + } + } + + /** + * Updates the given object with the data from the passed payload arrays + * + * @param obj + * @param intPayload + * @param floatPayload + * @param stringPayload + * @param index + * @throws IllegalAccessException + */ + @SuppressWarnings("rawtypes") + public void fromData(Object obj, int[] intPayload, float[] floatPayload, String[] stringPayload, IndexInPayload index) throws IllegalAccessException { + + for (Field member : intMember) { + member.setInt(obj, intPayload[index.intIndex]); + index.intIndex++; + } + + for (Field member : booleanMember) { + member.setBoolean(obj, intPayload[index.intIndex] == 1); + index.intIndex++; + } + + for (Field member : enumMember) { + member.set(obj, ((Class) member.getGenericType()).getEnumConstants()[intPayload[index.intIndex]]); + index.intIndex++; + } + + for (Field member : floatMember) { + member.setFloat(obj, floatPayload[index.floatIndex]); + index.floatIndex++; + } + for (Field member : stringMember) { + member.set(obj, stringPayload[index.stringIndex]); + index.stringIndex++; + } + + for (ClassMap map : objectMember) { + boolean isNull = intPayload[index.intIndex] == 0; + index.intIndex++; + + if (isNull) { + index.intIndex += map.intSize; + index.floatIndex += map.floatSize; + index.stringIndex += map.stringSize; + } else { + map.field.get(obj); + map.fromData(map.field.get(obj), intPayload, floatPayload, stringPayload, index); + } + } + } + + @SuppressWarnings("rawtypes") + public ClassMap(final Class targetClass) { + Field[] fields = targetClass.getFields(); + + try { + for (Field field : fields) { + // We only handle fields marked with EntityNetData + if (!isNetworkedMember(field)) + continue; + + Type type = field.getGenericType(); + + if (type instanceof Class && !((Class) type).isArray()) { + Class memberClass = (Class) type; + if (memberClass.equals(int.class)) { + intSize++; + intMember.add(field); + } else if (memberClass.equals(float.class)) { + floatSize++; + floatMember.add(field); + } else if (memberClass.equals(boolean.class)) { + intSize++; + booleanMember.add(field); + } else if (memberClass.equals(String.class)) { + stringSize++; + stringMember.add(field); + } else if (Enum.class.isAssignableFrom(memberClass)) { + intSize++; + enumMember.add(field); + } else { + // If we are none of the above we assume to be another + // mapable object + // Might not be true and fail! + ClassMap mapper = new ClassMap(memberClass); + mapper.field = field; + + objectMember.add(mapper); + intSize++; + + intSize += mapper.intSize; + floatSize += mapper.floatSize; + stringSize += mapper.stringSize; + } + } else if (type instanceof Class && ((Class) type).isArray()) + // We don't handle arrays currently. Throw exception + throw new RuntimeException("Tried to map class " + targetClass.toString() + " but it requested mapping of an array. Not handled!"); + } + } catch (IllegalArgumentException e) { + e.printStackTrace(); + } + } + + private boolean isNetworkedMember(Field member) { + return member.getAnnotation(EntityNetData.class) != null; + } + +} diff --git a/forestry_common/core/forestry/core/network/EntityNetData.java b/forestry_common/core/forestry/core/network/EntityNetData.java new file mode 100755 index 000000000..0bc48e769 --- /dev/null +++ b/forestry_common/core/forestry/core/network/EntityNetData.java @@ -0,0 +1,20 @@ +/******************************************************************************* + * Copyright 2011-2014 by SirSengir + * + * This work is licensed under a Creative Commons Attribution-NonCommercial-NoDerivs 3.0 Unported License. + * + * To view a copy of this license, visit http://creativecommons.org/licenses/by-nc-nd/3.0/. + ******************************************************************************/ +package forestry.core.network; + +import java.lang.annotation.Retention; +import java.lang.annotation.RetentionPolicy; + +/** + * Simple annotation to mark a field for synchronization in SMP. + */ +@Retention(RetentionPolicy.RUNTIME) +public @interface EntityNetData { + // Needs to be set for arrays + int staticSize() default -1; +} diff --git a/forestry_common/core/forestry/core/network/ForestryPacket.java b/forestry_common/core/forestry/core/network/ForestryPacket.java new file mode 100755 index 000000000..1a5a9f0db --- /dev/null +++ b/forestry_common/core/forestry/core/network/ForestryPacket.java @@ -0,0 +1,120 @@ +/******************************************************************************* + * Copyright 2011-2014 by SirSengir + * + * This work is licensed under a Creative Commons Attribution-NonCommercial-NoDerivs 3.0 Unported License. + * + * To view a copy of this license, visit http://creativecommons.org/licenses/by-nc-nd/3.0/. + ******************************************************************************/ +package forestry.core.network; + +import java.io.ByteArrayOutputStream; +import java.io.DataInputStream; +import java.io.DataOutputStream; +import java.io.IOException; + +import net.minecraft.item.Item; +import net.minecraft.item.ItemStack; +import net.minecraft.nbt.CompressedStreamTools; +import net.minecraft.nbt.NBTTagCompound; + +import cpw.mods.fml.common.network.internal.FMLProxyPacket; +import cpw.mods.fml.common.registry.GameData; + +import io.netty.buffer.Unpooled; + +import forestry.core.proxy.Proxies; + +public class ForestryPacket { + + protected int id; + protected static String channel = "FOR"; + + public ForestryPacket() { + } + + public ForestryPacket(int id) { + this.id = id; + } + + public FMLProxyPacket getPacket() { + ByteArrayOutputStream bytes = new ByteArrayOutputStream(); + DataOutputStream data = new DataOutputStream(bytes); + + try { + data.writeByte(getID()); + writeData(data); + } catch (IOException e) { + e.printStackTrace(); + } + + return new FMLProxyPacket(Unpooled.wrappedBuffer(bytes.toByteArray()), channel); + } + + public int getID() { + return id; + } + + protected ItemStack readItemStack(DataInputStream data) throws IOException { + ItemStack itemstack = null; + String itemName = data.readUTF(); + + if (!itemName.isEmpty()) { + Item item = GameData.itemRegistry.getObject(itemName); + byte stackSize = data.readByte(); + short meta = data.readShort(); + itemstack = new ItemStack(item, stackSize, meta); + + if (item.isDamageable() || Proxies.common.needsTagCompoundSynched(item)) + itemstack.stackTagCompound = this.readNBTTagCompound(data); + } + + return itemstack; + } + + protected void writeItemStack(ItemStack itemstack, DataOutputStream data) throws IOException { + + if (itemstack == null) + data.writeUTF(""); + else { + data.writeUTF(GameData.itemRegistry.getNameForObject(itemstack.getItem())); + data.writeByte(itemstack.stackSize); + data.writeShort(itemstack.getItemDamage()); + + if (itemstack.getItem().isDamageable() || Proxies.common.needsTagCompoundSynched(itemstack.getItem())) + this.writeNBTTagCompound(itemstack.stackTagCompound, data); + } + } + + protected NBTTagCompound readNBTTagCompound(DataInputStream data) throws IOException { + + short length = data.readShort(); + + if (length < 0) + return null; + else { + byte[] compressed = new byte[length]; + data.readFully(compressed); + return CompressedStreamTools.decompress(compressed); + } + + } + + protected void writeNBTTagCompound(NBTTagCompound nbttagcompound, DataOutputStream data) throws IOException { + + if (nbttagcompound == null) + data.writeShort(-1); + else { + byte[] compressed = CompressedStreamTools.compress(nbttagcompound); + data.writeShort((short) compressed.length); + data.write(compressed); + } + + } + + public void writeData(DataOutputStream data) throws IOException { + } + + public void readData(DataInputStream data) throws IOException { + } + +} diff --git a/forestry_common/core/forestry/core/network/GuiId.java b/forestry_common/core/forestry/core/network/GuiId.java new file mode 100755 index 000000000..d3ce75b09 --- /dev/null +++ b/forestry_common/core/forestry/core/network/GuiId.java @@ -0,0 +1,116 @@ +/******************************************************************************* + * Copyright 2011-2014 by SirSengir + * + * This work is licensed under a Creative Commons Attribution-NonCommercial-NoDerivs 3.0 Unported License. + * + * To view a copy of this license, visit http://creativecommons.org/licenses/by-nc-nd/3.0/. + ******************************************************************************/ +package forestry.core.network; + +public enum GuiId { + AlvearyGUI, + + AlvearySwarmerGUI, + + AlvearySieveGUI, + + AnalyzerGUI, + + ApiaristBackpackGUI, + + ApiaristChestGUI, + + ArboristChestGUI, + + ApiaryGUI, + + ArboretumGUI, + + BackpackGUI, + + BackpackT2GUI, + + BeealyzerGUI, + + BeehouseGUI, + + BottlerGUI, + + CatalogueGUI, + + CarpenterGUI, + + CentrifugeGUI, + + EngineBronzeGUI, + + EngineCopperGUI, + + EngineTinGUI, + + FabricatorGUI, + + FarmGUI, + + FermenterGUI, + + FlutterlyzerGUI, + + ForesterGUI, + + GeneratorGUI, + + HabitatLocatorGUI, + + HygroregulatorGUI, + + ImprinterGUI, + + InfuserGUI, + + LetterGUI, + + LepidopteristBackpackGUI, + + LepidopteristChestGUI, + + MailboxGUI, + + MoistenerGUI, + + MushroomFarmGUI, + + MultiFarmGUI, + + NaturalistBenchGUI, + + NetherFarmGUI, + + PeatBogGUI, + + PhilatelistGUI, + + PlantationGUI, + + PropolisPipeGUI, + + PumpkinFarmGUI, + + RaintankGUI, + + SolderingIronGUI, + + SqueezerGUI, + + StillGUI, + + TraderGUI, + + TraderNameGUI, + + TreealyzerGUI, + + WorktableGUI, + + Unknown +} diff --git a/forestry_common/core/forestry/core/network/ILocatedPacket.java b/forestry_common/core/forestry/core/network/ILocatedPacket.java new file mode 100755 index 000000000..234b8dda0 --- /dev/null +++ b/forestry_common/core/forestry/core/network/ILocatedPacket.java @@ -0,0 +1,15 @@ +/******************************************************************************* + * Copyright 2011-2014 by SirSengir + * + * This work is licensed under a Creative Commons Attribution-NonCommercial-NoDerivs 3.0 Unported License. + * + * To view a copy of this license, visit http://creativecommons.org/licenses/by-nc-nd/3.0/. + ******************************************************************************/ +package forestry.core.network; + +import net.minecraft.tileentity.TileEntity; +import net.minecraft.world.World; + +public interface ILocatedPacket { + TileEntity getTarget(World world); +} diff --git a/forestry_common/core/forestry/core/network/INetworkedEntity.java b/forestry_common/core/forestry/core/network/INetworkedEntity.java new file mode 100755 index 000000000..a9bc52d22 --- /dev/null +++ b/forestry_common/core/forestry/core/network/INetworkedEntity.java @@ -0,0 +1,16 @@ +/******************************************************************************* + * Copyright 2011-2014 by SirSengir + * + * This work is licensed under a Creative Commons Attribution-NonCommercial-NoDerivs 3.0 Unported License. + * + * To view a copy of this license, visit http://creativecommons.org/licenses/by-nc-nd/3.0/. + ******************************************************************************/ +package forestry.core.network; + +public interface INetworkedEntity { + + public void sendNetworkUpdate(); + + public void fromPacket(ForestryPacket packet); + +} diff --git a/forestry_common/core/forestry/core/network/IndexInPayload.java b/forestry_common/core/forestry/core/network/IndexInPayload.java new file mode 100755 index 000000000..28d93de30 --- /dev/null +++ b/forestry_common/core/forestry/core/network/IndexInPayload.java @@ -0,0 +1,23 @@ +/******************************************************************************* + * Copyright 2011-2014 by SirSengir + * + * This work is licensed under a Creative Commons Attribution-NonCommercial-NoDerivs 3.0 Unported License. + * + * To view a copy of this license, visit http://creativecommons.org/licenses/by-nc-nd/3.0/. + ******************************************************************************/ +package forestry.core.network; + +/** + * Keeps track of the indices to use when writing data to payload arrays. Internal use only. + */ +public class IndexInPayload { + public IndexInPayload(int intIndex, int floatIndex, int stringIndex) { + this.intIndex = intIndex; + this.floatIndex = floatIndex; + this.stringIndex = stringIndex; + } + + public int intIndex = 0; + public int floatIndex = 0; + public int stringIndex = 0; +} diff --git a/forestry_common/core/forestry/core/network/PacketCoordinates.java b/forestry_common/core/forestry/core/network/PacketCoordinates.java new file mode 100755 index 000000000..bf53f4466 --- /dev/null +++ b/forestry_common/core/forestry/core/network/PacketCoordinates.java @@ -0,0 +1,65 @@ +/******************************************************************************* + * Copyright 2011-2014 by SirSengir + * + * This work is licensed under a Creative Commons Attribution-NonCommercial-NoDerivs 3.0 Unported License. + * + * To view a copy of this license, visit http://creativecommons.org/licenses/by-nc-nd/3.0/. + ******************************************************************************/ +package forestry.core.network; + +import java.io.DataInputStream; +import java.io.DataOutputStream; +import java.io.IOException; + +import net.minecraft.tileentity.TileEntity; +import net.minecraft.util.ChunkCoordinates; +import net.minecraft.world.World; + +public class PacketCoordinates extends ForestryPacket implements ILocatedPacket { + + public int posX; + public int posY; + public int posZ; + + public PacketCoordinates() { + } + + public PacketCoordinates(int id, ChunkCoordinates coordinates) { + this(id, coordinates.posX, coordinates.posY, coordinates.posZ); + } + + public PacketCoordinates(int id, int posX, int posY, int posZ) { + super(id); + this.posX = posX; + this.posY = posY; + this.posZ = posZ; + } + + @Override + public void writeData(DataOutputStream data) throws IOException { + + data.writeInt(posX); + data.writeInt(posY); + data.writeInt(posZ); + + } + + @Override + public void readData(DataInputStream data) throws IOException { + + posX = data.readInt(); + posY = data.readInt(); + posZ = data.readInt(); + + } + + public ChunkCoordinates getCoordinates() { + return new ChunkCoordinates(posX, posY, posZ); + } + + @Override + public TileEntity getTarget(World world) { + return world.getTileEntity(posX, posY, posZ); + } + +} diff --git a/forestry_common/core/forestry/core/network/PacketFXSignal.java b/forestry_common/core/forestry/core/network/PacketFXSignal.java new file mode 100755 index 000000000..e9a4511bc --- /dev/null +++ b/forestry_common/core/forestry/core/network/PacketFXSignal.java @@ -0,0 +1,103 @@ +/******************************************************************************* + * Copyright 2011-2014 by SirSengir + * + * This work is licensed under a Creative Commons Attribution-NonCommercial-NoDerivs 3.0 Unported License. + * + * To view a copy of this license, visit http://creativecommons.org/licenses/by-nc-nd/3.0/. + ******************************************************************************/ +package forestry.core.network; + +import java.io.DataInputStream; +import java.io.DataOutputStream; +import java.io.IOException; + +import net.minecraft.block.Block; + +import cpw.mods.fml.common.registry.GameData; + +import forestry.core.proxy.Proxies; + +public class PacketFXSignal extends ForestryPacket { + + public static enum VisualFXType { + NONE, BLOCK_DESTROY, SAPLING_PLACE + }; + + public static enum SoundFXType { + NONE(""), BLOCK_DESTROY(""), BLOCK_PLACE(""), LEAF("step.grass"), LOG("dig.wood"), DIRT("dig.gravel"); + + public final String soundFile; + public final float volume = 1.0f; + public final float pitch = 1.0f; + + private SoundFXType(String soundFile) { + this.soundFile = soundFile; + } + }; + + private VisualFXType visualFX; + private SoundFXType soundFX; + + private int xCoord; + private int yCoord; + private int zCoord; + private Block block; + private int meta; + + public PacketFXSignal() { + } + + public PacketFXSignal(VisualFXType type, int xCoord, int yCoord, int zCoord, Block block, int meta) { + this(type, SoundFXType.NONE, xCoord, yCoord, zCoord, block, meta); + } + + public PacketFXSignal(SoundFXType type, int xCoord, int yCoord, int zCoord, Block block, int meta) { + this(VisualFXType.NONE, type, xCoord, yCoord, zCoord, block, meta); + } + + public PacketFXSignal(VisualFXType visualFX, SoundFXType soundFX, int xCoord, int yCoord, int zCoord, Block block, int meta) { + super(PacketIds.FX_SIGNAL); + this.visualFX = visualFX; + this.soundFX = soundFX; + this.xCoord = xCoord; + this.yCoord = yCoord; + this.zCoord = zCoord; + this.block = block; + this.meta = meta; + } + + @Override + public void writeData(DataOutputStream data) throws IOException { + data.writeShort(visualFX.ordinal()); + data.writeShort(soundFX.ordinal()); + data.writeInt(xCoord); + data.writeInt(yCoord); + data.writeInt(zCoord); + data.writeUTF(GameData.blockRegistry.getNameForObject(block)); + data.writeInt(meta); + } + + @Override + public void readData(DataInputStream data) throws IOException { + this.visualFX = VisualFXType.values()[data.readShort()]; + this.soundFX = SoundFXType.values()[data.readShort()]; + this.xCoord = data.readInt(); + this.yCoord = data.readInt(); + this.zCoord = data.readInt(); + this.block = GameData.blockRegistry.getObject(data.readUTF()); + this.meta = data.readInt(); + } + + public void executeFX() { + if (visualFX != VisualFXType.NONE) + Proxies.common.addBlockDestroyEffects(Proxies.common.getRenderWorld(), xCoord, yCoord, zCoord, block, meta); + if (soundFX != SoundFXType.NONE) + if (soundFX == SoundFXType.BLOCK_DESTROY) + Proxies.common.playBlockBreakSoundFX(Proxies.common.getRenderWorld(), xCoord, yCoord, zCoord, block); + else if (soundFX == SoundFXType.BLOCK_PLACE) + Proxies.common.playBlockPlaceSoundFX(Proxies.common.getRenderWorld(), xCoord, yCoord, zCoord, block); + else + Proxies.common.playSoundFX(Proxies.common.getRenderWorld(), xCoord, yCoord, zCoord, soundFX.soundFile, soundFX.volume, soundFX.pitch); + } + +} diff --git a/forestry_common/core/forestry/core/network/PacketHandler.java b/forestry_common/core/forestry/core/network/PacketHandler.java new file mode 100755 index 000000000..9fbe1e9e7 --- /dev/null +++ b/forestry_common/core/forestry/core/network/PacketHandler.java @@ -0,0 +1,297 @@ +/******************************************************************************* + * Copyright 2011-2014 by SirSengir + * + * This work is licensed under a Creative Commons Attribution-NonCommercial-NoDerivs 3.0 Unported License. + * + * To view a copy of this license, visit http://creativecommons.org/licenses/by-nc-nd/3.0/. + ******************************************************************************/ +package forestry.core.network; + +import java.io.ByteArrayInputStream; +import java.io.DataInputStream; + +import net.minecraft.entity.player.EntityPlayer; +import net.minecraft.entity.player.EntityPlayerMP; +import net.minecraft.inventory.Container; +import net.minecraft.inventory.IInventory; +import net.minecraft.item.ItemStack; +import net.minecraft.network.NetHandlerPlayServer; +import net.minecraft.tileentity.TileEntity; + +import cpw.mods.fml.common.FMLCommonHandler; +import cpw.mods.fml.common.eventhandler.SubscribeEvent; +import cpw.mods.fml.common.network.FMLEventChannel; +import cpw.mods.fml.common.network.FMLNetworkEvent.ClientCustomPacketEvent; +import cpw.mods.fml.common.network.FMLNetworkEvent.ServerCustomPacketEvent; +import cpw.mods.fml.common.network.NetworkRegistry; +import cpw.mods.fml.common.network.internal.FMLProxyPacket; + +import net.minecraftforge.common.MinecraftForge; + +import forestry.api.core.ForestryEvent; +import forestry.api.genetics.AlleleManager; +import forestry.api.genetics.IBreedingTracker; +import forestry.api.genetics.ISpeciesRoot; +import forestry.core.circuits.ItemCircuitBoard; +import forestry.core.gadgets.TileForestry; +import forestry.core.gui.ContainerForestry; +import forestry.core.gui.ContainerLiquidTanks; +import forestry.core.gui.ContainerSocketed; +import forestry.core.gui.IGuiSelectable; +import forestry.core.interfaces.ISocketable; +import forestry.core.proxy.Proxies; +import forestry.plugins.PluginManager; + +public class PacketHandler { + public PacketHandler() { + channel = NetworkRegistry.INSTANCE.newEventDrivenChannel(ForestryPacket.channel); + channel.register(this); + } + + @SubscribeEvent + public void onPacket(ServerCustomPacketEvent event) { + byte[] data = new byte[event.packet.payload().readableBytes()]; + event.packet.payload().readBytes(data); + + onPacketData(data, ((NetHandlerPlayServer) event.handler).playerEntity); + } + + @SubscribeEvent + public void onPacket(ClientCustomPacketEvent event) { + byte[] data = new byte[event.packet.payload().readableBytes()]; + event.packet.payload().readBytes(data); + + onPacketData(data, null); + } + + public void onPacketData(byte[] bData, EntityPlayer player) { + DataInputStream data = new DataInputStream(new ByteArrayInputStream(bData)); + PacketUpdate packetU; + + try { + + int packetId = data.readByte(); + + switch (packetId) { + + case PacketIds.TILE_FORESTRY_UPDATE: + PacketTileUpdate packetT = new PacketTileUpdate(); + packetT.readData(data); + onTileUpdate(packetT); + break; + case PacketIds.TILE_UPDATE: + PacketUpdate packetUpdate = new PacketUpdate(); + packetUpdate.readData(data); + onTileUpdate(packetUpdate); + break; + case PacketIds.TILE_NBT: + PacketTileNBT packetN = new PacketTileNBT(); + packetN.readData(data); + onTileUpdate(packetN); + break; + case PacketIds.SOCKET_UPDATE: + PacketSocketUpdate packetS = new PacketSocketUpdate(); + packetS.readData(data); + onSocketUpdate(packetS); + break; + case PacketIds.IINVENTORY_STACK: + PacketInventoryStack packetQ = new PacketInventoryStack(); + packetQ.readData(data); + onInventoryStack(packetQ); + break; + case PacketIds.FX_SIGNAL: + PacketFXSignal packetF = new PacketFXSignal(); + packetF.readData(data); + packetF.executeFX(); + break; + + case PacketIds.PIPETTE_CLICK: + packetU = new PacketUpdate(); + packetU.readData(data); + onPipetteClick(packetU, player); + break; + case PacketIds.SOLDERING_IRON_CLICK: + packetU = new PacketUpdate(); + packetU.readData(data); + onSolderingIronClick(packetU, player); + break; + case PacketIds.CHIPSET_CLICK: + packetU = new PacketUpdate(); + packetU.readData(data); + onChipsetClick(packetU, player); + break; + case PacketIds.ACCESS_SWITCH: + PacketCoordinates packetC = new PacketCoordinates(); + packetC.readData(data); + onAccessSwitch(packetC, player); + break; + case PacketIds.GUI_SELECTION: + PacketUpdate packetI = new PacketUpdate(); + packetI.readData(data); + onGuiSelection(packetI); + break; + case PacketIds.GUI_SELECTION_CHANGE: + PacketUpdate packetZ = new PacketUpdate(); + packetZ.readData(data); + onGuiChange(player, packetZ); + break; + case PacketIds.GENOME_TRACKER_UPDATE: + PacketNBT packetTR = new PacketNBT(); + packetTR.readData(data); + onGenomeTrackerUpdate(packetTR); + break; + case PacketIds.TANK_UPDATE: + PacketTankUpdate packetAB = new PacketTankUpdate(); + packetAB.readData(data); + onTankUpdate(packetAB); + break; + default: + for (forestry.core.interfaces.IPacketHandler handler : PluginManager.packetHandlers) + handler.onPacketData(packetId, data, player); + } + } catch (Exception ex) { + ex.printStackTrace(); + } + + } + + public void sendPacket(FMLProxyPacket packet) { + if (FMLCommonHandler.instance().getEffectiveSide().isClient()) { + channel.sendToServer(packet); + } else { + channel.sendToAll(packet); + } + } + + public void sendPacket(FMLProxyPacket packet, EntityPlayerMP player) { + channel.sendTo(packet, player); + } + + + private void onTankUpdate(PacketTankUpdate packetAB) { + assert FMLCommonHandler.instance().getEffectiveSide().isClient(); + + EntityPlayer player = Proxies.common.getPlayer(); + + if (player.openContainer instanceof ContainerForestry) { + ((ContainerForestry)player.openContainer).onTankUpdate(packetAB.nbttagcompound); + } + } + + private void onGenomeTrackerUpdate(PacketNBT packet) { + assert FMLCommonHandler.instance().getEffectiveSide().isClient(); + + EntityPlayer player = Proxies.common.getPlayer(); + IBreedingTracker tracker = null; + String type = packet.getTagCompound().getString("TYPE"); + + ISpeciesRoot root = AlleleManager.alleleRegistry.getSpeciesRoot(type); + if(root != null) + tracker = root.getBreedingTracker(Proxies.common.getRenderWorld(), player.getGameProfile().getId()); + if (tracker != null) { + tracker.decodeFromNBT(packet.getTagCompound()); + MinecraftForge.EVENT_BUS.post(new ForestryEvent.SyncedBreedingTracker(tracker, player)); + } + } + + private void onGuiChange(EntityPlayer player, PacketUpdate packet) { + assert FMLCommonHandler.instance().getEffectiveSide().isServer(); + + if (!(player.openContainer instanceof IGuiSelectable)) + return; + + ((IGuiSelectable) player.openContainer).handleSelectionChange(player, packet); + } + + private void onGuiSelection(PacketUpdate packet) { + assert FMLCommonHandler.instance().getEffectiveSide().isClient(); + + EntityPlayer player = Proxies.common.getPlayer(); + + Container container = player.openContainer; + if (!(container instanceof IGuiSelectable)) + return; + + ((IGuiSelectable) container).setSelection(packet); + + } + + private void onSocketUpdate(PacketSocketUpdate packet) { + assert FMLCommonHandler.instance().getEffectiveSide().isClient(); + + TileEntity tile = Proxies.common.getRenderWorld().getTileEntity(packet.posX, packet.posY, packet.posZ); + if (!(tile instanceof ISocketable)) + return; + + ISocketable socketable = (ISocketable) tile; + for (int i = 0; i < packet.itemstacks.length; i++) + socketable.setSocket(i, packet.itemstacks[i]); + } + + private void onTileUpdate(ForestryPacket packet) { + + TileEntity tile = ((ILocatedPacket) packet).getTarget(Proxies.common.getRenderWorld()); + if (tile instanceof INetworkedEntity) + ((INetworkedEntity) tile).fromPacket(packet); + + } + + private void onInventoryStack(PacketInventoryStack packet) { + + TileEntity tile = Proxies.common.getRenderWorld().getTileEntity(packet.posX, packet.posY, packet.posZ); + if (tile == null) + return; + + if (tile instanceof IInventory) { + ((IInventory) tile).setInventorySlotContents(packet.slotIndex, packet.itemstack); + } else if (tile instanceof TileForestry) { + IInventory inventory = ((TileForestry) tile).getInternalInventory(); + + if (inventory != null) inventory.setInventorySlotContents(packet.slotIndex, packet.itemstack); + } + } + + private void onChipsetClick(PacketUpdate packet, EntityPlayer player) { + assert FMLCommonHandler.instance().getEffectiveSide().isServer(); + + if (!(player.openContainer instanceof ContainerSocketed)) + return; + ItemStack itemstack = player.inventory.getItemStack(); + if (!(itemstack.getItem() instanceof ItemCircuitBoard)) + return; + + ((ContainerSocketed) player.openContainer).handleChipsetClick(packet.payload.intPayload[0], player, itemstack); + + } + + private void onSolderingIronClick(PacketUpdate packet, EntityPlayer player) { + assert FMLCommonHandler.instance().getEffectiveSide().isServer(); + + if (!(player.openContainer instanceof ContainerSocketed)) + return; + ItemStack itemstack = player.inventory.getItemStack(); + + ((ContainerSocketed) player.openContainer).handleSolderingIronClick(packet.payload.intPayload[0], player, itemstack); + } + + private void onAccessSwitch(PacketCoordinates packet, EntityPlayer playerEntity) { + assert FMLCommonHandler.instance().getEffectiveSide().isServer(); + + TileForestry tile = (TileForestry) playerEntity.worldObj.getTileEntity(packet.posX, packet.posY, packet.posZ); + if (tile == null) + return; + + tile.switchAccessRule(playerEntity); + } + + private void onPipetteClick(PacketUpdate packet, EntityPlayer player) { + assert FMLCommonHandler.instance().getEffectiveSide().isServer(); + + if (!(player.openContainer instanceof ContainerLiquidTanks)) + return; + + ((ContainerLiquidTanks) player.openContainer).handlePipetteClick(packet.payload.intPayload[0], player); + } + + private final FMLEventChannel channel; +} diff --git a/forestry_common/core/forestry/core/network/PacketIds.java b/forestry_common/core/forestry/core/network/PacketIds.java new file mode 100755 index 000000000..858ec0010 --- /dev/null +++ b/forestry_common/core/forestry/core/network/PacketIds.java @@ -0,0 +1,59 @@ +/******************************************************************************* + * Copyright 2011-2014 by SirSengir + * + * This work is licensed under a Creative Commons Attribution-NonCommercial-NoDerivs 3.0 Unported License. + * + * To view a copy of this license, visit http://creativecommons.org/licenses/by-nc-nd/3.0/. + ******************************************************************************/ +package forestry.core.network; + +/** + * Valid ids: 0 - 127 + */ +public class PacketIds { + + public static final int TILE_FORESTRY_UPDATE = 0; + public static final int TILE_UPDATE = 1; + public static final int TILE_DESCRIPTION = 2; + public static final int IINVENTORY_STACK = 3; + public static final int FX_SIGNAL = 4; + public static final int TILE_NBT = 5; + + public static final int HABITAT_BIOME_POINTER = 20; + + public static final int GUI_SELECTION_CHANGE = 30; + public static final int IMPRINT_SELECTION_GET = 31; + public static final int GUI_SELECTION = 32; + + public static final int PIPETTE_CLICK = 40; + + public static final int ACCESS_SWITCH = 50; + + public static final int GENOME_TRACKER_UPDATE = 60; + public static final int GAME_TOKEN_SET = 61; + + public static final int CHIPSET_CLICK = 70; + public static final int SOLDERING_IRON_CLICK = 71; + public static final int SOCKET_UPDATE = 72; + + public static final int LETTER_RECIPIENT = 80; + public static final int LETTER_TEXT = 81; + public static final int TRADING_MONIKER_SET = 82; + public static final int TRADING_INFO = 83; + public static final int POBOX_INFO = 85; + public static final int POBOX_INFO_REQUEST = 86; + + public static final int LEAF_UPDATE = 90; + + public static final int TANK_UPDATE = 91; + + // Propolis pipe + public static final int PROP_SEND_FILTER_SET = 100; + public static final int PROP_REQUEST_FILTER_SET = 101; + public static final int PROP_SEND_FILTER_CHANGE_GENOME = 102; + public static final int PROP_SEND_FILTER_CHANGE_TYPE = 103; + + + + +} diff --git a/forestry_common/core/forestry/core/network/PacketInventoryStack.java b/forestry_common/core/forestry/core/network/PacketInventoryStack.java new file mode 100755 index 000000000..d52e78c56 --- /dev/null +++ b/forestry_common/core/forestry/core/network/PacketInventoryStack.java @@ -0,0 +1,44 @@ +/******************************************************************************* + * Copyright 2011-2014 by SirSengir + * + * This work is licensed under a Creative Commons Attribution-NonCommercial-NoDerivs 3.0 Unported License. + * + * To view a copy of this license, visit http://creativecommons.org/licenses/by-nc-nd/3.0/. + ******************************************************************************/ +package forestry.core.network; + +import java.io.DataInputStream; +import java.io.DataOutputStream; +import java.io.IOException; + +import net.minecraft.item.ItemStack; + +public class PacketInventoryStack extends PacketCoordinates { + + public int slotIndex; + public ItemStack itemstack; + + public PacketInventoryStack() { + } + + public PacketInventoryStack(int id, int posX, int posY, int posZ, int slotIndex, ItemStack itemstack) { + super(id, posX, posY, posZ); + this.slotIndex = slotIndex; + this.itemstack = itemstack; + } + + @Override + public void writeData(DataOutputStream data) throws IOException { + super.writeData(data); + data.writeInt(slotIndex); + writeItemStack(itemstack, data); + } + + @Override + public void readData(DataInputStream data) throws IOException { + super.readData(data); + slotIndex = data.readInt(); + itemstack = readItemStack(data); + } + +} diff --git a/forestry_common/core/forestry/core/network/PacketNBT.java b/forestry_common/core/forestry/core/network/PacketNBT.java new file mode 100755 index 000000000..e25b59860 --- /dev/null +++ b/forestry_common/core/forestry/core/network/PacketNBT.java @@ -0,0 +1,51 @@ +/******************************************************************************* + * Copyright 2011-2014 by SirSengir + * + * This work is licensed under a Creative Commons Attribution-NonCommercial-NoDerivs 3.0 Unported License. + * + * To view a copy of this license, visit http://creativecommons.org/licenses/by-nc-nd/3.0/. + ******************************************************************************/ +package forestry.core.network; + +import java.io.DataInputStream; +import java.io.DataOutputStream; +import java.io.IOException; + +import net.minecraft.nbt.CompressedStreamTools; +import net.minecraft.nbt.NBTTagCompound; + +public class PacketNBT extends ForestryPacket { + + protected NBTTagCompound nbttagcompound; + + public PacketNBT() { + } + + public PacketNBT(int id) { + super(id); + } + + public PacketNBT(int id, NBTTagCompound nbttagcompound) { + super(id); + this.nbttagcompound = nbttagcompound; + } + + @Override + public void writeData(DataOutputStream data) throws IOException { + byte[] compressed = CompressedStreamTools.compress(nbttagcompound); + data.writeShort(compressed.length); + data.write(compressed); + } + + @Override + public void readData(DataInputStream data) throws IOException { + short length = data.readShort(); + byte[] compressed = new byte[length]; + data.readFully(compressed); + this.nbttagcompound = CompressedStreamTools.decompress(compressed); + } + + public NBTTagCompound getTagCompound() { + return this.nbttagcompound; + } +} diff --git a/forestry_common/core/forestry/core/network/PacketPayload.java b/forestry_common/core/forestry/core/network/PacketPayload.java new file mode 100755 index 000000000..746c18f1d --- /dev/null +++ b/forestry_common/core/forestry/core/network/PacketPayload.java @@ -0,0 +1,66 @@ +/******************************************************************************* + * Copyright 2011-2014 by SirSengir + * + * This work is licensed under a Creative Commons Attribution-NonCommercial-NoDerivs 3.0 Unported License. + * + * To view a copy of this license, visit http://creativecommons.org/licenses/by-nc-nd/3.0/. + ******************************************************************************/ +package forestry.core.network; + +import forestry.core.utils.Utils; + +public class PacketPayload { + public int[] intPayload = new int[0]; + public short[] shortPayload = new short[0]; + public float[] floatPayload = new float[0]; + public String[] stringPayload = new String[0]; + + public PacketPayload() { + } + + public PacketPayload(int intSize, int floatSize, int stringSize) { + intPayload = new int[intSize]; + floatPayload = new float[floatSize]; + stringPayload = new String[stringSize]; + } + + public PacketPayload(int intSize, int shortSize) { + intPayload = new int[intSize]; + shortPayload = new short[shortSize]; + } + + public void append(PacketPayload other) { + if (other == null) + return; + + if (other.intPayload.length > 0) + this.intPayload = Utils.concat(this.intPayload, other.intPayload); + if (other.shortPayload.length > 0) + this.shortPayload = Utils.concat(this.shortPayload, other.shortPayload); + if (other.floatPayload.length > 0) + this.floatPayload = Utils.concat(this.floatPayload, other.floatPayload); + if (other.stringPayload.length > 0) + this.stringPayload = Utils.concat(this.stringPayload, other.stringPayload); + + } + + public void append(int[] other) { + if (other == null || other.length < 0) + return; + + this.intPayload = Utils.concat(this.intPayload, other); + } + + /* + * public void splitTail(IndexInPayload index) { PacketPayload payload = new PacketPayload(intPayload.length - index.intIndex, floatPayload.length - + * index.floatIndex, stringPayload.length - index.stringIndex); + * + * if (intPayload.length > 0) { System.arraycopy(intPayload, index.intIndex, payload.intPayload, 0, payload.intPayload.length); } if (floatPayload.length > + * 0) { System.arraycopy(floatPayload, index.floatIndex, payload.floatPayload, 0, payload.floatPayload.length); } if (stringPayload.length > 0) { + * System.arraycopy(stringPayload, index.stringIndex, payload.stringPayload, 0, payload.stringPayload.length); } } + */ + + public boolean isEmpty() { + return intPayload.length == 0 && shortPayload.length == 0 && floatPayload.length == 0 && stringPayload.length == 0; + } +} diff --git a/forestry_common/core/forestry/core/network/PacketSocketUpdate.java b/forestry_common/core/forestry/core/network/PacketSocketUpdate.java new file mode 100755 index 000000000..e2f3eeb8e --- /dev/null +++ b/forestry_common/core/forestry/core/network/PacketSocketUpdate.java @@ -0,0 +1,51 @@ +/******************************************************************************* + * Copyright 2011-2014 by SirSengir + * + * This work is licensed under a Creative Commons Attribution-NonCommercial-NoDerivs 3.0 Unported License. + * + * To view a copy of this license, visit http://creativecommons.org/licenses/by-nc-nd/3.0/. + ******************************************************************************/ +package forestry.core.network; + +import java.io.DataInputStream; +import java.io.DataOutputStream; +import java.io.IOException; + +import net.minecraft.item.ItemStack; + +import forestry.core.interfaces.ISocketable; + +public class PacketSocketUpdate extends PacketCoordinates { + + public ItemStack[] itemstacks; + + public PacketSocketUpdate() { + } + + public PacketSocketUpdate(int id, int posX, int posY, int posZ, ISocketable tile) { + super(id, posX, posY, posZ); + + itemstacks = new ItemStack[tile.getSocketCount()]; + for (int i = 0; i < tile.getSocketCount(); i++) + itemstacks[i] = tile.getSocket(i); + } + + @Override + public void writeData(DataOutputStream data) throws IOException { + super.writeData(data); + + data.writeShort(itemstacks.length); + for (int i = 0; i < itemstacks.length; i++) + writeItemStack(itemstacks[i], data); + } + + @Override + public void readData(DataInputStream data) throws IOException { + super.readData(data); + + int sockets = data.readShort(); + itemstacks = new ItemStack[sockets]; + for (int i = 0; i < sockets; i++) + itemstacks[i] = readItemStack(data); + } +} diff --git a/forestry_common/core/forestry/core/network/PacketTankUpdate.java b/forestry_common/core/forestry/core/network/PacketTankUpdate.java new file mode 100755 index 000000000..7a9809eaf --- /dev/null +++ b/forestry_common/core/forestry/core/network/PacketTankUpdate.java @@ -0,0 +1,28 @@ +/******************************************************************************* + * Copyright 2011-2014 by SirSengir + * + * This work is licensed under a Creative Commons Attribution-NonCommercial-NoDerivs 3.0 Unported License. + * + * To view a copy of this license, visit http://creativecommons.org/licenses/by-nc-nd/3.0/. + ******************************************************************************/ +package forestry.core.network; + +import net.minecraft.nbt.NBTTagCompound; + +import forestry.core.utils.ForestryTank; + +public class PacketTankUpdate extends PacketNBT { + + public PacketTankUpdate(int tankSlot, ForestryTank tank) { + super(PacketIds.TANK_UPDATE); + NBTTagCompound nbt = new NBTTagCompound(); + nbt.setByte("tank", (byte) tankSlot); + nbt.setShort("capacity", (short) tank.getCapacity()); + tank.writeToNBT(nbt); + this.nbttagcompound = nbt; + } + + public PacketTankUpdate() { + } + +} diff --git a/forestry_common/core/forestry/core/network/PacketTileNBT.java b/forestry_common/core/forestry/core/network/PacketTileNBT.java new file mode 100755 index 000000000..3467c0abb --- /dev/null +++ b/forestry_common/core/forestry/core/network/PacketTileNBT.java @@ -0,0 +1,63 @@ +/******************************************************************************* + * Copyright 2011-2014 by SirSengir + * + * This work is licensed under a Creative Commons Attribution-NonCommercial-NoDerivs 3.0 Unported License. + * + * To view a copy of this license, visit http://creativecommons.org/licenses/by-nc-nd/3.0/. + ******************************************************************************/ +package forestry.core.network; + +import java.io.DataInputStream; +import java.io.DataOutputStream; +import java.io.IOException; + +import net.minecraft.nbt.NBTTagCompound; +import net.minecraft.tileentity.TileEntity; +import net.minecraft.world.World; + +public class PacketTileNBT extends PacketNBT implements ILocatedPacket { + + private int posX; + private int posY; + private int posZ; + + public PacketTileNBT() { + } + + public PacketTileNBT(int id, TileEntity tile) { + super(id); + + posX = tile.xCoord; + posY = tile.yCoord; + posZ = tile.zCoord; + + this.nbttagcompound = new NBTTagCompound(); + tile.writeToNBT(nbttagcompound); + } + + @Override + public void writeData(DataOutputStream data) throws IOException { + + data.writeInt(posX); + data.writeInt(posY); + data.writeInt(posZ); + + super.writeData(data); + } + + @Override + public void readData(DataInputStream data) throws IOException { + + posX = data.readInt(); + posY = data.readInt(); + posZ = data.readInt(); + + super.readData(data); + } + + @Override + public TileEntity getTarget(World world) { + return world.getTileEntity(posX, posY, posZ); + } + +} diff --git a/forestry_common/core/forestry/core/network/PacketTileUpdate.java b/forestry_common/core/forestry/core/network/PacketTileUpdate.java new file mode 100755 index 000000000..63795a6b5 --- /dev/null +++ b/forestry_common/core/forestry/core/network/PacketTileUpdate.java @@ -0,0 +1,103 @@ +/******************************************************************************* + * Copyright 2011-2014 by SirSengir + * + * This work is licensed under a Creative Commons Attribution-NonCommercial-NoDerivs 3.0 Unported License. + * + * To view a copy of this license, visit http://creativecommons.org/licenses/by-nc-nd/3.0/. + ******************************************************************************/ +package forestry.core.network; + +import java.io.DataInputStream; +import java.io.DataOutputStream; +import java.io.IOException; + +import net.minecraftforge.common.util.ForgeDirection; + +import forestry.core.EnumErrorCode; +import forestry.core.gadgets.TileForestry; +import forestry.core.utils.EnumAccess; + +public class PacketTileUpdate extends PacketUpdate { + + private ForgeDirection orientation = ForgeDirection.WEST; + private EnumErrorCode errorState = EnumErrorCode.OK; + + private boolean isOwnable = false; + private EnumAccess access = EnumAccess.SHARED; + private String owner = null; + + public PacketTileUpdate() { + } + + public PacketTileUpdate(TileForestry tile) { + super(PacketIds.TILE_FORESTRY_UPDATE, tile.getPacketPayload()); + + posX = tile.xCoord; + posY = tile.yCoord; + posZ = tile.zCoord; + + orientation = tile.getOrientation(); + errorState = tile.getErrorState(); + + isOwnable = tile.isOwnable(); + access = tile.getAccess(); + owner = tile.owner; + if (owner == null || owner.isEmpty()) + owner = ""; + } + + @Override + public void writeData(DataOutputStream data) throws IOException { + + data.writeInt(posX); + data.writeInt(posY); + data.writeInt(posZ); + + data.writeInt(this.orientation.ordinal()); + data.writeInt(this.errorState.ordinal()); + + if (isOwnable) { + data.writeInt(access.ordinal()); + data.writeUTF(owner); + } else + data.writeInt(-1); + + super.writeData(data); + } + + @Override + public void readData(DataInputStream data) throws IOException { + + posX = data.readInt(); + posY = data.readInt(); + posZ = data.readInt(); + + orientation = ForgeDirection.values()[data.readInt()]; + errorState = EnumErrorCode.values()[data.readInt()]; + + int ordinal = data.readInt(); + isOwnable = ordinal >= 0; + if (isOwnable) { + access = EnumAccess.values()[ordinal]; + owner = data.readUTF(); + } + + super.readData(data); + } + + public ForgeDirection getOrientation() { + return this.orientation; + } + + public EnumErrorCode getErrorState() { + return this.errorState; + } + + public EnumAccess getAccess() { + return this.access; + } + + public String getOwner() { + return this.owner; + } +} diff --git a/forestry_common/core/forestry/core/network/PacketUpdate.java b/forestry_common/core/forestry/core/network/PacketUpdate.java new file mode 100755 index 000000000..013efedf5 --- /dev/null +++ b/forestry_common/core/forestry/core/network/PacketUpdate.java @@ -0,0 +1,102 @@ +/******************************************************************************* + * Copyright 2011-2014 by SirSengir + * + * This work is licensed under a Creative Commons Attribution-NonCommercial-NoDerivs 3.0 Unported License. + * + * To view a copy of this license, visit http://creativecommons.org/licenses/by-nc-nd/3.0/. + ******************************************************************************/ +package forestry.core.network; + +import java.io.DataInputStream; +import java.io.DataOutputStream; +import java.io.IOException; + +public class PacketUpdate extends PacketCoordinates { + + public PacketPayload payload; + + public PacketUpdate() { + } + + public PacketUpdate(int id) { + this(id, null); + } + + public PacketUpdate(int id, PacketPayload payload) { + this(id, 0, 0, 0, payload); + } + + public PacketUpdate(int id, int posX, int posY, int posZ, PacketPayload payload) { + super(id, posX, posY, posZ); + + this.payload = payload; + } + + public PacketUpdate(int id, int posX, int posY, int posZ, short val) { + super(id, posX, posY, posZ); + + this.payload = new PacketPayload(0, 1); + this.payload.shortPayload[0] = val; + } + + public PacketUpdate(int id, int posX, int posY, int posZ, int val) { + super(id, posX, posY, posZ); + + this.payload = new PacketPayload(1, 0); + this.payload.intPayload[0] = val; + } + + @Override + public void writeData(DataOutputStream data) throws IOException { + + super.writeData(data); + + // No payload means no data + if (payload == null) { + data.writeInt(0); + data.writeInt(0); + data.writeInt(0); + data.writeInt(0); + return; + } + + data.writeInt(payload.intPayload.length); + data.writeInt(payload.shortPayload.length); + data.writeInt(payload.floatPayload.length); + data.writeInt(payload.stringPayload.length); + + for (int intData : payload.intPayload) + data.writeInt(intData); + for (int shortData : payload.shortPayload) + data.writeShort(shortData); + for (float floatData : payload.floatPayload) + data.writeFloat(floatData); + for (String stringData : payload.stringPayload) + data.writeUTF(stringData); + + } + + @Override + public void readData(DataInputStream data) throws IOException { + + super.readData(data); + + payload = new PacketPayload(); + + payload.intPayload = new int[data.readInt()]; + payload.shortPayload = new short[data.readInt()]; + payload.floatPayload = new float[data.readInt()]; + payload.stringPayload = new String[data.readInt()]; + + for (int i = 0; i < payload.intPayload.length; i++) + payload.intPayload[i] = data.readInt(); + for (int i = 0; i < payload.shortPayload.length; i++) + payload.shortPayload[i] = data.readShort(); + for (int i = 0; i < payload.floatPayload.length; i++) + payload.floatPayload[i] = data.readFloat(); + for (int i = 0; i < payload.stringPayload.length; i++) + payload.stringPayload[i] = data.readUTF(); + + } + +} diff --git a/forestry_common/core/forestry/core/proxy/ClientProxyCommon.java b/forestry_common/core/forestry/core/proxy/ClientProxyCommon.java new file mode 100755 index 000000000..597bf3838 --- /dev/null +++ b/forestry_common/core/forestry/core/proxy/ClientProxyCommon.java @@ -0,0 +1,214 @@ +/******************************************************************************* + * Copyright 2011-2014 by SirSengir + * + * This work is licensed under a Creative Commons Attribution-NonCommercial-NoDerivs 3.0 Unported License. + * + * To view a copy of this license, visit http://creativecommons.org/licenses/by-nc-nd/3.0/. + ******************************************************************************/ +package forestry.core.proxy; + +import java.io.File; + +import net.minecraft.block.Block; +import net.minecraft.client.Minecraft; +import net.minecraft.client.entity.EntityPlayerSP; +import net.minecraft.client.particle.EntityExplodeFX; +import net.minecraft.client.resources.IResourceManager; +import net.minecraft.entity.player.EntityPlayer; +import net.minecraft.item.Item; +import net.minecraft.item.ItemStack; +import net.minecraft.util.ChunkCoordinates; +import net.minecraft.util.ResourceLocation; +import net.minecraft.world.World; + +import org.lwjgl.input.Keyboard; + +import forestry.apiculture.render.TextureBiomefinder; +import forestry.core.ForestryClient; +import forestry.core.TickHandlerCoreClient; +import forestry.core.config.Config; +import forestry.core.render.SpriteSheet; + +public class ClientProxyCommon extends ProxyCommon { + + @Override + public void bindTexture(ResourceLocation location) { + getClientInstance().getTextureManager().bindTexture(location); + } + + @Override + public void bindTexture(SpriteSheet spriteSheet) { + bindTexture(spriteSheet.getLocation()); + } + + @Override + public void registerTickHandlers() { + super.registerTickHandlers(); + + new TickHandlerCoreClient(); + } + + @Override + public IResourceManager getSelectedTexturePack(Minecraft minecraft) { + return minecraft.getResourceManager(); + } + + @Override + public void setBiomefinderCoordinates(EntityPlayer player, ChunkCoordinates coordinates) { + if (isSimulating(player.worldObj)) + super.setBiomefinderCoordinates(player, coordinates); + else + TextureBiomefinder.getInstance().setTargetCoordinates(coordinates); + // TextureHabitatLocatorFX.instance.setTargetCoordinates(coordinates); + } + + @Override + public File getForestryRoot() { + return new File("."); + } + + @Override + public World getRenderWorld() { + return getClientInstance().theWorld; + } + + @Override + public int getBlockModelIdEngine() { + return ForestryClient.blockModelIdEngine; + } + + @Override + public int getByBlockModelId() { + return ForestryClient.byBlockModelId; + } + + @Override + public boolean isOp(EntityPlayer player) { + return true; + } + + @Override + public double getBlockReachDistance(EntityPlayer entityplayer) { + if (entityplayer instanceof EntityPlayerSP) + return getClientInstance().playerController.getBlockReachDistance(); + else + return 4f; + } + + @Override + public boolean isSimulating(World world) { + return !world.isRemote; + } + + @Override + public boolean isShiftDown() { + return Keyboard.isKeyDown(Keyboard.KEY_LSHIFT) || Keyboard.isKeyDown(Keyboard.KEY_RSHIFT); + } + + @Override + public String getItemStackDisplayName(Item item) { + return item.getItemStackDisplayName(null); + } + + @Override + public String getItemStackDisplayName(ItemStack stack) { + return stack.getItem().getItemStackDisplayName(stack); + } + + @Override + public String getCurrentLanguage() { + return Minecraft.getMinecraft().getLanguageManager().getCurrentLanguage().getLanguageCode(); + } + + @Override + public String getDisplayName(ItemStack itemstack) { + return itemstack.getItem().getItemStackDisplayName(itemstack); + } + + @Override + public void playSoundFX(World world, int x, int y, int z, Block block) { + if (Proxies.common.isSimulating(world)) + super.playSoundFX(world, x, y, z, block); + else + playSoundFX(world, x, y, z, block.stepSound.getStepResourcePath(), block.stepSound.getVolume(), block.stepSound.getPitch()); + } + + @Override + public void playBlockBreakSoundFX(World world, int x, int y, int z, Block block) { + if (Proxies.common.isSimulating(world)) + super.playSoundFX(world, x, y, z, block); + else + playSoundFX(world, x, y, z, block.stepSound.getBreakSound(), block.stepSound.getVolume() / 4, block.stepSound.getPitch()); + } + + @Override + public void playBlockPlaceSoundFX(World world, int x, int y, int z, Block block) { + if (Proxies.common.isSimulating(world)) + super.playSoundFX(world, x, y, z, block); + else + playSoundFX(world, x, y, z, block.stepSound.getStepResourcePath(), block.stepSound.getVolume() / 4, block.stepSound.getPitch()); + } + + @Override + public void playSoundFX(World world, int x, int y, int z, String sound, float volume, float pitch) { + world.playSound(x + 0.5, y + 0.5, z + 0.5, sound, volume, (1.0f + (world.rand.nextFloat() - world.rand.nextFloat()) * 0.2f) * 0.7f, false); + } + + /** + * Renders a EntityBiodustFX on client. + * + * @param world + * @param d1 + * @param d2 + * @param d3 + * @param f1 + * @param f2 + * @param f3 + */ + // FIXME: This is causing crashes. + @Override + public void addEntityBiodustFX(World world, double d1, double d2, double d3, float f1, float f2, float f3) { + if (!Config.enableParticleFX) + return; + + // ModLoader.getMinecraftInstance().effectRenderer.addEffect(new EntityBiodustFX(world, d1, d2, d3, f1, f2, f3)); + } + + // FIXME: This is causing crashes. + @Override + public void addEntitySwarmFX(World world, double d1, double d2, double d3, float f1, float f2, float f3) { + if (!Config.enableParticleFX) + return; + + // ModLoader.getMinecraftInstance().effectRenderer.addEffect(new EntityHoneydustFX(world, d1, d2, d3, f1, f2, f3)); + } + + @Override + public void addEntityExplodeFX(World world, double d1, double d2, double d3, float f1, float f2, float f3) { + if (!Config.enableParticleFX) + return; + + getClientInstance().effectRenderer.addEffect(new EntityExplodeFX(world, d1, d2, d3, f1, f2, f3)); + } + + @Override + public void addBlockDestroyEffects(World world, int xCoord, int yCoord, int zCoord, Block block, int i) { + if (!isSimulating(world)) + getClientInstance().effectRenderer.addBlockDestroyEffects(xCoord, yCoord, zCoord, block, i); + else + super.addBlockDestroyEffects(world, xCoord, yCoord, zCoord, block, i); + } + + @Override + public void addBlockPlaceEffects(World world, int xCoord, int yCoord, int zCoord, Block block, int i) { + if (!isSimulating(world)) + playBlockPlaceSoundFX(world, xCoord, yCoord, zCoord, block); + else + super.addBlockPlaceEffects(world, xCoord, yCoord, zCoord, block, i); + } + + @Override + public EntityPlayer getPlayer() { + return Minecraft.getMinecraft().thePlayer; + } +} diff --git a/forestry_common/core/forestry/core/proxy/ClientProxyNetwork.java b/forestry_common/core/forestry/core/proxy/ClientProxyNetwork.java new file mode 100755 index 000000000..66d717f7c --- /dev/null +++ b/forestry_common/core/forestry/core/proxy/ClientProxyNetwork.java @@ -0,0 +1,18 @@ +/******************************************************************************* + * Copyright 2011-2014 by SirSengir + * + * This work is licensed under a Creative Commons Attribution-NonCommercial-NoDerivs 3.0 Unported License. + * + * To view a copy of this license, visit http://creativecommons.org/licenses/by-nc-nd/3.0/. + ******************************************************************************/ +package forestry.core.proxy; + +import forestry.core.network.ForestryPacket; + +public class ClientProxyNetwork extends ProxyNetwork { + + @Override + public void sendToServer(ForestryPacket packet) { + Proxies.common.getClientInstance().getNetHandler().addToSendQueue(packet.getPacket()); + } +} diff --git a/forestry_common/core/forestry/core/proxy/ClientProxyRender.java b/forestry_common/core/forestry/core/proxy/ClientProxyRender.java new file mode 100755 index 000000000..a37e4bcd2 --- /dev/null +++ b/forestry_common/core/forestry/core/proxy/ClientProxyRender.java @@ -0,0 +1,117 @@ +/******************************************************************************* + * Copyright 2011-2014 by SirSengir + * + * This work is licensed under a Creative Commons Attribution-NonCommercial-NoDerivs 3.0 Unported License. + * + * To view a copy of this license, visit http://creativecommons.org/licenses/by-nc-nd/3.0/. + ******************************************************************************/ +package forestry.core.proxy; + +import net.minecraft.client.Minecraft; +import net.minecraft.client.renderer.texture.IIconRegister; +import net.minecraft.client.renderer.tileentity.TileEntitySpecialRenderer; +import net.minecraft.world.World; + +import cpw.mods.fml.client.FMLClientHandler; +import cpw.mods.fml.client.registry.ClientRegistry; +import cpw.mods.fml.client.registry.RenderingRegistry; +import cpw.mods.fml.common.registry.VillagerRegistry; + +import forestry.core.config.Config; +import forestry.core.gadgets.MachineDefinition; +import forestry.core.interfaces.IBlockRenderer; +import forestry.core.render.BlockRenderingHandler; +import forestry.core.render.EntitySnowFX; +import forestry.core.render.RenderEscritoire; +import forestry.core.render.RenderMachine; +import forestry.core.render.RenderMill; +import forestry.core.render.TextureManager; +import forestry.core.render.TileRendererIndex; +import forestry.core.utils.ForestryResource; + +public class ClientProxyRender extends ProxyRender { + + @Override + public int getNextAvailableRenderId() { + return RenderingRegistry.getNextAvailableRenderId(); + } + + @Override + public boolean fancyGraphicsEnabled() { + return Proxies.common.getClientInstance().gameSettings.fancyGraphics; + } + + @Override + public boolean hasRendering() { + return true; + } + + @Override + public void registerTESR(MachineDefinition definition) { + BlockRenderingHandler.byBlockRenderer.put(new TileRendererIndex(definition.block, definition.meta), definition.renderer); + ClientRegistry.bindTileEntitySpecialRenderer(definition.teClass, (TileEntitySpecialRenderer) definition.renderer); + } + + @Override + public IBlockRenderer getRenderDefaultMachine(String gfxBase) { + return new RenderMachine(gfxBase); + } + + @Override + public IBlockRenderer getRenderMill(String gfxBase) { + return new RenderMill(gfxBase); + } + + @Override + public IBlockRenderer getRenderMill(String gfxBase, byte charges) { + return new RenderMill(gfxBase, charges); + } + + @Override + public IBlockRenderer getRenderEscritoire() { + return new RenderEscritoire(); + } + + private boolean shouldSpawnParticle(World world, boolean canDisable) { + if (canDisable && !Config.enableParticleFX) + return false; + Minecraft mc = FMLClientHandler.instance().getClient(); + int particleSetting = mc.gameSettings.particleSetting; + if (!canDisable && particleSetting > 1) + particleSetting = 1; + if (particleSetting == 1 && world.rand.nextInt(3) == 0) + particleSetting = 2; + if (particleSetting > 1) + return false; + return true; + } + + @Override + public void addSnowFX(World world, double xCoord, double yCoord, double zCoord, int color, int areaX, int areaY, int areaZ) { + if (!shouldSpawnParticle(world, true)) + return; + + double spawnX = xCoord + world.rand.nextInt(areaX * 2) - areaX; + double spawnY = yCoord + world.rand.nextInt(areaY); + double spawnZ = zCoord + world.rand.nextInt(areaZ * 2) - areaZ; + + Proxies.common.getClientInstance().effectRenderer.addEffect(new EntitySnowFX(world, spawnX, spawnY, spawnZ, 0.0f, 0.0f, 0.0f)); + } + + @Override + public short registerItemTexUID(IIconRegister register, short uid, String ident) { + TextureManager.getInstance().registerTexUID(register, uid, ident); + return uid; + } + + @Override + public short registerTerrainTexUID(IIconRegister register, short uid, String ident) { + TextureManager.getInstance().registerTexUID(register, uid, ident); + return uid; + } + + @Override + public void registerVillagerSkin(int villagerId, String texturePath) { + VillagerRegistry.instance().registerVillagerSkin(villagerId, new ForestryResource(texturePath)); + } +} diff --git a/forestry_common/core/forestry/core/proxy/Proxies.java b/forestry_common/core/forestry/core/proxy/Proxies.java new file mode 100755 index 000000000..52e80d72b --- /dev/null +++ b/forestry_common/core/forestry/core/proxy/Proxies.java @@ -0,0 +1,21 @@ +/******************************************************************************* + * Copyright 2011-2014 by SirSengir + * + * This work is licensed under a Creative Commons Attribution-NonCommercial-NoDerivs 3.0 Unported License. + * + * To view a copy of this license, visit http://creativecommons.org/licenses/by-nc-nd/3.0/. + ******************************************************************************/ +package forestry.core.proxy; + +import cpw.mods.fml.common.SidedProxy; + +public class Proxies { + @SidedProxy(clientSide = "forestry.core.proxy.ClientProxyCommon", serverSide = "forestry.core.proxy.ProxyCommon") + public static ProxyCommon common; + @SidedProxy(clientSide = "forestry.core.proxy.ClientProxyNetwork", serverSide = "forestry.core.proxy.ProxyNetwork") + public static ProxyNetwork net; + @SidedProxy(clientSide = "forestry.core.proxy.ClientProxyRender", serverSide = "forestry.core.proxy.ProxyRender") + public static ProxyRender render; + + public static ProxyLog log = new ProxyLog(); +} diff --git a/forestry_common/core/forestry/core/proxy/ProxyCommon.java b/forestry_common/core/forestry/core/proxy/ProxyCommon.java new file mode 100755 index 000000000..206bf506e --- /dev/null +++ b/forestry_common/core/forestry/core/proxy/ProxyCommon.java @@ -0,0 +1,259 @@ +/******************************************************************************* + * Copyright 2011-2014 by SirSengir + * + * This work is licensed under a Creative Commons Attribution-NonCommercial-NoDerivs 3.0 Unported License. + * + * To view a copy of this license, visit http://creativecommons.org/licenses/by-nc-nd/3.0/. + ******************************************************************************/ +package forestry.core.proxy; + +import java.io.File; + +import net.minecraft.block.Block; +import net.minecraft.client.Minecraft; +import net.minecraft.client.resources.IResourceManager; +import net.minecraft.entity.player.EntityPlayer; +import net.minecraft.entity.player.EntityPlayerMP; +import net.minecraft.item.Item; +import net.minecraft.item.ItemBlock; +import net.minecraft.item.ItemStack; +import net.minecraft.item.crafting.CraftingManager; +import net.minecraft.potion.Potion; +import net.minecraft.server.MinecraftServer; +import net.minecraft.util.ChunkCoordinates; +import net.minecraft.util.ResourceLocation; +import net.minecraft.world.World; + +import cpw.mods.fml.client.FMLClientHandler; +import cpw.mods.fml.common.FMLCommonHandler; +import cpw.mods.fml.common.Loader; +import cpw.mods.fml.common.registry.GameRegistry; + +import net.minecraftforge.oredict.ShapedOreRecipe; +import net.minecraftforge.oredict.ShapelessOreRecipe; + +import forestry.Forestry; +import forestry.core.TickHandlerCoreServer; +import forestry.core.config.Defaults; +import forestry.core.config.ForestryItem; +import forestry.core.network.PacketCoordinates; +import forestry.core.network.PacketFXSignal; +import forestry.core.network.PacketIds; +import forestry.core.render.SpriteSheet; + +public class ProxyCommon { + + public String getMinecraftVersion() { + return Loader.instance().getMinecraftModContainer().getVersion(); + } + + public void registerTickHandlers() { + new TickHandlerCoreServer(); + } + + public void registerBlock(Block block, Class itemClass) { + GameRegistry.registerBlock(block, itemClass, block.getUnlocalizedName()); + } + + public void registerItem(Item item) { + GameRegistry.registerItem(item, item.getUnlocalizedName().replace("item.", "")); + } + + /** + * As addRecipe, except that the recipe is injected into the front of the + * crafting manager to avoid certain generic collisions. Notably, all + * Forestry wood crafting into oak stairs & slabs. + */ + @SuppressWarnings("unchecked") + public void addPriorityRecipe(ItemStack itemstack, Object... obj) { + cleanRecipe(obj); + CraftingManager.getInstance().getRecipeList().add(0, new ShapedOreRecipe(itemstack, obj)); + } + + /** + * As addShapelessRecipe, except that the recipe is injected into the front + * of the crafting manager to avoid certain generic collisions. Notably, all + * Forestry wood crafting into oak stairs & slabs. + */ + @SuppressWarnings("unchecked") + public void addPriorityShapelessRecipe(ItemStack itemstack, Object... obj) { + cleanRecipe(obj); + CraftingManager.getInstance().getRecipeList().add(0, new ShapelessOreRecipe(itemstack, obj)); + } + + @SuppressWarnings("unchecked") + public void addRecipe(ItemStack itemstack, Object... obj) { + cleanRecipe(obj); + CraftingManager.getInstance().getRecipeList().add(new ShapedOreRecipe(itemstack, obj)); + } + + @SuppressWarnings("unchecked") + public void addShapelessRecipe(ItemStack itemstack, Object... obj) { + cleanRecipe(obj); + CraftingManager.getInstance().getRecipeList().add(new ShapelessOreRecipe(itemstack, obj)); + } + + private void cleanRecipe(Object... obj) { + for (int i = 0; i < obj.length; i++) { + if (obj[i] instanceof ForestryItem) { + obj[i] = ((ForestryItem) obj[i]).item(); + } + } + } + + public void addSmelting(ItemStack res, ItemStack prod) { + GameRegistry.addSmelting(res.getItem(), prod, 0.0f); // TODO: use full stack as arg? + } + + public void dropItemPlayer(EntityPlayer player, ItemStack stack) { + player.dropPlayerItemWithRandomChoice(stack, true); + } + + public void setBiomefinderCoordinates(EntityPlayer player, ChunkCoordinates coordinates) { + if (coordinates != null) + Forestry.packetHandler.sendPacket(new PacketCoordinates(PacketIds.HABITAT_BIOME_POINTER, coordinates).getPacket(), (EntityPlayerMP) player); + } + + public void removePotionEffect(EntityPlayer player, Potion effect) { + player.clearActivePotions(); + } + + public String getCurrentLanguage() { + return null; + } + + public String getItemStackDisplayName(Item item) { + return null; + } + + public String getDisplayName(ItemStack itemstack) { + return null; + } + + public File getForestryRoot() { + return new File("./"); + } + + public int getByBlockModelId() { + return 0; + } + + public boolean isOp(EntityPlayer player) { + MinecraftServer server = FMLCommonHandler.instance().getMinecraftServerInstance(); + return server.getConfigurationManager().isPlayerOpped(player.getGameProfile().getId()); + } + + public double getBlockReachDistance(EntityPlayer entityplayer) { + return 4f; + } + + public boolean isSimulating(World world) { + return true; + } + + public boolean isShiftDown() { + return false; + } + + public boolean isItemStackTagEqual(ItemStack stack1, ItemStack stack2) { + return ItemStack.areItemStackTagsEqual(stack1, stack2); + } + + public String getItemStackDisplayName(ItemStack stack) { + return null; + } + + public boolean setBlockWithNotify(World world, int x, int y, int z, Block block) { + return world.setBlock(x, y, z, block, 0, Defaults.FLAG_BLOCK_SYNCH); + } + + public void playSoundFX(World world, int x, int y, int z, Block block) { + Proxies.net.sendNetworkPacket(new PacketFXSignal(PacketFXSignal.SoundFXType.LEAF, x, y, z, block, 0), x, y, z); + } + + public void playSoundFX(World world, int x, int y, int z, String sound, float volume, float pitch) { + } + + public void addEntityBiodustFX(World world, double d1, double d2, double d3, float f1, float f2, float f3) { + } + + public void addEntitySwarmFX(World world, double d1, double d2, double d3, float f1, float f2, float f3) { + } + + public void addEntityExplodeFX(World world, double d1, double d2, double d3, float f1, float f2, float f3) { + } + + public boolean needsTagCompoundSynched(Item item) { + return item.getShareTag(); + } + + public void addBlockDestroyEffects(World world, int xCoord, int yCoord, int zCoord, Block block, int i) { + sendFXSignal(PacketFXSignal.VisualFXType.BLOCK_DESTROY, PacketFXSignal.SoundFXType.BLOCK_DESTROY, world, xCoord, yCoord, zCoord, block, i); + } + + public void addBlockPlaceEffects(World world, int xCoord, int yCoord, int zCoord, Block block, int i) { + sendFXSignal(PacketFXSignal.VisualFXType.NONE, PacketFXSignal.SoundFXType.BLOCK_PLACE, world, xCoord, yCoord, zCoord, block, i); + } + + public void playBlockBreakSoundFX(World world, int x, int y, int z, Block block) { + } + + public void playBlockPlaceSoundFX(World world, int x, int y, int z, Block block) { + } + + public void sendFXSignal(PacketFXSignal.VisualFXType visualFX, PacketFXSignal.SoundFXType soundFX, World world, int xCoord, int yCoord, int zCoord, + Block block, int i) { + if (Proxies.common.isSimulating(world)) + Proxies.net.sendNetworkPacket(new PacketFXSignal(visualFX, soundFX, xCoord, yCoord, zCoord, block, i), xCoord, yCoord, zCoord); + } + + public IResourceManager getSelectedTexturePack(Minecraft minecraft) { + return null; + } + + public World getRenderWorld() { + return null; + } + + public Minecraft getClientInstance() { + return FMLClientHandler.instance().getClient(); + } + + public int getBlockModelIdEngine() { + return 0; + } + + public void closeGUI(EntityPlayer player) { + ((EntityPlayerMP) player).closeScreen(); + } + + /* DEPENDENCY HANDLING */ + public boolean isModLoaded(String modname) { + return Loader.isModLoaded(modname); + } + + public Object instantiateIfModLoaded(String modname, String className) { + + if (isModLoaded(modname)) + try { + Class clas = Class.forName(className, true, Loader.instance().getModClassLoader()); + return clas.newInstance(); + } catch (Exception ex) { + Proxies.log.severe("Failed to load " + className + " even though mod " + modname + " was available."); + return null; + } + else + return null; + + } + + public void bindTexture(ResourceLocation location) { + } + + public void bindTexture(SpriteSheet spriteSheet) { + } + + public EntityPlayer getPlayer() { + return null; + } +} diff --git a/forestry_common/core/forestry/core/proxy/ProxyLog.java b/forestry_common/core/forestry/core/proxy/ProxyLog.java new file mode 100755 index 000000000..509e5e960 --- /dev/null +++ b/forestry_common/core/forestry/core/proxy/ProxyLog.java @@ -0,0 +1,119 @@ +/******************************************************************************* + * Copyright 2011-2014 by SirSengir + * + * This work is licensed under a Creative Commons Attribution-NonCommercial-NoDerivs 3.0 Unported License. + * + * To view a copy of this license, visit http://creativecommons.org/licenses/by-nc-nd/3.0/. + ******************************************************************************/ +package forestry.core.proxy; + +import org.apache.logging.log4j.Level; +import org.apache.logging.log4j.LogManager; +import org.apache.logging.log4j.Logger; + +import forestry.core.config.Defaults; + +public class ProxyLog { + + /* LOGGING */ + private static Logger forestryLogger; + + private void initLogger() { + forestryLogger = LogManager.getLogger(Defaults.MOD); + } + + /* FINEST */ + public void finest(String message) { + log(Level.TRACE, message); + } + + public void finest(String message, Object param) { + log(Level.TRACE, message, param); + } + + public void finest(String message, Object... params) { + log(Level.TRACE, message, params); + } + + /* FINER */ + public void finer(String message) { + log(Level.TRACE, message); + } + + public void finer(String message, Object param) { + log(Level.TRACE, message, param); + } + + public void finer(String message, Object... params) { + log(Level.TRACE, message, params); + } + + /* FINE */ + public void fine(String message) { + log(Level.DEBUG, message); + } + + public void fine(String message, Object param) { + log(Level.DEBUG, message, param); + } + + public void fine(String message, Object... params) { + log(Level.DEBUG, message, params); + } + + /* INFO */ + public void info(String message) { + log(Level.INFO, message); + } + + public void info(String message, Object param) { + log(Level.INFO, message, param); + } + + public void info(String message, Object... params) { + log(Level.INFO, message, params); + } + + /* WARNING */ + public void warning(String message) { + log(Level.WARN, message); + } + + public void warning(String message, Object param) { + log(Level.WARN, message, param); + } + + public void warning(String message, Object... params) { + log(Level.WARN, message, params); + } + + /* SEVERE */ + public void severe(String message) { + log(Level.FATAL, message); + } + + public void severe(String message, Object param) { + log(Level.FATAL, message, param); + } + + public void severe(String message, Object... params) { + log(Level.FATAL, message, params); + } + + /* GENERIC */ + public void log(Level logLevel, String message) { + if (forestryLogger == null) + initLogger(); + + forestryLogger.log(logLevel, message); + } + + public void log(Level logLevel, String message, Object... params) { + log(logLevel, String.format(message, params)); + } + + public void log(Level logLevel, String message, Object param) { + log(logLevel, String.format(message, param)); + } + +} diff --git a/forestry_common/core/forestry/core/proxy/ProxyNetwork.java b/forestry_common/core/forestry/core/proxy/ProxyNetwork.java new file mode 100755 index 000000000..189914973 --- /dev/null +++ b/forestry_common/core/forestry/core/proxy/ProxyNetwork.java @@ -0,0 +1,52 @@ +/******************************************************************************* + * Copyright 2011-2014 by SirSengir + * + * This work is licensed under a Creative Commons Attribution-NonCommercial-NoDerivs 3.0 Unported License. + * + * To view a copy of this license, visit http://creativecommons.org/licenses/by-nc-nd/3.0/. + ******************************************************************************/ +package forestry.core.proxy; + +import net.minecraft.entity.player.EntityPlayer; +import net.minecraft.entity.player.EntityPlayerMP; +import net.minecraft.world.World; + +import net.minecraftforge.common.DimensionManager; + +import forestry.Forestry; +import forestry.core.config.Defaults; +import forestry.core.network.ForestryPacket; + +public class ProxyNetwork { + + public void sendNetworkPacket(ForestryPacket packet, int x, int y, int z) { + if (packet == null) + return; + + World[] worlds = DimensionManager.getWorlds(); + for (int i = 0; i < worlds.length; i++) + for (int j = 0; j < worlds[i].playerEntities.size(); j++) { + EntityPlayerMP player = (EntityPlayerMP) worlds[i].playerEntities.get(j); + + if (Math.abs(player.posX - x) <= Defaults.NET_MAX_UPDATE_DISTANCE && Math.abs(player.posY - y) <= Defaults.NET_MAX_UPDATE_DISTANCE + && Math.abs(player.posZ - z) <= Defaults.NET_MAX_UPDATE_DISTANCE) + Forestry.packetHandler.sendPacket(packet.getPacket(), player); + } + } + + public void sendToPlayer(ForestryPacket packet, EntityPlayer entityplayer) { + if (!(entityplayer instanceof EntityPlayerMP)) + return; + + EntityPlayerMP player = (EntityPlayerMP) entityplayer; + Forestry.packetHandler.sendPacket(packet.getPacket(), player); + } + + public void sendToServer(ForestryPacket packet) { + } + + public void inventoryChangeNotify(EntityPlayer player) { + if (player instanceof EntityPlayerMP) + ((EntityPlayerMP) player).sendContainerToPlayer(player.inventoryContainer); + } +} diff --git a/forestry_common/core/forestry/core/proxy/ProxyRender.java b/forestry_common/core/forestry/core/proxy/ProxyRender.java new file mode 100755 index 000000000..5abd13d8b --- /dev/null +++ b/forestry_common/core/forestry/core/proxy/ProxyRender.java @@ -0,0 +1,62 @@ +/******************************************************************************* + * Copyright 2011-2014 by SirSengir + * + * This work is licensed under a Creative Commons Attribution-NonCommercial-NoDerivs 3.0 Unported License. + * + * To view a copy of this license, visit http://creativecommons.org/licenses/by-nc-nd/3.0/. + ******************************************************************************/ +package forestry.core.proxy; + +import net.minecraft.client.renderer.texture.IIconRegister; +import net.minecraft.world.World; + +import forestry.core.gadgets.MachineDefinition; +import forestry.core.interfaces.IBlockRenderer; + +public class ProxyRender { + + public int getNextAvailableRenderId() { + return 0; + } + + public boolean fancyGraphicsEnabled() { + return false; + } + + public boolean hasRendering() { + return false; + } + + public void registerTESR(MachineDefinition definition) { + } + + public IBlockRenderer getRenderDefaultMachine(String gfxBase) { + return null; + } + + public IBlockRenderer getRenderMill(String gfxBase) { + return null; + } + + public IBlockRenderer getRenderMill(String gfxBase, byte charges) { + return null; + } + + public IBlockRenderer getRenderEscritoire() { + return null; + } + + public void addSnowFX(World world, double xCoord, double yCoord, double zCoord, int color, int areaX, int areaY, int areaZ) { + } + + public short registerItemTexUID(IIconRegister register, short uid, String ident) { + return uid; + } + + public short registerTerrainTexUID(IIconRegister register, short uid, String ident) { + return uid; + } + + public void registerVillagerSkin(int villagerId, String texturePath) { + } +} diff --git a/forestry_common/core/forestry/core/render/BlockRenderingHandler.java b/forestry_common/core/forestry/core/render/BlockRenderingHandler.java new file mode 100755 index 000000000..c78761ab6 --- /dev/null +++ b/forestry_common/core/forestry/core/render/BlockRenderingHandler.java @@ -0,0 +1,51 @@ +/******************************************************************************* + * Copyright 2011-2014 by SirSengir + * + * This work is licensed under a Creative Commons Attribution-NonCommercial-NoDerivs 3.0 Unported License. + * + * To view a copy of this license, visit http://creativecommons.org/licenses/by-nc-nd/3.0/. + ******************************************************************************/ +package forestry.core.render; + +import java.util.HashMap; + +import net.minecraft.block.Block; +import net.minecraft.client.renderer.RenderBlocks; +import net.minecraft.world.IBlockAccess; + +import cpw.mods.fml.client.registry.ISimpleBlockRenderingHandler; + +import forestry.core.ForestryClient; +import forestry.core.interfaces.IBlockRenderer; + +public class BlockRenderingHandler implements ISimpleBlockRenderingHandler { + + public static HashMap byBlockRenderer = new HashMap(); + + @Override + public void renderInventoryBlock(Block block, int metadata, int modelID, RenderBlocks renderer) { + + if (block.getRenderType() == ForestryClient.byBlockModelId) { + TileRendererIndex index = new TileRendererIndex(block, metadata); + if (byBlockRenderer.containsKey(index)) + byBlockRenderer.get(index).inventoryRender(-0.5, -0.5, -0.5, 0, 0); + } + + } + + @Override + public boolean renderWorldBlock(IBlockAccess world, int x, int y, int z, Block block, int modelId, RenderBlocks renderer) { + return true; + } + + @Override + public boolean shouldRender3DInInventory(int modelId) { + return true; + } + + @Override + public int getRenderId() { + return ForestryClient.byBlockModelId; + } + +} diff --git a/forestry_common/core/forestry/core/render/EntityBiodustFX.java b/forestry_common/core/forestry/core/render/EntityBiodustFX.java new file mode 100755 index 000000000..032499f4a --- /dev/null +++ b/forestry_common/core/forestry/core/render/EntityBiodustFX.java @@ -0,0 +1,33 @@ +/******************************************************************************* + * Copyright 2011-2014 by SirSengir + * + * This work is licensed under a Creative Commons Attribution-NonCommercial-NoDerivs 3.0 Unported License. + * + * To view a copy of this license, visit http://creativecommons.org/licenses/by-nc-nd/3.0/. + ******************************************************************************/ +package forestry.core.render; + +import net.minecraft.client.particle.EntityReddustFX; +import net.minecraft.world.World; + +public class EntityBiodustFX extends EntityReddustFX { + + public EntityBiodustFX(World world, double d, double d1, double d2, float f, float f1, float f2) { + this(world, d, d1, d2, 1.0F, f, f1, f2); + } + + public EntityBiodustFX(World world, double d, double d1, double d2, float f, float f1, float f2, float f3) { + super(world, d, d1, d2, f, f1, f2, f3); + // float f4 = (float)Math.random() * 0.4F + 0.6F; + // particleRed = ((float)(Math.random() * 0.20000000298023224D) + 0.8F) + // * f1 * f4; + // particleGreen = ((float)(Math.random() * 0.20000000298023224D) + + // 0.8F) * f2 * f4; + // particleBlue = ((float)(Math.random() * 0.20000000298023224D) + 0.8F) + // * f3 * f4; + particleRed = 0F; + particleGreen = 1.0F; + particleBlue = 0F; + } + +} diff --git a/forestry_common/core/forestry/core/render/EntityHoneydustFX.java b/forestry_common/core/forestry/core/render/EntityHoneydustFX.java new file mode 100755 index 000000000..510883d9a --- /dev/null +++ b/forestry_common/core/forestry/core/render/EntityHoneydustFX.java @@ -0,0 +1,33 @@ +/******************************************************************************* + * Copyright 2011-2014 by SirSengir + * + * This work is licensed under a Creative Commons Attribution-NonCommercial-NoDerivs 3.0 Unported License. + * + * To view a copy of this license, visit http://creativecommons.org/licenses/by-nc-nd/3.0/. + ******************************************************************************/ +package forestry.core.render; + +import net.minecraft.client.particle.EntityReddustFX; +import net.minecraft.world.World; + +public class EntityHoneydustFX extends EntityReddustFX { + + public EntityHoneydustFX(World world, double d, double d1, double d2, float f, float f1, float f2) { + this(world, d, d1, d2, 1.0F, f, f1, f2); + } + + public EntityHoneydustFX(World world, double d, double d1, double d2, float f, float f1, float f2, float f3) { + super(world, d, d1, d2, f, f1, f2, f3); + // float f4 = (float)Math.random() * 0.4F + 0.6F; + // particleRed = ((float)(Math.random() * 0.20000000298023224D) + 0.95F) + // * f1 * f4; + // particleGreen = ((float)(Math.random() * 0.20000000298023224D) + + // 0.75F) * f2 * f4; + // particleBlue = ((float)(Math.random() * 0.20000000298023224D) + 0.1F) + // * f3 * f4; + particleRed = 0.9F; + particleGreen = 0.75F; + particleBlue = 0F; + } + +} diff --git a/forestry_common/core/forestry/core/render/EntitySnowFX.java b/forestry_common/core/forestry/core/render/EntitySnowFX.java new file mode 100755 index 000000000..1d7c21acf --- /dev/null +++ b/forestry_common/core/forestry/core/render/EntitySnowFX.java @@ -0,0 +1,77 @@ +/******************************************************************************* + * Copyright 2011-2014 by SirSengir + * + * This work is licensed under a Creative Commons Attribution-NonCommercial-NoDerivs 3.0 Unported License. + * + * To view a copy of this license, visit http://creativecommons.org/licenses/by-nc-nd/3.0/. + ******************************************************************************/ +package forestry.core.render; + +import java.util.Random; + +import net.minecraft.client.particle.EntityFX; +import net.minecraft.client.renderer.Tessellator; +import net.minecraft.util.IIcon; +import net.minecraft.world.World; + +public class EntitySnowFX extends EntityFX { + + public static IIcon icons[]; + private Random spreadRand = new Random(); + + public EntitySnowFX(World world, double x, double y, double z, float motionScaleX, float motionScaleY, float motionScaleZ) { + super(world, x, y, z, 0.0D, 0.0D, 0.0D); + + this.setParticleIcon(icons[rand.nextInt(icons.length)]); + this.particleScale *= 0.5F; + this.particleMaxAge = (int) (40.0D / (Math.random() * 0.8D + 0.2D)); + this.noClip = true; + + this.motionX *= 0.01D; + this.motionY *= -0.4D; + this.motionZ *= 0.01D; + } + + @Override + public int getFXLayer() { + return 2; + } + + @Override + public void renderParticle(Tessellator tess, float timeStep, float rotationX, float rotationXZ, float rotationZ, float rotationYZ, float rotationXY) { + double x = (this.prevPosX + (this.posX - this.prevPosX) * timeStep - interpPosX); + double y = (this.prevPosY + (this.posY - this.prevPosY) * timeStep - interpPosY); + double z = (this.prevPosZ + (this.posZ - this.prevPosZ) * timeStep - interpPosZ); + + float minU = this.particleTextureIndexX / 16.0F; + float maxU = minU + 0.0624375F; + float minV = this.particleTextureIndexY / 16.0F; + float maxV = minV + 0.0624375F; + float scale = 0.1F * this.particleScale; + + if (this.particleIcon != null) { + minU = this.particleIcon.getMinU(); + maxU = this.particleIcon.getMaxU(); + minV = this.particleIcon.getMinV(); + maxV = this.particleIcon.getMaxV(); + } + + float brightness = 1.0F; + tess.setColorRGBA_F(this.particleRed * brightness, this.particleGreen * brightness, this.particleBlue * brightness, this.particleAlpha); + + spreadRand.setSeed(701); + + for (int i = 0; i < 5; i++) { + renderParticle(tess, x + spreadRand.nextGaussian() * 8, y, z + spreadRand.nextGaussian() * 8, rotationX, rotationXZ, rotationZ, rotationYZ, rotationXY, minU, maxU, minV, maxV, scale); + } + + } + + private void renderParticle(Tessellator tess, double x, double y, double z, float rotationX, float rotationXZ, float rotationZ, float rotationYZ, float rotationXY, + float minU, float maxU, float minV, float maxV, float scale) { + tess.addVertexWithUV((x - rotationX * scale - rotationYZ * scale), (y - rotationXZ * scale), (z - rotationZ * scale - rotationXY * scale), maxU, maxV); + tess.addVertexWithUV((x - rotationX * scale + rotationYZ * scale), (y + rotationXZ * scale), (z - rotationZ * scale + rotationXY * scale), maxU, minV); + tess.addVertexWithUV((x + rotationX * scale + rotationYZ * scale), (y + rotationXZ * scale), (z + rotationZ * scale + rotationXY * scale), minU, minV); + tess.addVertexWithUV((x + rotationX * scale - rotationYZ * scale), (y - rotationXZ * scale), (z + rotationZ * scale - rotationXY * scale), minU, maxV); + } +} diff --git a/forestry_common/core/forestry/core/render/ModelEscritoire.java b/forestry_common/core/forestry/core/render/ModelEscritoire.java new file mode 100755 index 000000000..72f586262 --- /dev/null +++ b/forestry_common/core/forestry/core/render/ModelEscritoire.java @@ -0,0 +1,193 @@ +/******************************************************************************* + * Copyright 2011-2014 by SirSengir + * + * This work is licensed under a Creative Commons Attribution-NonCommercial-NoDerivs 3.0 Unported License. + * + * To view a copy of this license, visit http://creativecommons.org/licenses/by-nc-nd/3.0/. + ******************************************************************************/ +package forestry.core.render; + +import net.minecraft.client.model.ModelBase; +import net.minecraft.client.model.ModelRenderer; +import net.minecraft.entity.Entity; + +public class ModelEscritoire extends ModelBase { + + //fields + ModelRenderer desk; + ModelRenderer standRB; + ModelRenderer standRF; + ModelRenderer standLB; + ModelRenderer standLF; + ModelRenderer drawers; + ModelRenderer standLowLF; + ModelRenderer standLowRB; + ModelRenderer standLowRF; + ModelRenderer standLowLB; + + public ModelEscritoire() { + textureWidth = 64; + textureHeight = 32; + + desk = new ModelRenderer(this, 0, 0); + desk.addBox(-8F, 3F, -7.8F, 16, 2, 15); + desk.setRotationPoint(0F, 0F, 0F); + desk.setTextureSize(64, 32); + desk.mirror = true; + setRotation(desk, 0.0872665f, 0f, 0f); + standRB = new ModelRenderer(this, 38, 18); + standRB.addBox(5F, 4F, 5F, 2, 6, 2); + standRB.setRotationPoint(0F, 0F, 0F); + standRB.setTextureSize(64, 32); + standRB.mirror = true; + setRotation(standRB, 0F, 0F, 0F); + standRF = new ModelRenderer(this, 38, 18); + standRF.addBox(5F, 4F, -7F, 2, 6, 2); + standRF.setRotationPoint(0F, 0F, 0F); + standRF.setTextureSize(64, 32); + standRF.mirror = true; + setRotation(standRF, 0F, 0F, 0F); + standLB = new ModelRenderer(this, 38, 18); + standLB.addBox(-7F, 4F, 5F, 2, 6, 2); + standLB.setRotationPoint(0F, 0F, 0F); + standLB.setTextureSize(64, 32); + standLB.mirror = true; + setRotation(standLB, 0F, 0F, 0F); + standLF = new ModelRenderer(this, 38, 18); + standLF.addBox(-7F, 4F, -7F, 2, 6, 2); + standLF.setRotationPoint(0F, 0F, 0F); + standLF.setTextureSize(64, 32); + standLF.mirror = true; + setRotation(standLF, 0F, 0F, 0F); + drawers = new ModelRenderer(this, 0, 18); + drawers.addBox(-7.5F, -2F, 4.5F, 15, 5, 3); + drawers.setRotationPoint(0F, 0F, 0F); + drawers.setTextureSize(64, 32); + drawers.mirror = true; + setRotation(drawers, 0F, 0F, 0F); + standLowLF = new ModelRenderer(this, 0, 26); + standLowLF.addBox(-6.5F, 10F, -6.5F, 1, 4, 1); + standLowLF.setRotationPoint(0F, 0F, 0F); + standLowLF.setTextureSize(64, 32); + standLowLF.mirror = true; + setRotation(standLowLF, 0F, 0F, 0F); + standLowRB = new ModelRenderer(this, 0, 26); + standLowRB.addBox(5.5F, 10F, 5.5F, 1, 4, 1); + standLowRB.setRotationPoint(0F, 0F, 0F); + standLowRB.setTextureSize(64, 32); + standLowRB.mirror = true; + setRotation(standLowRB, 0F, 0F, 0F); + standLowRF = new ModelRenderer(this, 0, 26); + standLowRF.addBox(5.5F, 10F, -6.5F, 1, 4, 1); + standLowRF.setRotationPoint(0F, 0F, 0F); + standLowRF.setTextureSize(64, 32); + standLowRF.mirror = true; + setRotation(standLowRF, 0F, 0F, 0F); + standLowLB = new ModelRenderer(this, 0, 26); + standLowLB.addBox(-6.5F, 10F, 5.5F, 1, 4, 1); + standLowLB.setRotationPoint(0F, 0F, 0F); + standLowLB.setTextureSize(64, 32); + standLowLB.mirror = true; + setRotation(standLowLB, 0F, 0F, 0F); + /* + desk = new ModelRenderer(this, 0, 0); + desk.addBox(0F, 0F, 0F, 16, 2, 15); + desk.setRotationPoint(-8F, 4F, -7.5F); + desk.setTextureSize(64, 32); + desk.mirror = true; + setRotation(desk, 0.0872665F, 0F, 0F); + standRB = new ModelRenderer(this, 38, 18); + standRB.addBox(0F, 0F, 0F, 2, 6, 2); + standRB.setRotationPoint(5F, 4F, 5F); + standRB.setTextureSize(64, 32); + standRB.mirror = true; + setRotation(standRB, 0F, 0F, 0F); + standRF = new ModelRenderer(this, 38, 18); + standRF.addBox(0F, 0F, 0F, 2, 6, 2); + standRF.setRotationPoint(5F, 4F, -7F); + standRF.setTextureSize(64, 32); + standRF.mirror = true; + setRotation(standRF, 0F, 0F, 0F); + standLB = new ModelRenderer(this, 38, 18); + standLB.addBox(0F, 0F, 0F, 2, 6, 2); + standLB.setRotationPoint(-7F, 4F, 5F); + standLB.setTextureSize(64, 32); + standLB.mirror = true; + setRotation(standLB, 0F, 0F, 0F); + standLF = new ModelRenderer(this, 38, 18); + standLF.addBox(0F, 0F, 0F, 2, 6, 2); + standLF.setRotationPoint(-7F, 4F, -7F); + standLF.setTextureSize(64, 32); + standLF.mirror = true; + setRotation(standLF, 0F, 0F, 0F); + drawers = new ModelRenderer(this, 0, 18); + drawers.addBox(0F, 0F, 0F, 16, 5, 3); + drawers.setRotationPoint(-8F, -2F, 4.5F); + drawers.setTextureSize(64, 32); + drawers.mirror = true; + setRotation(drawers, 0F, 0F, 0F); + standLowLF = new ModelRenderer(this, 0, 25); + standLowLF.addBox(0F, 0F, 0F, 1, 4, 1); + standLowLF.setRotationPoint(-6.5F, 10F, -6.5F); + standLowLF.setTextureSize(64, 32); + standLowLF.mirror = true; + setRotation(standLowLF, 0F, 0F, 0F); + standLowRB = new ModelRenderer(this, 0, 25); + standLowRB.addBox(0F, 0F, 0F, 1, 4, 1); + standLowRB.setRotationPoint(5.5F, 10F, 5.5F); + standLowRB.setTextureSize(64, 32); + standLowRB.mirror = true; + setRotation(standLowRB, 0F, 0F, 0F); + standLowRF = new ModelRenderer(this, 0, 25); + standLowRF.addBox(0F, 0F, 0F, 1, 4, 1); + standLowRF.setRotationPoint(5.5F, 10F, -6.5F); + standLowRF.setTextureSize(64, 32); + standLowRF.mirror = true; + setRotation(standLowRF, 0F, 0F, 0F); + standLowLB = new ModelRenderer(this, 0, 25); + standLowLB.addBox(0F, 0F, 0F, 1, 4, 1); + standLowLB.setRotationPoint(-6.5F, 10F, 5.5F); + standLowLB.setTextureSize(64, 32); + standLowLB.mirror = true; + setRotation(standLowLB, 0F, 0F, 0F); + */ + } + + @Override + 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); + desk.render(f5); + standRB.render(f5); + standRF.render(f5); + standLB.render(f5); + standLF.render(f5); + drawers.render(f5); + standLowLF.render(f5); + standLowRB.render(f5); + standLowRF.render(f5); + standLowLB.render(f5); + } + + private void setRotation(ModelRenderer model, float x, float y, float z) { + model.rotateAngleX = x; + model.rotateAngleY = y; + model.rotateAngleZ = z; + } + + @Override + public void setRotationAngles(float f, float f1, float f2, float f3, float f4, float f5, Entity entity) { + setRotation(desk, f + 0.0872665f, f1, f2); + setRotation(standRB, f, f1, f2); + setRotation(standRF, f, f1, f2); + setRotation(standLB, f, f1, f2); + setRotation(standLF, f, f1, f2); + setRotation(drawers, f, f1, f2); + setRotation(standLowLF, f, f1, f2); + setRotation(standLowRB, f, f1, f2); + setRotation(standLowRF, f, f1, f2); + setRotation(standLowLB, f, f1, f2); + super.setRotationAngles(f, f1, f2, f3, f4, f5, entity); + } + +} diff --git a/forestry_common/core/forestry/core/render/OverlayRenderingHandler.java b/forestry_common/core/forestry/core/render/OverlayRenderingHandler.java new file mode 100755 index 000000000..1a6c82aa4 --- /dev/null +++ b/forestry_common/core/forestry/core/render/OverlayRenderingHandler.java @@ -0,0 +1,110 @@ +/******************************************************************************* + * Copyright 2011-2014 by SirSengir + * + * This work is licensed under a Creative Commons Attribution-NonCommercial-NoDerivs 3.0 Unported License. + * + * To view a copy of this license, visit http://creativecommons.org/licenses/by-nc-nd/3.0/. + ******************************************************************************/ +package forestry.core.render; + +import net.minecraft.block.Block; +import net.minecraft.client.renderer.RenderBlocks; +import net.minecraft.client.renderer.Tessellator; +import net.minecraft.util.IIcon; +import net.minecraft.world.IBlockAccess; + +import cpw.mods.fml.client.registry.ISimpleBlockRenderingHandler; + +public abstract class OverlayRenderingHandler implements ISimpleBlockRenderingHandler { + + protected static final double OVERLAY_SHIFT = 0.001; + + protected int determineMixedBrightness(IBlockAccess world, Block block, int x, int y, int z, RenderBlocks renderer, int mixedBrightness) { + return renderer.renderMinY > 0.0D ? mixedBrightness : block.getMixedBrightnessForBlock(world, x, y, z); + } + + protected void renderBottomFace(IBlockAccess world, Block block, int x, int y, int z, RenderBlocks renderer, IIcon textureIndex, int mixedBrightness, + float r, float g, float b) { + + if (!renderer.renderAllFaces && !block.shouldSideBeRendered(world, x, y - 1, z, 0)) + return; + + Tessellator tesselator = Tessellator.instance; + + tesselator.setBrightness(determineMixedBrightness(world, block, x, y - 1, z, renderer, mixedBrightness)); + tesselator.setColorOpaque_F(r, g, b); + renderer.renderFaceYNeg(block, x, y - OVERLAY_SHIFT, z, textureIndex); + + } + + protected void renderTopFace(IBlockAccess world, Block block, int x, int y, int z, RenderBlocks renderer, IIcon textureIndex, int mixedBrightness, float r, + float g, float b) { + + if (!renderer.renderAllFaces && !block.shouldSideBeRendered(world, x, y + 1, z, 1)) + return; + + Tessellator tesselator = Tessellator.instance; + + tesselator.setBrightness(determineMixedBrightness(world, block, x, y + 1, z, renderer, mixedBrightness)); + tesselator.setColorOpaque_F(r, g, b); + renderer.renderFaceYPos(block, x, y + OVERLAY_SHIFT, z, textureIndex); + + } + + protected void renderEastFace(IBlockAccess world, Block block, int x, int y, int z, RenderBlocks renderer, IIcon textureIndex, int mixedBrightness, float r, + float g, float b) { + + if (!renderer.renderAllFaces && !block.shouldSideBeRendered(world, x, y, z - 1, 2)) + return; + + Tessellator tesselator = Tessellator.instance; + + tesselator.setBrightness(determineMixedBrightness(world, block, x, y, z - 1, renderer, mixedBrightness)); + tesselator.setColorOpaque_F(r, g, b); + renderer.renderFaceZNeg(block, x, y, z - OVERLAY_SHIFT, textureIndex); + + } + + protected void renderWestFace(IBlockAccess world, Block block, int x, int y, int z, RenderBlocks renderer, IIcon textureIndex, int mixedBrightness, float r, + float g, float b) { + + if (!renderer.renderAllFaces && !block.shouldSideBeRendered(world, x, y, z + 1, 3)) + return; + + Tessellator tesselator = Tessellator.instance; + + tesselator.setBrightness(determineMixedBrightness(world, block, x, y, z + 1, renderer, mixedBrightness)); + tesselator.setColorOpaque_F(r, g, b); + renderer.renderFaceZPos(block, x, y, z + OVERLAY_SHIFT, textureIndex); + + } + + protected void renderNorthFace(IBlockAccess world, Block block, int x, int y, int z, RenderBlocks renderer, IIcon textureIndex, int mixedBrightness, + float r, float g, float b) { + + if (!renderer.renderAllFaces && !block.shouldSideBeRendered(world, x - 1, y, z, 4)) + return; + + Tessellator tesselator = Tessellator.instance; + + tesselator.setBrightness(determineMixedBrightness(world, block, x - 1, y, z, renderer, mixedBrightness)); + tesselator.setColorOpaque_F(r, g, b); + renderer.renderFaceXNeg(block, x - OVERLAY_SHIFT, y, z, textureIndex); + + } + + protected void renderSouthFace(IBlockAccess world, Block block, int x, int y, int z, RenderBlocks renderer, IIcon textureIndex, int mixedBrightness, + float r, float g, float b) { + + if (!renderer.renderAllFaces && !block.shouldSideBeRendered(world, x + 1, y, z, 5)) + return; + + Tessellator tesselator = Tessellator.instance; + + tesselator.setBrightness(determineMixedBrightness(world, block, x + 1, y, z, renderer, mixedBrightness)); + tesselator.setColorOpaque_F(r, g, b); + renderer.renderFaceXPos(block, x + OVERLAY_SHIFT, y, z, textureIndex); + + } + +} diff --git a/forestry_common/core/forestry/core/render/RenderAnalyzer.java b/forestry_common/core/forestry/core/render/RenderAnalyzer.java new file mode 100755 index 000000000..8b6b228a8 --- /dev/null +++ b/forestry_common/core/forestry/core/render/RenderAnalyzer.java @@ -0,0 +1,89 @@ +/******************************************************************************* + * Copyright 2011-2014 by SirSengir + * + * This work is licensed under a Creative Commons Attribution-NonCommercial-NoDerivs 3.0 Unported License. + * + * To view a copy of this license, visit http://creativecommons.org/licenses/by-nc-nd/3.0/. + ******************************************************************************/ +package forestry.core.render; + +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.world.World; + +import net.minecraftforge.common.util.ForgeDirection; + +import org.lwjgl.opengl.GL11; + +import forestry.apiculture.render.ModelAnalyzer; +import forestry.core.gadgets.TileAnalyzer; +import forestry.core.interfaces.IBlockRenderer; + +public class RenderAnalyzer extends TileEntitySpecialRenderer implements IBlockRenderer { + + private ModelAnalyzer model; + private final EntityItem dummyEntityItem = new EntityItem(null); + private final RenderItem customRenderItem; + private long lastTick; + + public RenderAnalyzer() { + customRenderItem = new RenderItem() { + @Override + public boolean shouldBob() { + return true; + } + + @Override + public boolean shouldSpreadItems() { + return false; + }; + }; + customRenderItem.setRenderManager(RenderManager.instance); + } + + public RenderAnalyzer(String baseTexture) { + this(); + this.model = new ModelAnalyzer(baseTexture); + } + + @Override + public void inventoryRender(double x, double y, double z, float f, float f1) { + render(null, null, ForgeDirection.WEST, x, y, z); + } + + @Override + public void renderTileEntityAt(TileEntity tile, double d, double d1, double d2, float f) { + + TileAnalyzer analyzer = (TileAnalyzer) tile; + render(analyzer.getIndividualOnDisplay(), tile.getWorldObj(), analyzer.getOrientation(), d, d1, d2); + } + + private void render(ItemStack itemstack, World world, ForgeDirection orientation, double x, double y, double z) { + + dummyEntityItem.worldObj = world; + + model.render(orientation, (float) x, (float) y, (float) z); + if (itemstack == null) + return; + float renderScale = 1.0f; + + GL11.glPushMatrix(); + GL11.glTranslatef((float) x, (float) y, (float) z); + GL11.glTranslatef(0.5f, 0.2f, 0.5f); + GL11.glScalef(renderScale, renderScale, renderScale); + dummyEntityItem.setEntityItemStack(itemstack); + + if (world.getTotalWorldTime() != lastTick) { + lastTick = world.getTotalWorldTime(); + dummyEntityItem.onUpdate(); + } + customRenderItem.doRender(dummyEntityItem, 0, 0, 0, 0, 0); + GL11.glPopMatrix(); + + } + +} diff --git a/forestry_common/core/forestry/core/render/RenderEscritoire.java b/forestry_common/core/forestry/core/render/RenderEscritoire.java new file mode 100755 index 000000000..905cecfd0 --- /dev/null +++ b/forestry_common/core/forestry/core/render/RenderEscritoire.java @@ -0,0 +1,114 @@ +/******************************************************************************* + * Copyright 2011-2014 by SirSengir + * + * This work is licensed under a Creative Commons Attribution-NonCommercial-NoDerivs 3.0 Unported License. + * + * To view a copy of this license, visit http://creativecommons.org/licenses/by-nc-nd/3.0/. + ******************************************************************************/ +package forestry.core.render; + +import net.minecraft.client.renderer.entity.RenderItem; +import net.minecraft.client.renderer.entity.RenderManager; +import net.minecraft.client.renderer.tileentity.TileEntitySpecialRenderer; +import net.minecraft.item.ItemStack; +import net.minecraft.tileentity.TileEntity; +import net.minecraft.util.ResourceLocation; + +import net.minecraftforge.common.util.ForgeDirection; + +import org.lwjgl.opengl.GL11; + +import forestry.core.config.Defaults; +import forestry.core.gadgets.TileEscritoire; +import forestry.core.interfaces.IBlockRenderer; +import forestry.core.proxy.Proxies; +import forestry.core.utils.ForestryResource; + +public class RenderEscritoire extends TileEntitySpecialRenderer implements IBlockRenderer { + + ModelEscritoire modelEscritoire; + ResourceLocation texture = new ForestryResource(Defaults.TEXTURE_PATH_BLOCKS + "/escritoire.png"); + //private final EntityItem dummyEntityItem = new EntityItem(null); + private final RenderItem customRenderItem; + + public RenderEscritoire() { + modelEscritoire = new ModelEscritoire(); + + customRenderItem = new RenderItem() { + @Override + public boolean shouldBob() { + return false; + } + + @Override + public boolean shouldSpreadItems() { + return false; + }; + }; + customRenderItem.setRenderManager(RenderManager.instance); + + } + + @Override + public void inventoryRender(double x, double y, double z, float f, float f1) { + render(null, ForgeDirection.EAST, x, y, z); + } + + @Override + public void renderTileEntityAt(TileEntity tileentity, double x, double y, double z, float f) { + TileEscritoire tile = (TileEscritoire)tileentity; + render(tile.getStackInSlot(TileEscritoire.SLOT_ANALYZE), tile.getOrientation(), x, y, z); + } + + private void render(ItemStack itemstack, ForgeDirection orientation, double x, double y, double z) { + float factor = (float) (1.0 / 16.0); + + GL11.glPushMatrix(); + GL11.glDisable(GL11.GL_LIGHTING); + GL11.glTranslatef((float) x + 0.5f, (float) y + 0.875f, (float) z + 0.5f); + + float[] angle = { (float) Math.PI, 0, 0 }; + + if (orientation == null) + orientation = ForgeDirection.WEST; + switch (orientation) { + case EAST: + angle[1] = (float)Math.PI / 2; + break; + case SOUTH: + break; + case NORTH: + angle[1] = (float)Math.PI; + break; + case WEST: + default: + angle[1] = -(float)Math.PI / 2; + break; + } + + Proxies.common.bindTexture(texture); + modelEscritoire.render(null, angle[0], angle[1], angle[2], 0f, 0f, factor); + + GL11.glEnable(GL11.GL_LIGHTING); + GL11.glPopMatrix(); + + /* + if(itemstack != null) { + float renderScale = 1.0f; + + GL11.glPushMatrix(); + GL11.glTranslatef((float) x, (float) y, (float) z); + GL11.glTranslatef(0.6f, 0.8f, 0.5f); + GL11.glRotatef(90.0f, 1.0F, 0.0F, 0.0F); + GL11.glScalef(renderScale, renderScale, renderScale); + + RenderItem.renderInFrame = true; + dummyEntityItem.setEntityItemStack(itemstack); + customRenderItem.doRenderItem(dummyEntityItem, 0, 0, 0, 0, 0); + RenderItem.renderInFrame = false; + GL11.glPopMatrix(); + } + */ + + } +} diff --git a/forestry_common/core/forestry/core/render/RenderMachine.java b/forestry_common/core/forestry/core/render/RenderMachine.java new file mode 100755 index 000000000..2893cb6b9 --- /dev/null +++ b/forestry_common/core/forestry/core/render/RenderMachine.java @@ -0,0 +1,228 @@ +/******************************************************************************* + * Copyright 2011-2014 by SirSengir + * + * This work is licensed under a Creative Commons Attribution-NonCommercial-NoDerivs 3.0 Unported License. + * + * To view a copy of this license, visit http://creativecommons.org/licenses/by-nc-nd/3.0/. + ******************************************************************************/ +package forestry.core.render; + +import net.minecraft.client.model.ModelBase; +import net.minecraft.client.model.ModelRenderer; +import net.minecraft.client.renderer.tileentity.TileEntitySpecialRenderer; +import net.minecraft.tileentity.TileEntity; +import net.minecraft.util.ResourceLocation; + +import net.minecraftforge.common.util.ForgeDirection; + +import org.lwjgl.opengl.GL11; + +import forestry.core.interfaces.IBlockRenderer; +import forestry.core.interfaces.IRenderableMachine; +import forestry.core.proxy.Proxies; +import forestry.core.utils.EnumTankLevel; +import forestry.core.utils.ForestryResource; + +public class RenderMachine extends TileEntitySpecialRenderer implements IBlockRenderer { + + private final ModelBase model = new ModelBase() { + }; + + private final ModelRenderer basefront; + private final ModelRenderer baseback; + private final ModelRenderer resourceTank; + private final ModelRenderer productTank; + + private static enum Textures { + BASE, + TANK_R_EMPTY, TANK_R_LOW, TANK_R_MEDIUM, TANK_R_HIGH, TANK_R_MAXIMUM, + TANK_P_EMPTY, TANK_P_LOW, TANK_P_MEDIUM, TANK_P_HIGH, TANK_P_MAXIMUM + }; + private ResourceLocation[] textures; + + public RenderMachine() { + + basefront = new ModelRenderer(model, 0, 0); + basefront.addBox(-8F, -8F, -8F, 16, 4, 16); + basefront.rotationPointX = 8; + basefront.rotationPointY = 8; + basefront.rotationPointZ = 8; + + baseback = new ModelRenderer(model, 0, 0); + baseback.addBox(-8F, 4F, -8F, 16, 4, 16); + baseback.rotationPointX = 8; + baseback.rotationPointY = 8; + baseback.rotationPointZ = 8; + + resourceTank = new ModelRenderer(model, 0, 0); + resourceTank.addBox(-6F, -8F, -6F, 12, 16, 6); + resourceTank.rotationPointX = 8; + resourceTank.rotationPointY = 8; + resourceTank.rotationPointZ = 8; + + productTank = new ModelRenderer(model, 0, 0); + productTank.addBox(-6F, -8F, 0F, 12, 16, 6); + productTank.rotationPointX = 8; + productTank.rotationPointY = 8; + productTank.rotationPointZ = 8; + + } + + public RenderMachine(String baseTexture) { + this(); + + textures = new ResourceLocation[] { + new ForestryResource(baseTexture + "base.png"), + + new ForestryResource(baseTexture + "tank_resource_empty.png"), + new ForestryResource(baseTexture + "tank_resource_low.png"), + new ForestryResource(baseTexture + "tank_resource_medium.png"), + new ForestryResource(baseTexture + "tank_resource_high.png"), + new ForestryResource(baseTexture + "tank_resource_maximum.png"), + + new ForestryResource(baseTexture + "tank_product_empty.png"), + new ForestryResource(baseTexture + "tank_product_low.png"), + new ForestryResource(baseTexture + "tank_product_medium.png"), + new ForestryResource(baseTexture + "tank_product_high.png"), + new ForestryResource(baseTexture + "tank_product_maximum.png"), + }; + + } + + @Override + public void inventoryRender(double x, double y, double z, float f, float f1) { + render(EnumTankLevel.EMPTY, EnumTankLevel.EMPTY, ForgeDirection.UP, x, y, z); + } + + @Override + public void renderTileEntityAt(TileEntity tileentity, double d, double d1, double d2, float f) { + IRenderableMachine generator = (IRenderableMachine) tileentity; + render(generator.getPrimaryLevel(), generator.getSecondaryLevel(), generator.getOrientation(), d, d1, d2); + + } + + private void render(EnumTankLevel waterLevel, EnumTankLevel melangeLevel, ForgeDirection orientation, double x, double y, double z) { + render(waterLevel.ordinal(), melangeLevel.ordinal(), orientation, x, y, z); + } + + public void render(int waterLevelInt, int melangeLevelInt, ForgeDirection orientation, double x, double y, double z) { + + EnumTankLevel waterLevel = EnumTankLevel.values()[waterLevelInt]; + EnumTankLevel melangeLevel = EnumTankLevel.values()[melangeLevelInt]; + + GL11.glPushMatrix(); + // GL11.glDisable(2896 /* GL_LIGHTING */); + GL11.glDisable(GL11.GL_LIGHTING); + + GL11.glTranslatef((float) x, (float) y, (float) z); + + float[] angle = { 0, 0, 0 }; + float[] translate = { 0, 0, 0 }; + + if (orientation == null) + orientation = ForgeDirection.WEST; + switch (orientation) { + case EAST: + // angle [2] = (float) Math.PI / 2; + angle[1] = (float) Math.PI; + angle[2] = (float) -Math.PI / 2; + translate[0] = 1; + break; + case WEST: + // 2, -PI/2 + angle[2] = (float) Math.PI / 2; + translate[0] = -1; + break; + case UP: + translate[1] = 1; + break; + case DOWN: + angle[2] = (float) Math.PI; + translate[1] = -1; + break; + case SOUTH: + angle[0] = (float) Math.PI / 2; + angle[2] = (float) Math.PI / 2; + translate[2] = 1; + break; + case NORTH: + default: + angle[0] = (float) -Math.PI / 2; + angle[2] = (float) Math.PI / 2; + translate[2] = -1; + break; + } + + basefront.rotateAngleX = angle[0]; + basefront.rotateAngleY = angle[1]; + basefront.rotateAngleZ = angle[2]; + + baseback.rotateAngleX = angle[0]; + baseback.rotateAngleY = angle[1]; + baseback.rotateAngleZ = angle[2]; + + resourceTank.rotateAngleX = angle[0]; + resourceTank.rotateAngleY = angle[1]; + resourceTank.rotateAngleZ = angle[2]; + + productTank.rotateAngleX = angle[0]; + productTank.rotateAngleY = angle[1]; + productTank.rotateAngleZ = angle[2]; + + float factor = (float) (1.0 / 16.0); + + Proxies.common.bindTexture(textures[Textures.BASE.ordinal()]); + basefront.render(factor); + + Proxies.common.bindTexture(textures[Textures.BASE.ordinal()]); + baseback.render(factor); + + ResourceLocation texture; + + switch (waterLevel) { + case LOW: + texture = textures[Textures.TANK_R_LOW.ordinal()]; + break; + case MEDIUM: + texture = textures[Textures.TANK_R_MEDIUM.ordinal()]; + break; + case HIGH: + texture = textures[Textures.TANK_R_HIGH.ordinal()]; + break; + case MAXIMUM: + texture = textures[Textures.TANK_R_MAXIMUM.ordinal()]; + break; + case EMPTY: + default: + texture = textures[Textures.TANK_R_EMPTY.ordinal()]; + break; + } + Proxies.common.bindTexture(texture); + resourceTank.render(factor); + + switch (melangeLevel) { + case LOW: + texture = textures[Textures.TANK_P_LOW.ordinal()]; + break; + case MEDIUM: + texture = textures[Textures.TANK_P_MEDIUM.ordinal()]; + break; + case HIGH: + texture = textures[Textures.TANK_P_HIGH.ordinal()]; + break; + case MAXIMUM: + texture = textures[Textures.TANK_P_MAXIMUM.ordinal()]; + break; + case EMPTY: + default: + texture = textures[Textures.TANK_P_EMPTY.ordinal()]; + break; + } + Proxies.common.bindTexture(texture); + productTank.render(factor); + + // GL11.glEnable(2896 /* GL_LIGHTING */); + GL11.glEnable(GL11.GL_LIGHTING); + GL11.glPopMatrix(); + } +} diff --git a/forestry_common/core/forestry/core/render/RenderMill.java b/forestry_common/core/forestry/core/render/RenderMill.java new file mode 100755 index 000000000..3cae846e9 --- /dev/null +++ b/forestry_common/core/forestry/core/render/RenderMill.java @@ -0,0 +1,198 @@ +/******************************************************************************* + * Copyright 2011-2014 by SirSengir + * + * This work is licensed under a Creative Commons Attribution-NonCommercial-NoDerivs 3.0 Unported License. + * + * To view a copy of this license, visit http://creativecommons.org/licenses/by-nc-nd/3.0/. + ******************************************************************************/ +package forestry.core.render; + +import net.minecraft.client.model.ModelBase; +import net.minecraft.client.model.ModelRenderer; +import net.minecraft.client.renderer.tileentity.TileEntitySpecialRenderer; +import net.minecraft.tileentity.TileEntity; +import net.minecraft.util.ResourceLocation; + +import net.minecraftforge.common.util.ForgeDirection; + +import org.lwjgl.opengl.GL11; + +import forestry.core.gadgets.Mill; +import forestry.core.interfaces.IBlockRenderer; +import forestry.core.proxy.Proxies; +import forestry.core.utils.ForestryResource; + +public class RenderMill extends TileEntitySpecialRenderer implements IBlockRenderer { + + private final ModelBase model = new ModelBase() { + }; + + private static enum Textures { PEDESTAL, EXTENSION, BLADE_1, BLADE_2, CHARGE }; + private ResourceLocation[] textures; + + private final ModelRenderer pedestal; + private final ModelRenderer column; + private final ModelRenderer extension; + private final ModelRenderer blade1; + private final ModelRenderer blade2; + + public RenderMill() { + pedestal = new ModelRenderer(model, 0, 0); + pedestal.addBox(-8F, -8F, -8F, 16, 1, 16); + pedestal.rotationPointX = 8; + pedestal.rotationPointY = 8; + pedestal.rotationPointZ = 8; + + column = new ModelRenderer(model, 0, 0); + column.addBox(-2, -7F, -2, 4, 15, 4); + column.rotationPointX = 8; + column.rotationPointY = 8; + column.rotationPointZ = 8; + + extension = new ModelRenderer(model, 0, 0); + extension.addBox(1F, 8F, 7F, 14, 2, 2); + extension.rotationPointX = 0; + extension.rotationPointY = 0; + extension.rotationPointZ = 0; + + blade1 = new ModelRenderer(model, 0, 0); + blade1.addBox(-4F, -5F, -3F, 8, 12, 1); + blade1.rotationPointX = 8; + blade1.rotationPointY = 8; + blade1.rotationPointZ = 8; + + blade2 = new ModelRenderer(model, 0, 0); + blade2.addBox(-4F, -5F, 2F, 8, 12, 1); + blade2.rotationPointX = 8; + blade2.rotationPointY = 8; + blade2.rotationPointZ = 8; + + } + + public RenderMill(String baseTexture) { + this(); + + textures = new ResourceLocation[12]; + + textures[Textures.PEDESTAL.ordinal()] = new ForestryResource(baseTexture + "pedestal.png"); + textures[Textures.EXTENSION.ordinal()] = new ForestryResource(baseTexture + "extension.png"); + textures[Textures.BLADE_1.ordinal()] = new ForestryResource(baseTexture + "blade1.png"); + textures[Textures.BLADE_2.ordinal()] = new ForestryResource(baseTexture + "blade2.png"); + + for(int i = 0; i < 8; i++) { + textures[Textures.CHARGE.ordinal() + i] = new ForestryResource(baseTexture + "column_"+ i +".png"); + } + } + + public RenderMill(String baseTexture, byte charges) { + this(baseTexture); + } + + @Override + public void inventoryRender(double x, double y, double z, float f, float f1) { + byte charge = 0; + render(0.0f, charge, ForgeDirection.WEST, x, y, z); + } + + @Override + public void renderTileEntityAt(TileEntity tileentity, double d, double d1, double d2, float f) { + Mill tile = (Mill) tileentity; + render(tile.progress, tile.charge, ForgeDirection.WEST, d, d1, d2); + } + + private void render(float progress, int charge, ForgeDirection orientation, double x, double y, double z) { + + GL11.glPushMatrix(); + GL11.glDisable(2896 /* GL_LIGHTING */); + + GL11.glTranslatef((float) x, (float) y, (float) z); + + float step; + + if (progress > 0.5) + step = 3.99F - (progress - 0.5F) * 2F * 3.99F; + else + step = progress * 2F * 3.99F; + + float[] angle = { 0, 0, 0 }; + float[] translate = { 0, 0, 0 }; + float tfactor = step / 16; + + if (orientation == null) + orientation = ForgeDirection.WEST; + switch (orientation) { + case EAST: + // angle [2] = (float) Math.PI / 2; + angle[1] = (float) Math.PI; + angle[2] = (float) -Math.PI / 2; + translate[0] = 1; + break; + case WEST: + // 2, -PI/2 + angle[2] = (float) Math.PI / 2; + translate[0] = -1; + break; + case UP: + translate[1] = 1; + break; + case DOWN: + angle[2] = (float) Math.PI; + translate[1] = -1; + break; + case SOUTH: + angle[0] = (float) Math.PI / 2; + angle[2] = (float) Math.PI / 2; + translate[2] = 1; + break; + case NORTH: + default: + angle[0] = (float) -Math.PI / 2; + angle[2] = (float) Math.PI / 2; + translate[2] = -1; + break; + } + + pedestal.rotateAngleX = angle[0]; + pedestal.rotateAngleY = angle[2]; + pedestal.rotateAngleZ = angle[1]; + + column.rotateAngleX = angle[0]; + column.rotateAngleY = angle[2]; + column.rotateAngleZ = angle[1]; + + blade1.rotateAngleX = angle[0]; + blade1.rotateAngleY = angle[2]; + blade1.rotateAngleZ = angle[1]; + + blade2.rotateAngleX = angle[0]; + blade2.rotateAngleY = angle[2]; + blade2.rotateAngleZ = angle[1]; + + float factor = (float) (1.0 / 16.0); + + Proxies.common.bindTexture(textures[Textures.PEDESTAL.ordinal()]); + pedestal.render(factor); + + Proxies.common.bindTexture(textures[Textures.CHARGE.ordinal() + charge]); + column.render(factor); + + Proxies.common.bindTexture(textures[Textures.EXTENSION.ordinal()]); + extension.render(factor); + + Proxies.common.bindTexture(textures[Textures.BLADE_1.ordinal()]); + GL11.glTranslatef(translate[0] * tfactor, translate[1] * tfactor, translate[2] * tfactor); + blade1.render(factor); + + // Reset + GL11.glTranslatef(-translate[0] * tfactor, -translate[1] * tfactor, -translate[2] * tfactor); + + Proxies.common.bindTexture(textures[Textures.BLADE_2.ordinal()]); + GL11.glTranslatef(-translate[0] * tfactor, translate[1] * tfactor, -translate[2] * tfactor); + blade2.render(factor); + + GL11.glEnable(2896 /* GL_LIGHTING */); + GL11.glPopMatrix(); + + } + +} diff --git a/forestry_common/core/forestry/core/render/SpriteSheet.java b/forestry_common/core/forestry/core/render/SpriteSheet.java new file mode 100755 index 000000000..10aa0fa57 --- /dev/null +++ b/forestry_common/core/forestry/core/render/SpriteSheet.java @@ -0,0 +1,24 @@ +/******************************************************************************* + * Copyright 2011-2014 by SirSengir + * + * This work is licensed under a Creative Commons Attribution-NonCommercial-NoDerivs 3.0 Unported License. + * + * To view a copy of this license, visit http://creativecommons.org/licenses/by-nc-nd/3.0/. + ******************************************************************************/ +package forestry.core.render; + +import net.minecraft.client.renderer.texture.TextureMap; +import net.minecraft.util.ResourceLocation; + +public enum SpriteSheet { + BLOCKS, + ITEMS; + + public ResourceLocation getLocation() { + return ordinal() == 0 ? TextureMap.locationBlocksTexture : TextureMap.locationItemsTexture; + } + + public int getSheetOrdinal() { + return ordinal(); + } +} diff --git a/forestry_common/core/forestry/core/render/TextureManager.java b/forestry_common/core/forestry/core/render/TextureManager.java new file mode 100755 index 000000000..e12a6bd13 --- /dev/null +++ b/forestry_common/core/forestry/core/render/TextureManager.java @@ -0,0 +1,103 @@ +/******************************************************************************* + * Copyright 2011-2014 by SirSengir + * + * This work is licensed under a Creative Commons Attribution-NonCommercial-NoDerivs 3.0 Unported License. + * + * To view a copy of this license, visit http://creativecommons.org/licenses/by-nc-nd/3.0/. + ******************************************************************************/ +package forestry.core.render; + +import java.util.ArrayList; +import java.util.HashMap; + +import net.minecraft.client.renderer.texture.IIconRegister; +import net.minecraft.util.IIcon; + +import cpw.mods.fml.relauncher.Side; +import cpw.mods.fml.relauncher.SideOnly; + +import forestry.api.core.ForestryAPI; +import forestry.api.core.IIconProvider; +import forestry.api.core.ITextureManager; + +@SideOnly(Side.CLIENT) +public class TextureManager implements ITextureManager { + + private static TextureManager instance; + + public static TextureManager getInstance() { + if (instance == null) { + instance = new TextureManager(); + ForestryAPI.textureManager = instance; + } + + return instance; + } + + String[] defaultIconNames = new String[] { "habitats/desert", "habitats/end", "habitats/forest", "habitats/hills", "habitats/jungle", "habitats/mushroom", + "habitats/nether", "habitats/ocean", "habitats/plains", "habitats/snow", "habitats/swamp", "habitats/taiga", "misc/access.private", + "misc/access.viewable", "misc/access.shared", "misc/empty", "misc/energy", "misc/hint", "misc/liquid", + "analyzer/anything", "analyzer/bee", "analyzer/cave", "analyzer/closed", "analyzer/drone", "analyzer/flyer", + "analyzer/item", "analyzer/nocturnal", "analyzer/princess", "analyzer/pure_breed", "analyzer/pure_cave", + "analyzer/pure_flyer", "analyzer/pure_nocturnal", "analyzer/queen", "analyzer/natural", + "particles/ember", "particles/flame", "particles/poison", "particles/snow", "particles/swarm_bee", "errors/errored", + "slots/blocked", "slots/blocked_2", "slots/liquid", "slots/container", "slots/locked", + "mail/carrier.player", "mail/carrier.trader" }; + HashMap defaultIcons = new HashMap(); + + public void initDefaultIcons(IIconRegister register) { + for (String str : defaultIconNames) + defaultIcons.put(str, TextureManager.getInstance().registerTex(register, str)); + } + + public IIcon getDefault(String ident) { + if (defaultIcons.containsKey(ident)) + return defaultIcons.get(ident); + else + return null; + } + + //public TextureMap terrainMap; + //public TextureMap itemMap; + + IIcon[] textures = new IIcon[2048]; + + ArrayList iconProvider = new ArrayList(); + + public TextureManager() { + //this.terrainMap = textureMap; + //this.itemMap = itemMap; + } + + public IIcon registerTex(IIconRegister register, String identifier) { + return register.registerIcon("forestry:" + identifier); + } + + public IIcon registerTexUID(IIconRegister register, short uid, String identifier) { + return setTexUID(uid, registerTex(register, identifier)); + } + + public IIcon setTexUID(short uid, IIcon texture) { + textures[uid] = texture; + return texture; + } + + @Override + public void registerIconProvider(IIconProvider provider) { + iconProvider.add(provider); + } + + @Override + public IIcon getIcon(short texUID) { + if (texUID < textures.length) + return textures[texUID]; + + for (IIconProvider provider : iconProvider) { + IIcon retr = provider.getIcon(texUID); + if (retr != null) + return retr; + } + + return null; + } +} diff --git a/forestry_common/core/forestry/core/render/TileRendererIndex.java b/forestry_common/core/forestry/core/render/TileRendererIndex.java new file mode 100755 index 000000000..4669bb51c --- /dev/null +++ b/forestry_common/core/forestry/core/render/TileRendererIndex.java @@ -0,0 +1,33 @@ +/******************************************************************************* + * Copyright 2011-2014 by SirSengir + * + * This work is licensed under a Creative Commons Attribution-NonCommercial-NoDerivs 3.0 Unported License. + * + * To view a copy of this license, visit http://creativecommons.org/licenses/by-nc-nd/3.0/. + ******************************************************************************/ +package forestry.core.render; + +import net.minecraft.block.Block; + +public class TileRendererIndex { + private Block block; + private int meta; + + public TileRendererIndex(Block block, int meta) { + this.block = block; + this.meta = meta; + } + + public int hashCode() { + return block.hashCode() + meta; + } + + public boolean equals(Object aobj) { + if (!(aobj instanceof TileRendererIndex)) + return false; + + TileRendererIndex index = (TileRendererIndex) aobj; + + return index.block == block && index.meta == meta; + } +} diff --git a/forestry_common/core/forestry/core/triggers/ForestryTrigger.java b/forestry_common/core/forestry/core/triggers/ForestryTrigger.java new file mode 100755 index 000000000..6b8c3df0a --- /dev/null +++ b/forestry_common/core/forestry/core/triggers/ForestryTrigger.java @@ -0,0 +1,43 @@ +/******************************************************************************* + * Copyright 2011-2014 by SirSengir + * + * This work is licensed under a Creative Commons Attribution-NonCommercial-NoDerivs 3.0 Unported License. + * + * To view a copy of this license, visit http://creativecommons.org/licenses/by-nc-nd/3.0/. + ******************************************************************************/ +package forestry.core.triggers; + +import buildcraft.api.gates.ActionManager; + +public class ForestryTrigger { + + public static Trigger lowFuel25; + public static Trigger lowFuel10; + public static Trigger lowResource25; + public static Trigger lowResource10; + public static Trigger lowSoil25; + public static Trigger lowSoil10; + public static Trigger lowGermlings25; + public static Trigger lowGermlings10; + public static Trigger missingQueen; + public static Trigger missingDrone; + public static Trigger hasWork; + + public static void initialize() { + ActionManager.registerTrigger(lowFuel25 = new TriggerLowFuel("lowFuel.25", 0.25f)); + ActionManager.registerTrigger(lowFuel10 = new TriggerLowFuel("lowFuel.10", 0.1f)); + ActionManager.registerTrigger(lowResource25 = new TriggerLowResource("lowResources.25", 0.25f)); + ActionManager.registerTrigger(lowResource10 = new TriggerLowResource("lowResources.10", 0.1f)); + + ActionManager.registerTrigger(lowSoil25 = new TriggerLowSoil("lowSoil.25", 0.25f)); + ActionManager.registerTrigger(lowSoil10 = new TriggerLowSoil("lowSoil.10", 0.1f)); + ActionManager.registerTrigger(lowGermlings25 = new TriggerLowGermlings("lowGermlings.25", 0.25f)); + ActionManager.registerTrigger(lowGermlings10 = new TriggerLowGermlings("lowGermlings.10", 0.1f)); + + ActionManager.registerTrigger(missingQueen = new TriggerMissingQueen()); + ActionManager.registerTrigger(missingDrone = new TriggerMissingDrone()); + + ActionManager.registerTrigger(hasWork = new TriggerHasWork()); + + } +} diff --git a/forestry_common/core/forestry/core/triggers/Trigger.java b/forestry_common/core/forestry/core/triggers/Trigger.java new file mode 100755 index 000000000..1a683904b --- /dev/null +++ b/forestry_common/core/forestry/core/triggers/Trigger.java @@ -0,0 +1,76 @@ +/******************************************************************************* + * Copyright 2011-2014 by SirSengir + * + * This work is licensed under a Creative Commons Attribution-NonCommercial-NoDerivs 3.0 Unported License. + * + * To view a copy of this license, visit http://creativecommons.org/licenses/by-nc-nd/3.0/. + ******************************************************************************/ +package forestry.core.triggers; + +import net.minecraft.client.renderer.texture.IIconRegister; +import net.minecraft.util.IIcon; + +import cpw.mods.fml.relauncher.Side; +import cpw.mods.fml.relauncher.SideOnly; + +import buildcraft.api.gates.ActionManager; +import buildcraft.api.gates.ITileTrigger; +import buildcraft.api.gates.ITriggerParameter; + +import forestry.core.render.TextureManager; +import forestry.core.utils.StringUtil; + +public abstract class Trigger implements ITileTrigger { + + private final String uid; + private final String unlocalized; + + public Trigger(String uid) { + this(uid, uid); + } + + public Trigger(String uid, String localization) { + this.uid = "forestry." + uid; + unlocalized = "trigger." + localization; + ActionManager.registerTrigger(this); + } + + @Override + public String getUniqueTag() { + return uid; + } + + @Override + public String getDescription() { + return StringUtil.localize(unlocalized); + } + + @Override + public boolean hasParameter() { + return false; + } + + @Override + public boolean requiresParameter() { + return false; + } + + @Override + public ITriggerParameter createParameter() { + return null; + } + @SideOnly(Side.CLIENT) + private IIcon icon; + + @Override + @SideOnly(Side.CLIENT) + public IIcon getIcon() { + return icon; + } + + @Override + @SideOnly(Side.CLIENT) + public void registerIcons(IIconRegister register) { + icon = TextureManager.getInstance().registerTex(register, "triggers/" + unlocalized.replace("trigger.", "")); + } +} diff --git a/forestry_common/core/forestry/core/triggers/TriggerHasWork.java b/forestry_common/core/forestry/core/triggers/TriggerHasWork.java new file mode 100755 index 000000000..3caef782f --- /dev/null +++ b/forestry_common/core/forestry/core/triggers/TriggerHasWork.java @@ -0,0 +1,36 @@ +/******************************************************************************* + * Copyright 2011-2014 by SirSengir + * + * This work is licensed under a Creative Commons Attribution-NonCommercial-NoDerivs 3.0 Unported License. + * + * To view a copy of this license, visit http://creativecommons.org/licenses/by-nc-nd/3.0/. + ******************************************************************************/ +package forestry.core.triggers; + +import net.minecraft.tileentity.TileEntity; + +import net.minecraftforge.common.util.ForgeDirection; + +import buildcraft.api.gates.ITriggerParameter; + +import forestry.core.gadgets.TilePowered; + +public class TriggerHasWork extends Trigger { + + public TriggerHasWork() { + super("hasWork"); + } + + /** + * Return true if the tile given in parameter activates the trigger, given + * the parameters. + */ + @Override + public boolean isTriggerActive(ForgeDirection direction, TileEntity tile, ITriggerParameter parameter) { + + if (!(tile instanceof TilePowered)) + return false; + + return ((TilePowered) tile).hasWork(); + } +} diff --git a/forestry_common/core/forestry/core/triggers/TriggerLowFuel.java b/forestry_common/core/forestry/core/triggers/TriggerLowFuel.java new file mode 100755 index 000000000..bd015c038 --- /dev/null +++ b/forestry_common/core/forestry/core/triggers/TriggerLowFuel.java @@ -0,0 +1,50 @@ +/******************************************************************************* + * Copyright 2011-2014 by SirSengir + * + * This work is licensed under a Creative Commons Attribution-NonCommercial-NoDerivs 3.0 Unported License. + * + * To view a copy of this license, visit http://creativecommons.org/licenses/by-nc-nd/3.0/. + ******************************************************************************/ +package forestry.core.triggers; + +import net.minecraft.tileentity.TileEntity; + +import net.minecraftforge.common.util.ForgeDirection; + +import buildcraft.api.gates.ITriggerParameter; + +import forestry.core.gadgets.Engine; +import forestry.core.gadgets.TilePowered; + +public class TriggerLowFuel extends Trigger { + + private float threshold = 0.25F; + + public TriggerLowFuel(String tag, float threshold) { + super(tag, "lowFuel"); + this.threshold = threshold; + } + + @Override + public String getDescription() { + return super.getDescription() + " < " + threshold * 100 + "%"; + } + + /** + * Return true if the tile given in parameter activates the trigger, given the parameters. + */ + @Override + public boolean isTriggerActive(ForgeDirection direction, TileEntity tile, ITriggerParameter parameter) { + + if (tile instanceof TilePowered) + return !((TilePowered) tile).hasFuelMin(threshold); + + if (tile instanceof Engine) { + Engine engine = (Engine) tile; + return !engine.hasFuelMin(threshold); + } + + return false; + } + +} diff --git a/forestry_common/core/forestry/core/triggers/TriggerLowGermlings.java b/forestry_common/core/forestry/core/triggers/TriggerLowGermlings.java new file mode 100755 index 000000000..25cb2594b --- /dev/null +++ b/forestry_common/core/forestry/core/triggers/TriggerLowGermlings.java @@ -0,0 +1,43 @@ +/******************************************************************************* + * Copyright 2011-2014 by SirSengir + * + * This work is licensed under a Creative Commons Attribution-NonCommercial-NoDerivs 3.0 Unported License. + * + * To view a copy of this license, visit http://creativecommons.org/licenses/by-nc-nd/3.0/. + ******************************************************************************/ +package forestry.core.triggers; + +import net.minecraft.tileentity.TileEntity; + +import net.minecraftforge.common.util.ForgeDirection; + +import buildcraft.api.gates.ITriggerParameter; + +import forestry.core.gadgets.TilePowered; + +public class TriggerLowGermlings extends Trigger { + + private float threshold = 0.25F; + + public TriggerLowGermlings(String tag, float threshold) { + super(tag, "lowGermlings"); + this.threshold = threshold; + } + + @Override + public String getDescription() { + return super.getDescription() + " < " + threshold * 100 + "%"; + } + + /** + * Return true if the tile given in parameter activates the trigger, given the parameters. + */ + @Override + public boolean isTriggerActive(ForgeDirection direction, TileEntity tile, ITriggerParameter parameter) { + if (!(tile instanceof TilePowered)) + return false; + + return !((TilePowered) tile).hasResourcesMin(threshold); + } + +} diff --git a/forestry_common/core/forestry/core/triggers/TriggerLowResource.java b/forestry_common/core/forestry/core/triggers/TriggerLowResource.java new file mode 100755 index 000000000..a719caa15 --- /dev/null +++ b/forestry_common/core/forestry/core/triggers/TriggerLowResource.java @@ -0,0 +1,43 @@ +/******************************************************************************* + * Copyright 2011-2014 by SirSengir + * + * This work is licensed under a Creative Commons Attribution-NonCommercial-NoDerivs 3.0 Unported License. + * + * To view a copy of this license, visit http://creativecommons.org/licenses/by-nc-nd/3.0/. + ******************************************************************************/ +package forestry.core.triggers; + +import net.minecraft.tileentity.TileEntity; + +import net.minecraftforge.common.util.ForgeDirection; + +import buildcraft.api.gates.ITriggerParameter; + +import forestry.core.gadgets.TilePowered; + +public class TriggerLowResource extends Trigger { + + private float threshold = 0.25F; + + public TriggerLowResource(String tag, float threshold) { + super(tag, "lowResources"); + this.threshold = threshold; + } + + @Override + public String getDescription() { + return super.getDescription() + " < " + threshold * 100 + "%"; + } + + /** + * Return true if the tile given in parameter activates the trigger, given the parameters. + */ + @Override + public boolean isTriggerActive(ForgeDirection direction, TileEntity tile, ITriggerParameter parameter) { + if (!(tile instanceof TilePowered)) + return false; + + return !((TilePowered) tile).hasResourcesMin(threshold); + } + +} diff --git a/forestry_common/core/forestry/core/triggers/TriggerLowSoil.java b/forestry_common/core/forestry/core/triggers/TriggerLowSoil.java new file mode 100755 index 000000000..b78999cd1 --- /dev/null +++ b/forestry_common/core/forestry/core/triggers/TriggerLowSoil.java @@ -0,0 +1,43 @@ +/******************************************************************************* + * Copyright 2011-2014 by SirSengir + * + * This work is licensed under a Creative Commons Attribution-NonCommercial-NoDerivs 3.0 Unported License. + * + * To view a copy of this license, visit http://creativecommons.org/licenses/by-nc-nd/3.0/. + ******************************************************************************/ +package forestry.core.triggers; + +import net.minecraft.tileentity.TileEntity; + +import net.minecraftforge.common.util.ForgeDirection; + +import buildcraft.api.gates.ITriggerParameter; + +import forestry.core.gadgets.TilePowered; + +public class TriggerLowSoil extends Trigger { + + private float threshold = 0.25F; + + public TriggerLowSoil(String tag, float threshold) { + super(tag, "lowSoil"); + this.threshold = threshold; + } + + @Override + public String getDescription() { + return super.getDescription() + " < " + threshold * 100 + "%"; + } + + /** + * Return true if the tile given in parameter activates the trigger, given the parameters. + */ + @Override + public boolean isTriggerActive(ForgeDirection direction, TileEntity tile, ITriggerParameter parameter) { + if (!(tile instanceof TilePowered)) + return false; + + return !((TilePowered) tile).hasFuelMin(threshold); + } + +} diff --git a/forestry_common/core/forestry/core/triggers/TriggerMissingDrone.java b/forestry_common/core/forestry/core/triggers/TriggerMissingDrone.java new file mode 100755 index 000000000..755f7112a --- /dev/null +++ b/forestry_common/core/forestry/core/triggers/TriggerMissingDrone.java @@ -0,0 +1,38 @@ +/******************************************************************************* + * Copyright 2011-2014 by SirSengir + * + * This work is licensed under a Creative Commons Attribution-NonCommercial-NoDerivs 3.0 Unported License. + * + * To view a copy of this license, visit http://creativecommons.org/licenses/by-nc-nd/3.0/. + ******************************************************************************/ +package forestry.core.triggers; + +import net.minecraft.tileentity.TileEntity; + +import net.minecraftforge.common.util.ForgeDirection; + +import buildcraft.api.gates.ITriggerParameter; + +import forestry.core.EnumErrorCode; +import forestry.core.interfaces.IErrorSource; + +public class TriggerMissingDrone extends Trigger { + + public TriggerMissingDrone() { + super("missingDrone"); + } + + /** + * Return true if the tile given in parameter activates the trigger, given the parameters. + */ + @Override + public boolean isTriggerActive(ForgeDirection direction, TileEntity tile, ITriggerParameter parameter) { + + if (!(tile instanceof IErrorSource)) + return false; + + return ((IErrorSource) tile).getErrorState() == EnumErrorCode.NODRONE; + + } + +} diff --git a/forestry_common/core/forestry/core/triggers/TriggerMissingQueen.java b/forestry_common/core/forestry/core/triggers/TriggerMissingQueen.java new file mode 100755 index 000000000..411c6e402 --- /dev/null +++ b/forestry_common/core/forestry/core/triggers/TriggerMissingQueen.java @@ -0,0 +1,36 @@ +/******************************************************************************* + * Copyright 2011-2014 by SirSengir + * + * This work is licensed under a Creative Commons Attribution-NonCommercial-NoDerivs 3.0 Unported License. + * + * To view a copy of this license, visit http://creativecommons.org/licenses/by-nc-nd/3.0/. + ******************************************************************************/ +package forestry.core.triggers; + +import net.minecraft.tileentity.TileEntity; + +import net.minecraftforge.common.util.ForgeDirection; + +import buildcraft.api.gates.ITriggerParameter; + +import forestry.core.EnumErrorCode; +import forestry.core.interfaces.IErrorSource; + +public class TriggerMissingQueen extends Trigger { + + public TriggerMissingQueen() { + super("missingQueen"); + } + + /** + * Return true if the tile given in parameter activates the trigger, given the parameters. + */ + @Override + public boolean isTriggerActive(ForgeDirection direction, TileEntity tile, ITriggerParameter parameter) { + + if (!(tile instanceof IErrorSource)) + return false; + + return ((IErrorSource) tile).getErrorState() == EnumErrorCode.NOQUEEN; + } +} diff --git a/forestry_common/core/forestry/core/utils/BlockUtil.java b/forestry_common/core/forestry/core/utils/BlockUtil.java new file mode 100755 index 000000000..0ccc82e0a --- /dev/null +++ b/forestry_common/core/forestry/core/utils/BlockUtil.java @@ -0,0 +1,189 @@ +/******************************************************************************* + * Copyright 2011-2014 by SirSengir + * + * This work is licensed under a Creative Commons Attribution-NonCommercial-NoDerivs 3.0 Unported License. + * + * To view a copy of this license, visit http://creativecommons.org/licenses/by-nc-nd/3.0/. + ******************************************************************************/ +package forestry.core.utils; + +import java.util.ArrayList; +import java.util.Arrays; +import java.util.LinkedList; + +import net.minecraft.block.Block; +import net.minecraft.block.BlockCocoa; +import net.minecraft.block.BlockLog; +import net.minecraft.init.Blocks; +import net.minecraft.inventory.IInventory; +import net.minecraft.item.ItemStack; +import net.minecraft.tileentity.TileEntity; +import net.minecraft.tileentity.TileEntityHopper; +import net.minecraft.util.Direction; +import net.minecraft.world.World; + +import net.minecraftforge.common.util.ForgeDirection; + +import buildcraft.api.core.Position; +import buildcraft.api.power.IPowerReceptor; +import buildcraft.api.transport.IPipeConnection; +import buildcraft.api.transport.IPipeConnection.ConnectOverride; +import buildcraft.api.transport.IPipeTile; +import buildcraft.api.transport.IPipeTile.PipeType; + +import forestry.core.config.Defaults; + +public class BlockUtil { + + public static ArrayList getBlockItemStack(World world, Vect posBlock) { + Block block = world.getBlock(posBlock.x, posBlock.y, posBlock.z); + int meta = world.getBlockMetadata(posBlock.x, posBlock.y, posBlock.z); + + return block.getDrops(world, posBlock.x, posBlock.y, posBlock.z, meta, 0); + + } + + /** + * Searches for inventories adjacent to block, excludes IPowerReceptor + * + * @return + */ + public static IInventory[] getAdjacentInventories(World world, Vect blockPos, ForgeDirection from) { + ArrayList inventories = new ArrayList(); + + for (ForgeDirection dir : ForgeDirection.VALID_DIRECTIONS) { + if (from != ForgeDirection.UNKNOWN && from != dir.getOpposite()) + continue; + + TileEntity entity = world.getTileEntity(blockPos.x + dir.offsetX, blockPos.y + dir.offsetY, blockPos.z + dir.offsetZ); + if (entity != null) + if (entity instanceof IInventory) + if (!(entity instanceof TileEntityHopper)) + if (!(entity instanceof IPowerReceptor)) + inventories.add((IInventory) entity); + } + + return inventories.toArray(new IInventory[inventories.size()]); + } + + /** + * Returns a list of adjacent pipes. + * + * @param world + * @param blockPos + * @return + */ + public static ForgeDirection[] getPipeDirections(World world, Vect blockPos, ForgeDirection from) { + LinkedList possiblePipes = new LinkedList(); + + for (ForgeDirection dir : ForgeDirection.VALID_DIRECTIONS) { + if (from != ForgeDirection.UNKNOWN && from != dir.getOpposite()) + continue; + + Position posPipe = new Position(blockPos.x, blockPos.y, blockPos.z, dir); + posPipe.moveForwards(1.0); + + TileEntity pipeEntry = world.getTileEntity((int) posPipe.x, (int) posPipe.y, (int) posPipe.z); + + if (pipeEntry instanceof IPipeTile) { + IPipeTile pipe = (IPipeTile)pipeEntry; + + if (from != ForgeDirection.UNKNOWN && pipeEntry instanceof IPipeConnection) { + if (((IPipeConnection) pipeEntry).overridePipeConnection(PipeType.ITEM, from) != ConnectOverride.DISCONNECT) + possiblePipes.add(dir); + } else if(pipe.getPipeType() == PipeType.ITEM && pipe.isPipeConnected(dir.getOpposite())) + possiblePipes.add(dir); + } + } + + return possiblePipes.toArray(new ForgeDirection[0]); + + } + + public static ArrayList filterPipeDirections(ForgeDirection[] all, ForgeDirection[] exclude) { + ArrayList filtered = new ArrayList(); + ArrayList excludeList = new ArrayList(Arrays.asList(exclude)); + + for (int i = 0; i < all.length; i++) + if (!excludeList.contains(all[i])) + filtered.add(all[i]); + + return filtered; + + } + + public static boolean putFromStackIntoPipe(TileEntity tile, ArrayList pipes, ItemStack stack) { + + if (stack == null) + return false; + if (stack.stackSize <= 0) + return false; + if (pipes.size() <= 0) + return false; + + int choice = tile.getWorldObj().rand.nextInt(pipes.size()); + Position itemPos = new Position(tile.xCoord, tile.yCoord, tile.zCoord, pipes.get(choice)); + + itemPos.x += 0.5; + itemPos.y += 0.25; + itemPos.z += 0.5; + itemPos.moveForwards(0.5); + + Position pipePos = new Position(tile.xCoord, tile.yCoord, tile.zCoord, pipes.get(choice)); + pipePos.moveForwards(1.0); + + IPipeTile pipe = (IPipeTile) tile.getWorldObj().getTileEntity((int) pipePos.x, (int) pipePos.y, (int) pipePos.z); + + ItemStack payload = stack.splitStack(1); + if(pipe.injectItem(payload, true, itemPos.orientation.getOpposite()) > 0) + return true; + else + pipes.remove(choice); + + return false; + } + + public static boolean isPoweredTile(ForgeDirection side, TileEntity tile) { + if (tile == null) + return false; + + if (!(tile instanceof IPowerReceptor)) + return false; + + IPowerReceptor receptor = (IPowerReceptor) tile; + return receptor.getPowerReceiver(side) != null; + } + + public static boolean tryPlantPot(World world, int x, int y, int z, Block block) { + + int direction = getDirectionalMetadata(world, x, y, z); + if (direction < 0) + return false; + + world.setBlock(x, y, z, block, direction, Defaults.FLAG_BLOCK_SYNCH); + return true; + } + + public static int getDirectionalMetadata(World world, int x, int y, int z) { + for (int i = 0; i < 4; i++) { + if (!isValidPot(world, x, y, z, i)) + continue; + return i; + } + return -1; + } + + public static boolean isValidPot(World world, int x, int y, int z, int notchDirection) { + x += Direction.offsetX[notchDirection]; + z += Direction.offsetZ[notchDirection]; + Block block = world.getBlock(x, y, z); + if (block == Blocks.log) + return BlockLog.func_150165_c(world.getBlockMetadata(x, y, z)) == 3; + else + return block.isWood(world, x, y, z); + } + + public static int getMaturityPod(int metadata) { + return BlockCocoa.func_149987_c(metadata); + } +} diff --git a/forestry_common/core/forestry/core/utils/CommandMC.java b/forestry_common/core/forestry/core/utils/CommandMC.java new file mode 100755 index 000000000..b61e915a0 --- /dev/null +++ b/forestry_common/core/forestry/core/utils/CommandMC.java @@ -0,0 +1,60 @@ +/******************************************************************************* + * Copyright 2011-2014 by SirSengir + * + * This work is licensed under a Creative Commons Attribution-NonCommercial-NoDerivs 3.0 Unported License. + * + * To view a copy of this license, visit http://creativecommons.org/licenses/by-nc-nd/3.0/. + ******************************************************************************/ +package forestry.core.utils; + +import net.minecraft.command.CommandBase; +import net.minecraft.command.ICommandSender; +import net.minecraft.command.PlayerNotFoundException; +import net.minecraft.command.WrongUsageException; +import net.minecraft.entity.player.EntityPlayer; +import net.minecraft.entity.player.EntityPlayerMP; +import net.minecraft.server.MinecraftServer; +import net.minecraft.util.ChatComponentText; +import net.minecraft.world.World; + +public abstract class CommandMC extends CommandBase { + + protected World getWorld(ICommandSender sender, String[] arguments) { + + // Handle passed in world argument + if (arguments.length > 2) { + int dim = 0; + try { + dim = Integer.parseInt(arguments[1]); + } catch (Exception ex) { + throw new WrongUsageException("/" + getCommandName() + " set [] "); + } + + return MinecraftServer.getServer().worldServerForDimension(dim); + } + + if (sender instanceof EntityPlayer) { + EntityPlayer player = (EntityPlayer) sender; + return player.worldObj; + } else + return MinecraftServer.getServer().worldServerForDimension(0); + + } + + protected EntityPlayer getPlayerFromName(String name) { + EntityPlayerMP player = MinecraftServer.getServer().getConfigurationManager().getPlayerForUsername(name); + + if (player == null) + throw new PlayerNotFoundException(); + else + return player; + } + + protected String[] getPlayers() { + return MinecraftServer.getServer().getAllUsernames(); + } + + protected void sendChatMessage(ICommandSender sender, String message) { + sender.addChatMessage(new ChatComponentText(message)); + } +} diff --git a/forestry_common/core/forestry/core/utils/DamageSourceForestry.java b/forestry_common/core/forestry/core/utils/DamageSourceForestry.java new file mode 100755 index 000000000..d717922f0 --- /dev/null +++ b/forestry_common/core/forestry/core/utils/DamageSourceForestry.java @@ -0,0 +1,35 @@ +/******************************************************************************* + * Copyright 2011-2014 by SirSengir + * + * This work is licensed under a Creative Commons Attribution-NonCommercial-NoDerivs 3.0 Unported License. + * + * To view a copy of this license, visit http://creativecommons.org/licenses/by-nc-nd/3.0/. + ******************************************************************************/ +package forestry.core.utils; + +import net.minecraft.entity.EntityLivingBase; +import net.minecraft.util.ChatComponentTranslation; +import net.minecraft.util.DamageSource; +import net.minecraft.util.IChatComponent; + +public class DamageSourceForestry extends DamageSource { + + public DamageSourceForestry(String ident) { + super(ident); + setDamageBypassesArmor(); + } + + @Override + public IChatComponent func_151519_b(EntityLivingBase living) { + EntityLivingBase other = living.func_94060_bK(); + String ssp = "death." + this.damageType; + String smp = ssp + ".player"; + + if (other != null) { + return new ChatComponentTranslation(smp, living.func_145748_c_(), other.func_145748_c_()); + } else { + return new ChatComponentTranslation(ssp, living.func_145748_c_()); + } + } + +} diff --git a/forestry_common/core/forestry/core/utils/DelayTimer.java b/forestry_common/core/forestry/core/utils/DelayTimer.java new file mode 100755 index 000000000..f37ac8466 --- /dev/null +++ b/forestry_common/core/forestry/core/utils/DelayTimer.java @@ -0,0 +1,27 @@ +/******************************************************************************* + * Copyright 2011-2014 by SirSengir + * + * This work is licensed under a Creative Commons Attribution-NonCommercial-NoDerivs 3.0 Unported License. + * + * To view a copy of this license, visit http://creativecommons.org/licenses/by-nc-nd/3.0/. + ******************************************************************************/ +package forestry.core.utils; + +import net.minecraft.world.World; + +public class DelayTimer { + private long markedTime; + + public boolean delayPassed(World world, long delay) { + long currentTime = world.getTotalWorldTime(); + + if (currentTime < markedTime) { + markedTime = currentTime; + return false; + } else if (markedTime + delay <= currentTime) { + markedTime = currentTime; + return true; + } else + return false; + } +} diff --git a/forestry_common/core/forestry/core/utils/EnumAccess.java b/forestry_common/core/forestry/core/utils/EnumAccess.java new file mode 100755 index 000000000..094deaf08 --- /dev/null +++ b/forestry_common/core/forestry/core/utils/EnumAccess.java @@ -0,0 +1,31 @@ +/******************************************************************************* + * Copyright 2011-2014 by SirSengir + * + * This work is licensed under a Creative Commons Attribution-NonCommercial-NoDerivs 3.0 Unported License. + * + * To view a copy of this license, visit http://creativecommons.org/licenses/by-nc-nd/3.0/. + ******************************************************************************/ +package forestry.core.utils; + +import net.minecraft.util.IIcon; + +import cpw.mods.fml.relauncher.Side; +import cpw.mods.fml.relauncher.SideOnly; + +public enum EnumAccess { + SHARED("gui.rule.shared"), VIEWABLE("gui.rule.restricted"), PRIVATE("gui.rule.private"); + + private final String name; + + @SideOnly(Side.CLIENT) + private IIcon icon; + + private EnumAccess(String name) { + this.name = name; + } + + public String getName() { + return this.name; + } + +} diff --git a/forestry_common/core/forestry/core/utils/EnumTankLevel.java b/forestry_common/core/forestry/core/utils/EnumTankLevel.java new file mode 100755 index 000000000..2e3fcf3a4 --- /dev/null +++ b/forestry_common/core/forestry/core/utils/EnumTankLevel.java @@ -0,0 +1,21 @@ +/******************************************************************************* + * Copyright 2011-2014 by SirSengir + * + * This work is licensed under a Creative Commons Attribution-NonCommercial-NoDerivs 3.0 Unported License. + * + * To view a copy of this license, visit http://creativecommons.org/licenses/by-nc-nd/3.0/. + ******************************************************************************/ +package forestry.core.utils; + +public enum EnumTankLevel { + + EMPTY, + + LOW, + + MEDIUM, + + HIGH, + + MAXIMUM +} diff --git a/forestry_common/core/forestry/core/utils/FluidMap.java b/forestry_common/core/forestry/core/utils/FluidMap.java new file mode 100755 index 000000000..9dba21329 --- /dev/null +++ b/forestry_common/core/forestry/core/utils/FluidMap.java @@ -0,0 +1,43 @@ +/******************************************************************************* + * Copyright 2011-2014 by SirSengir + * + * This work is licensed under a Creative Commons Attribution-NonCommercial-NoDerivs 3.0 Unported License. + * + * To view a copy of this license, visit http://creativecommons.org/licenses/by-nc-nd/3.0/. + ******************************************************************************/ +package forestry.core.utils; + +import net.minecraftforge.fluids.Fluid; +import net.minecraftforge.fluids.FluidRegistry; +import net.minecraftforge.fluids.FluidStack; + +public class FluidMap extends StackMap { + private static final long serialVersionUID = 15891293315299994L; + + @Override + protected boolean areEqual(Fluid a, Object b) { + if (b instanceof FluidStack) + return ((FluidStack) b).getFluid() == a; + if (b instanceof Fluid) + return ((Fluid) b) == a; + if (b instanceof String) + return ((String) b).equals(a.getName()); + return false; + } + + @Override + protected boolean isValidKey(Object key) { + return key instanceof FluidStack || key instanceof Fluid || key instanceof String; + } + + @Override + protected Fluid getStack(Object key) { + if (key instanceof FluidStack) + return ((FluidStack) key).getFluid(); + if (key instanceof Fluid) + return (Fluid) key; + if (key instanceof String) + return FluidRegistry.getFluid((String) key); + return null; + } +} diff --git a/forestry_common/core/forestry/core/utils/FluidStackMap.java b/forestry_common/core/forestry/core/utils/FluidStackMap.java new file mode 100755 index 000000000..57f4cb619 --- /dev/null +++ b/forestry_common/core/forestry/core/utils/FluidStackMap.java @@ -0,0 +1,44 @@ +/******************************************************************************* + * Copyright 2011-2014 by SirSengir + * + * This work is licensed under a Creative Commons Attribution-NonCommercial-NoDerivs 3.0 Unported License. + * + * To view a copy of this license, visit http://creativecommons.org/licenses/by-nc-nd/3.0/. + ******************************************************************************/ +package forestry.core.utils; + +import net.minecraftforge.fluids.Fluid; +import net.minecraftforge.fluids.FluidStack; + +public class FluidStackMap extends StackMap { + private static final long serialVersionUID = -3314134471346370713L; + + @Override + protected boolean areEqual(FluidStack a, Object b) { + + if(b instanceof FluidStack) + return a.isFluidEqual((FluidStack) b); + if(b instanceof Fluid) { + return ((Fluid)b).getID() == a.getFluid().getID(); + } if(b instanceof String) + return ((String)b).equals(a.getFluid().getName()); + return false; + } + + @Override + protected boolean isValidKey(Object key) { + return key instanceof FluidStack || key instanceof Fluid || key instanceof String; + } + + @Override + protected FluidStack getStack(Object key) { + if (key instanceof FluidStack) + return (FluidStack) key; + if (key instanceof Fluid) + return LiquidHelper.getLiquid(((Fluid) key).getName(), 1); + if (key instanceof String) + return LiquidHelper.getLiquid((String) key, 1); + return null; + } + +} diff --git a/forestry_common/core/forestry/core/utils/Fluids.java b/forestry_common/core/forestry/core/utils/Fluids.java new file mode 100755 index 000000000..a1a2d8ac9 --- /dev/null +++ b/forestry_common/core/forestry/core/utils/Fluids.java @@ -0,0 +1,55 @@ +/******************************************************************************* + * Copyright 2011-2014 by SirSengir + * + * This work is licensed under a Creative Commons Attribution-NonCommercial-NoDerivs 3.0 Unported License. + * + * To view a copy of this license, visit http://creativecommons.org/licenses/by-nc-nd/3.0/. + ******************************************************************************/ +package forestry.core.utils; + +import java.util.Locale; + +import net.minecraft.item.ItemStack; + +import net.minecraftforge.fluids.Fluid; +import net.minecraftforge.fluids.FluidRegistry; +import net.minecraftforge.fluids.FluidStack; + +/** + * + * @author CovertJaguar + */ +public enum Fluids { + + WATER, LAVA, FUEL, BIOFUEL, CREOSOTE, STEAM; + + public String getTag() { + return name().toLowerCase(Locale.ENGLISH); + } + + public Fluid get() { + return FluidRegistry.getFluid(getTag()); + } + + public FluidStack get(int qty) { + return FluidRegistry.getFluidStack(getTag(), qty); + } + + public boolean is(Fluid fluid) { + return get() == fluid; + } + + public boolean is(FluidStack fluidStack) { + return fluidStack != null && get() == fluidStack.getFluid(); + } + + public boolean isContained(ItemStack containerStack) { + return containerStack != null && LiquidHelper.containsFluid(containerStack, Fluids.WATER.get()); + } + + public static boolean areEqual(Fluid fluid, FluidStack fluidStack){ + if(fluidStack != null && fluid == fluidStack.getFluid()) + return true; + return fluid == null && fluidStack == null; + } +} diff --git a/forestry_common/core/forestry/core/utils/FontColour.java b/forestry_common/core/forestry/core/utils/FontColour.java new file mode 100755 index 000000000..56f844765 --- /dev/null +++ b/forestry_common/core/forestry/core/utils/FontColour.java @@ -0,0 +1,47 @@ +/******************************************************************************* + * Copyright 2011-2014 by SirSengir + * + * This work is licensed under a Creative Commons Attribution-NonCommercial-NoDerivs 3.0 Unported License. + * + * To view a copy of this license, visit http://creativecommons.org/licenses/by-nc-nd/3.0/. + ******************************************************************************/ +package forestry.core.utils; + +import java.io.InputStream; +import java.util.Properties; + +import net.minecraft.client.resources.IResourceManager; + +public class FontColour { + + //private static final ResourceLocation colourDefinitions = new ForestryResource("/config/forestry/colour.properties"); + + private final Properties defaultMappings = new Properties(); + private final Properties mappings = new Properties(); + + public FontColour(IResourceManager texturepack) { + load(texturepack); + } + + public synchronized int get(String key) { + return Integer.parseInt(mappings.getProperty(key, defaultMappings.getProperty(key, "d67fff")), 16); + } + + public void load(IResourceManager texturepack) { + try { + //InputStream fontStream = texturepack.func_110536_a(colourDefinitions).func_110527_b(); + InputStream defaultFontStream = FontColour.class.getResourceAsStream("/config/forestry/colour.properties"); + //mappings.load((fontStream == null) ? defaultFontStream : fontStream); + mappings.load(defaultFontStream); + defaultMappings.load(defaultFontStream); + + //if (fontStream != null) + // fontStream.close(); + defaultFontStream.close(); + } catch (Exception e) { + e.printStackTrace(); + } + + } + +} diff --git a/forestry_common/core/forestry/core/utils/ForestryModEnvWarningCallable.java b/forestry_common/core/forestry/core/utils/ForestryModEnvWarningCallable.java new file mode 100755 index 000000000..626d50eca --- /dev/null +++ b/forestry_common/core/forestry/core/utils/ForestryModEnvWarningCallable.java @@ -0,0 +1,66 @@ +/******************************************************************************* + * Copyright 2011-2014 by SirSengir + * + * This work is licensed under a Creative Commons Attribution-NonCommercial-NoDerivs 3.0 Unported License. + * + * To view a copy of this license, visit http://creativecommons.org/licenses/by-nc-nd/3.0/. + ******************************************************************************/ +package forestry.core.utils; + +import java.util.ArrayList; +import java.util.List; + +import cpw.mods.fml.client.FMLClientHandler; +import cpw.mods.fml.common.FMLCommonHandler; +import cpw.mods.fml.common.ICrashCallable; +import cpw.mods.fml.common.Loader; +import cpw.mods.fml.relauncher.Side; + +import forestry.core.config.Defaults; + +public class ForestryModEnvWarningCallable implements ICrashCallable { + + private final List modIDs; + + public ForestryModEnvWarningCallable() { + this.modIDs = new ArrayList(); + + if (FMLCommonHandler.instance().getSide() == Side.CLIENT && FMLClientHandler.instance().hasOptifine()) { + modIDs.add("Optifine"); + } + + if (Loader.isModLoaded("gregtech_addon")) { + modIDs.add("GregTech"); + } + + try { + @SuppressWarnings("unused") + Class c = Class.forName("org.bukkit.Bukkit"); + modIDs.add("Bukkit, MCPC+, or other Bukkit replacement"); + } + catch (Throwable t) {} // No need to do anything. + + // Add other bad mods here. + + if (modIDs.size() > 0) { + FMLCommonHandler.instance().registerCrashCallable(this); + } + } + + @Override + public String call() throws Exception { + String message = "[" + Defaults.MOD + "] Warning: You have mods that change the behavior of Minecraft, ForgeModLoader, and/or Minecraft Forge to your client: \r\n"; + message = message + modIDs.get(0); + for (int i = 1; i < modIDs.size(); ++i) { + message = message + ", " + modIDs.get(i); + } + message = message + "\r\nThese may have caused this error, and may not be supported. Try reproducing the crash WITHOUT these mods, and report it then."; + return message; + } + + @Override + public String getLabel() { + return Defaults.MOD + " "; + } + +} diff --git a/forestry_common/core/forestry/core/utils/ForestryResource.java b/forestry_common/core/forestry/core/utils/ForestryResource.java new file mode 100755 index 000000000..e17864b1b --- /dev/null +++ b/forestry_common/core/forestry/core/utils/ForestryResource.java @@ -0,0 +1,20 @@ +/******************************************************************************* + * Copyright 2011-2014 by SirSengir + * + * This work is licensed under a Creative Commons Attribution-NonCommercial-NoDerivs 3.0 Unported License. + * + * To view a copy of this license, visit http://creativecommons.org/licenses/by-nc-nd/3.0/. + ******************************************************************************/ +package forestry.core.utils; + +import net.minecraft.util.ResourceLocation; + +import forestry.core.config.Defaults; + +public class ForestryResource extends ResourceLocation { + + public ForestryResource(String path) { + super(Defaults.ID, path); + } + +} diff --git a/forestry_common/core/forestry/core/utils/ForestryTank.java b/forestry_common/core/forestry/core/utils/ForestryTank.java new file mode 100755 index 000000000..378a1739d --- /dev/null +++ b/forestry_common/core/forestry/core/utils/ForestryTank.java @@ -0,0 +1,83 @@ +/******************************************************************************* + * Copyright 2011-2014 by SirSengir + * + * This work is licensed under a Creative Commons Attribution-NonCommercial-NoDerivs 3.0 Unported License. + * + * To view a copy of this license, visit http://creativecommons.org/licenses/by-nc-nd/3.0/. + ******************************************************************************/ +package forestry.core.utils; + +import java.util.Locale; + +import net.minecraft.item.EnumRarity; + +import net.minecraftforge.fluids.Fluid; +import net.minecraftforge.fluids.FluidStack; +import net.minecraftforge.fluids.FluidTank; +import net.minecraftforge.fluids.FluidTankInfo; + +import forestry.core.config.Config; +import forestry.core.gui.tooltips.ToolTip; +import forestry.core.gui.tooltips.ToolTipLine; + +public class ForestryTank extends FluidTank { + + public static final ForestryTank FAKETANK = new ForestryTank(0); + public static final ForestryTank[] FAKETANK_ARRAY = new ForestryTank[] { FAKETANK }; + public static final FluidTankInfo DUMMY_TANK_INFO = new FluidTankInfo(FAKETANK); + public static final FluidTankInfo[] DUMMY_TANKINFO_ARRAY = new FluidTankInfo[] { DUMMY_TANK_INFO }; + + public ForestryTank(FluidStack stack, int capacity) { + super(stack, capacity); + } + + public ForestryTank(int capacity) { + super(capacity); + } + + public ForestryTank(Fluid fluid, int amount, int capacity) { + super(fluid, amount, capacity); + } + + public boolean isEmpty() { + return getFluid() == null || getFluid().amount <= 0; + } + + public boolean isFull() { + return getFluid() != null && getFluid().amount == getCapacity(); + } + + public Fluid getFluidType() { + return getFluid() != null ? getFluid().getFluid() : null; + } + + @Override + public String toString() { + return String.format("Tank: %s, %d/%d", fluid != null && fluid.getFluid() != null ? fluid.getFluid().getName() : "Empty", getFluidAmount(), getCapacity()); + } + + public ToolTip getToolTip() { + return toolTip; + } + protected final ToolTip toolTip = new ToolTip() { + @Override + public void refresh() { + toolTip.clear(); + int amount = 0; + if (getFluid() != null && getFluid().amount > 0 && getFluid().getFluid() != null) { + Fluid fluidType = getFluidType(); + EnumRarity rarity = fluidType.getRarity(); + if (rarity == null) + rarity = EnumRarity.common; + ToolTipLine fluidName = new ToolTipLine(fluidType.getLocalizedName(), rarity.rarityColor); + fluidName.setSpacing(2); + toolTip.add(fluidName); + amount = getFluid().amount; + } else { + toolTip.add(new ToolTipLine(StringUtil.localize("gui.empty"))); + } + if (Config.tooltipLiquidAmount) + toolTip.add(new ToolTipLine(String.format(Locale.ENGLISH, "%,d / %,d", amount, getCapacity()))); + } + }; +} diff --git a/forestry_common/core/forestry/core/utils/IDAllocator.java b/forestry_common/core/forestry/core/utils/IDAllocator.java new file mode 100755 index 000000000..8220e1b20 --- /dev/null +++ b/forestry_common/core/forestry/core/utils/IDAllocator.java @@ -0,0 +1,88 @@ +/******************************************************************************* + * Copyright 2011-2014 by SirSengir + * + * This work is licensed under a Creative Commons Attribution-NonCommercial-NoDerivs 3.0 Unported License. + * + * To view a copy of this license, visit http://creativecommons.org/licenses/by-nc-nd/3.0/. + ******************************************************************************/ +package forestry.core.utils; + +import java.util.HashMap; +import java.util.Iterator; +import java.util.Map.Entry; + +import net.minecraft.nbt.NBTTagCompound; +import net.minecraft.nbt.NBTTagList; +import net.minecraft.world.World; +import net.minecraft.world.WorldSavedData; + +public class IDAllocator extends WorldSavedData { + + public static String SAVE_NAME = "IDAlloc"; + + public static IDAllocator cachedIDAllocator; + + private final int maxId = 2048; + + public static IDAllocator getIDAllocator(World world, String type) { + if (cachedIDAllocator != null) + return cachedIDAllocator; + + IDAllocator allocator = (IDAllocator) world.loadItemData(IDAllocator.class, SAVE_NAME + "." + type); + if (allocator == null) { + allocator = new IDAllocator(SAVE_NAME + "." + type); + world.setItemData(SAVE_NAME + type, allocator); + } + + cachedIDAllocator = allocator; + return allocator; + } + + public IDAllocator(String par1Str) { + super(par1Str); + } + + public HashMap idMap = new HashMap(); + + public int getId(String uid) { + if (idMap.containsKey(uid)) + return idMap.get(uid); + + for (int i = 0; i < maxId; i++) + if (!idMap.containsValue(i)) { + idMap.put(uid, i); + this.markDirty(); + return i; + } + + throw new RuntimeException("No ids left for the type: " + uid); + } + + @Override + public void readFromNBT(NBTTagCompound nbttagcompound) { + + NBTTagList nbttaglist = nbttagcompound.getTagList("IdMap", 10); + for (int i = 0; i < nbttaglist.tagCount(); i++) { + NBTTagCompound subcompound = nbttaglist.getCompoundTagAt(i); + idMap.put(subcompound.getString("UID"), subcompound.getInteger("Id")); + } + + } + + @Override + public void writeToNBT(NBTTagCompound nbttagcompound) { + + NBTTagList nbttaglist = new NBTTagList(); + Iterator> it = idMap.entrySet().iterator(); + while (it.hasNext()) { + Entry entry = it.next(); + NBTTagCompound subcompound = new NBTTagCompound(); + subcompound.setString("UID", entry.getKey()); + subcompound.setInteger("Id", entry.getValue()); + nbttaglist.appendTag(subcompound); + } + nbttagcompound.setTag("IdMap", nbttaglist); + + } + +} diff --git a/forestry_common/core/forestry/core/utils/InventoryAdapter.java b/forestry_common/core/forestry/core/utils/InventoryAdapter.java new file mode 100755 index 000000000..44be03633 --- /dev/null +++ b/forestry_common/core/forestry/core/utils/InventoryAdapter.java @@ -0,0 +1,391 @@ +/******************************************************************************* + * Copyright 2011-2014 by SirSengir + * + * This work is licensed under a Creative Commons Attribution-NonCommercial-NoDerivs 3.0 Unported License. + * + * To view a copy of this license, visit http://creativecommons.org/licenses/by-nc-nd/3.0/. + ******************************************************************************/ +package forestry.core.utils; + +import net.minecraft.entity.player.EntityPlayer; +import net.minecraft.init.Blocks; +import net.minecraft.inventory.IInventory; +import net.minecraft.item.ItemStack; +import net.minecraft.nbt.NBTTagCompound; +import net.minecraft.nbt.NBTTagList; + +import forestry.api.core.INBTTagable; +import forestry.core.config.Defaults; + +/** + * With permission from Krapht. + */ +public class InventoryAdapter implements IInventory, INBTTagable { + + private IInventory inventory = null; + //private boolean debug = false; + + public InventoryAdapter(int size, String name) { + this(size, name, 64); + } + + public InventoryAdapter(int size, String name, int stackLimit) { + this(new PlainInventory(size, name, stackLimit)); + } + + public InventoryAdapter(IInventory inventory) { + this.inventory = inventory; + configureSided(); + } + + /* + public InventoryAdapter enableDebug() { + this.debug = true; + return this; + } + */ + + /** + * @return Copy of this inventory. Stacks are copies. + */ + public InventoryAdapter copy() { + InventoryAdapter copy = new InventoryAdapter(inventory.getSizeInventory(), inventory.getInventoryName(), inventory.getInventoryStackLimit()); + + for (int i = 0; i < inventory.getSizeInventory(); i++) + if (inventory.getStackInSlot(i) != null) + copy.setInventorySlotContents(i, inventory.getStackInSlot(i).copy()); + + return copy; + } + + public ItemStack[] getStacks() { + ItemStack[] stacks = new ItemStack[inventory.getSizeInventory()]; + for(int i = 0; i < inventory.getSizeInventory(); i++) + stacks[i] = inventory.getStackInSlot(i); + return stacks; + } + + public ItemStack[] getStacks(int slot1, int length) { + ItemStack[] result = new ItemStack[length]; + for(int i = slot1; i < slot1 + length; i++) + result[i - slot1] = inventory.getStackInSlot(i); + return result; + } + + public boolean tryAddStacksCopy(ItemStack[] stacks, boolean all) { + + boolean addedAll = true; + for (ItemStack stack : stacks) { + if (stack == null) + continue; + + if (!tryAddStack(stack.copy(), all)) + addedAll = false; + } + + return addedAll; + } + + public boolean tryAddStacks(ItemStack[] stacks, boolean all) { + + boolean addedAll = true; + for (ItemStack stack : stacks) { + if (stack == null) + continue; + + if (!tryAddStack(stack, all)) + addedAll = false; + } + + return addedAll; + } + + public boolean tryAddStack(ItemStack stack, boolean all) { + return tryAddStack(stack, 0, this.getSizeInventory(), all); + } + + /** + * Tries to add a stack to the specified slot range. + * + * @param stack + * @param startSlot + * @param slots + * @param all + * @return + */ + public boolean tryAddStack(ItemStack stack, int startSlot, int slots, boolean all) { + return tryAddStack(stack, startSlot, slots, all, true); + } + + public boolean tryAddStack(ItemStack stack, int startSlot, int slots, boolean all, boolean doAdd) { + return addStack(stack, startSlot, slots, all, doAdd) > 0; + } + + public int addStack(ItemStack stack, boolean all, boolean doAdd) { + return addStack(stack, 0, this.getSizeInventory(), all, doAdd); + } + + public int addStack(ItemStack stack, int startSlot, int slots, boolean all, boolean doAdd) { + + int added = 0; + // Add to existing stacks first + for (int i = startSlot; i < startSlot + slots; i++) { + + // Empty slot. Add + if (inventory.getStackInSlot(i) == null) + continue; + + // Already occupied by different item, skip this slot. + if (!inventory.getStackInSlot(i).isItemEqual(stack)) + continue; + if (!ItemStack.areItemStackTagsEqual(inventory.getStackInSlot(i), stack)) + continue; + + int remain = stack.stackSize - added; + int space = inventory.getStackInSlot(i).getMaxStackSize() - inventory.getStackInSlot(i).stackSize; + // No space left, skip this slot. + if (space <= 0) + continue; + // Enough space + if (space >= remain) { + if (doAdd) + inventory.getStackInSlot(i).stackSize += remain; + return stack.stackSize; + } + + // Not enough space + if (doAdd) + inventory.getStackInSlot(i).stackSize = inventory.getStackInSlot(i).getMaxStackSize(); + + added += space; + } + + if (added >= stack.stackSize) + return added; + + for (int i = startSlot; i < startSlot + slots; i++) { + if (inventory.getStackInSlot(i) != null) + continue; + + if (doAdd) { + setInventorySlotContents(i, stack.copy()); + inventory.getStackInSlot(i).stackSize = stack.stackSize - added; + } + return stack.stackSize; + + } + + return added; + + } + + /* CONTAINS */ + public boolean contains(ItemStack[] query, int startSlot, int slots) { + for (ItemStack queried : query) { + + int itemCount = 0; + for (int i = startSlot; i < startSlot + slots; i++) { + ItemStack stack = inventory.getStackInSlot(i); + + if (stack == null) + continue; + + if (StackUtils.equals(Blocks.air, queried)) { + itemCount += stack.stackSize; + continue; + } + if (queried.getItemDamage() < 0) { + + if (stack.getItem() == queried.getItem()) + itemCount += stack.stackSize; + continue; + } + + if (stack.isItemEqual(queried) && ItemStack.areItemStackTagsEqual(stack, queried)) + itemCount += stack.stackSize; + } + + if (itemCount < queried.stackSize) + return false; + + } + + return true; + } + + /* REMOVAL */ + public void removeResources(ItemStack[] query, int startSlot, int slots) { + for (ItemStack queried : query) { + + ItemStack remain = queried.copy(); + + for (int i = startSlot; i < startSlot + slots; i++) { + ItemStack stack = inventory.getStackInSlot(i); + + if (stack == null) + continue; + + if (queried.getItemDamage() < 0) { + + if (stack.getItem() == queried.getItem()) { + ItemStack removed = decrStackSize(i, remain.stackSize); + remain.stackSize -= removed.stackSize; + } + + } else if (stack.isItemEqual(remain) && ItemStack.areItemStackTagsEqual(stack, remain)) { + ItemStack removed = decrStackSize(i, remain.stackSize); + remain.stackSize -= removed.stackSize; + } + + if (remain.stackSize <= 0) + break; + } + + } + + } + + /* IINVENTORY */ + @Override + public int getSizeInventory() { + return inventory.getSizeInventory(); + } + + @Override + public ItemStack getStackInSlot(int slotId) { + return inventory.getStackInSlot(slotId); + } + + @Override + public ItemStack decrStackSize(int slotId, int count) { + return inventory.decrStackSize(slotId, count); + } + + @Override + public void setInventorySlotContents(int slotId, ItemStack itemstack) { + inventory.setInventorySlotContents(slotId, itemstack); + } + + @Override + public String getInventoryName() { + return inventory.getInventoryName(); + } + + @Override + public int getInventoryStackLimit() { + return inventory.getInventoryStackLimit(); + } + + @Override + public void markDirty() { + inventory.markDirty(); + } + + @Override + public ItemStack getStackInSlotOnClosing(int slotIndex) { + return inventory.getStackInSlotOnClosing(slotIndex); + } + + @Override + public boolean isUseableByPlayer(EntityPlayer entityplayer) { + return false; + } + + @Override + public boolean hasCustomInventoryName() { + return true; + } + + @Override + public boolean isItemValidForSlot(int i, ItemStack itemstack) { + return true; + } + + @Override + public void openInventory() { + } + + @Override + public void closeInventory() { + } + + /* ISIDEDINVENTORY */ + private int[][] slotMap; + + public int[] getSizeInventorySide(int side) { + return slotMap[side]; + } + + private void configureSided() { + slotMap = new int[6][0]; + configureSided(Defaults.FACINGS, 0, getSizeInventory()); + } + + public InventoryAdapter configureSidedUp(int startSlot, int count) { + return configureSided(Defaults.FACING_UP, startSlot, count); + } + + public InventoryAdapter configureSidedDown(int startSlot, int count) { + return configureSided(Defaults.FACING_DOWN, startSlot, count); + } + + public InventoryAdapter configureSidedNorthSouth(int startSlot, int count) { + return configureSided(Defaults.FACING_NORTHSOUTH, startSlot, count); + } + + public InventoryAdapter configureSidedWestEast(int startSlot, int count) { + return configureSided(Defaults.FACING_WESTEAST, startSlot, count); + } + + public InventoryAdapter configureSidedSides(int startSlot, int count) { + return configureSided(Defaults.FACING_SIDES, startSlot, count); + } + + public InventoryAdapter configureSided(int side, int startSlot, int count) { + return configureSided(new int[] { side }, startSlot, count); + } + + public InventoryAdapter configureSided(int[] sides, int startSlot, int count) { + int[] slots = new int[count]; + for(int i = 0; i < count; i++) + slots[i] = startSlot + i; + + return configureSided(sides, slots); + } + + public InventoryAdapter configureSided(int[] sides, int[] slots) { + for(int side : sides) + slotMap[side] = slots; + + return this; + } + + /* SAVING & LOADING */ + @Override + public void readFromNBT(NBTTagCompound nbttagcompound) { + if (!nbttagcompound.hasKey(inventory.getInventoryName())) + return; + + NBTTagList nbttaglist = nbttagcompound.getTagList(inventory.getInventoryName(), 10); + + for (int j = 0; j < nbttaglist.tagCount(); ++j) { + NBTTagCompound nbttagcompound2 = nbttaglist.getCompoundTagAt(j); + int index = nbttagcompound2.getByte("Slot"); + inventory.setInventorySlotContents(index, ItemStack.loadItemStackFromNBT(nbttagcompound2)); + } + } + + @Override + public void writeToNBT(NBTTagCompound nbttagcompound) { + NBTTagList nbttaglist = new NBTTagList(); + for (int i = 0; i < inventory.getSizeInventory(); i++) + if (inventory.getStackInSlot(i) != null) { + NBTTagCompound nbttagcompound2 = new NBTTagCompound(); + nbttagcompound2.setByte("Slot", (byte) i); + inventory.getStackInSlot(i).writeToNBT(nbttagcompound2); + nbttaglist.appendTag(nbttagcompound2); + } + nbttagcompound.setTag(inventory.getInventoryName(), nbttaglist); + } + +} diff --git a/forestry_common/core/forestry/core/utils/ItemInventory.java b/forestry_common/core/forestry/core/utils/ItemInventory.java new file mode 100755 index 000000000..4031fd5c2 --- /dev/null +++ b/forestry_common/core/forestry/core/utils/ItemInventory.java @@ -0,0 +1,221 @@ +/******************************************************************************* + * Copyright 2011-2014 by SirSengir + * + * This work is licensed under a Creative Commons Attribution-NonCommercial-NoDerivs 3.0 Unported License. + * + * To view a copy of this license, visit http://creativecommons.org/licenses/by-nc-nd/3.0/. + ******************************************************************************/ +package forestry.core.utils; + +import net.minecraft.entity.player.EntityPlayer; +import net.minecraft.inventory.IInventory; +import net.minecraft.item.Item; +import net.minecraft.item.ItemStack; +import net.minecraft.nbt.NBTTagCompound; +import net.minecraft.nbt.NBTTagList; + +import forestry.api.core.INBTTagable; + +public class ItemInventory implements IInventory, INBTTagable { + + public final Class itemClass; + public boolean isItemInventory = false; + public ItemStack parent; + protected ItemStack[] inventoryStacks; + + protected ItemInventory(Class itemClass) { + this.itemClass = itemClass; + } + + public ItemInventory(Class itemClass, int slots) { + this(itemClass); + inventoryStacks = new ItemStack[slots]; + } + + public ItemInventory(Class itemClass, int size, ItemStack itemstack) { + this(itemClass, size); + + parent = itemstack; + isItemInventory = true; + + // Set an uid to identify the itemstack on SMP + setUID(true); + + readFromNBT(itemstack.getTagCompound()); + } + + protected void setUID(boolean override) { + if (parent.getTagCompound() == null) + parent.setTagCompound(new NBTTagCompound()); + + NBTTagCompound nbt = parent.getTagCompound(); + if (override || !nbt.hasKey("UID")) { + nbt.setInteger("UID", Utils.getUID()); + } + } + + public void onGuiSaved(EntityPlayer player) { + parent = findParent(player); + if (parent != null) + save(); + } + + public ItemStack findParent(EntityPlayer player) { + if (parent == null) + return null; + + NBTTagCompound parentNBT = parent.getTagCompound(); + if (parentNBT == null) + return null; + + int uid = parentNBT.getInteger("UID"); + + for (int i = 0; i < player.inventory.getSizeInventory(); i++) { + ItemStack stack = player.inventory.getStackInSlot(i); + if (stack == null) + continue; + if(stack.getItem() != parent.getItem()) + continue; + NBTTagCompound slotNBT = stack.getTagCompound(); + if (slotNBT == null) + continue; + if (uid == slotNBT.getInteger("UID")) + return player.inventory.getStackInSlot(i); + } + return null; + } + + public boolean matchesUID(int otherId) { + if (parent == null) + return false; + + NBTTagCompound nbt = parent.getTagCompound(); + if (nbt == null) + return false; + + int uid = nbt.getInteger("UID"); + return uid == otherId; + } + + public void save() { + NBTTagCompound nbt = parent.getTagCompound(); + if (nbt == null) + nbt = new NBTTagCompound(); + writeToNBT(nbt); + parent.setTagCompound(nbt); + } + + @Override + public void readFromNBT(NBTTagCompound nbt) { + + if (nbt == null) + return; + + if (nbt.hasKey("Items")) { + NBTTagList nbttaglist = nbt.getTagList("Items", 10); + inventoryStacks = new ItemStack[getSizeInventory()]; + for (int i = 0; i < nbttaglist.tagCount(); i++) { + NBTTagCompound nbttagcompound1 = nbttaglist.getCompoundTagAt(i); + byte byte0 = nbttagcompound1.getByte("Slot"); + if (byte0 >= 0 && byte0 < inventoryStacks.length) + inventoryStacks[byte0] = ItemStack.loadItemStackFromNBT(nbttagcompound1); + } + } + + } + + @Override + public void writeToNBT(NBTTagCompound nbt) { + + NBTTagList nbttaglist = new NBTTagList(); + for (int i = 0; i < inventoryStacks.length; i++) + if (inventoryStacks[i] != null) { + NBTTagCompound nbttagcompound1 = new NBTTagCompound(); + nbttagcompound1.setByte("Slot", (byte) i); + inventoryStacks[i].writeToNBT(nbttagcompound1); + nbttaglist.appendTag(nbttagcompound1); + } + nbt.setTag("Items", nbttaglist); + + } + + @Override + public ItemStack decrStackSize(int i, int j) { + if (inventoryStacks[i] == null) + return null; + + ItemStack product; + if (inventoryStacks[i].stackSize <= j) { + product = inventoryStacks[i]; + inventoryStacks[i] = null; + return product; + } else { + product = inventoryStacks[i].splitStack(j); + if (inventoryStacks[i].stackSize == 0) + inventoryStacks[i] = null; + + return product; + } + } + + @Override + public void setInventorySlotContents(int i, ItemStack itemstack) { + inventoryStacks[i] = itemstack; + } + + @Override + public ItemStack getStackInSlot(int i) { + return inventoryStacks[i]; + } + + @Override + public int getSizeInventory() { + return inventoryStacks.length; + } + + @Override + public String getInventoryName() { + return "BeeBag"; + } + + @Override + public int getInventoryStackLimit() { + return 64; + } + + @Override + public void markDirty() { + } + + @Override + public boolean isUseableByPlayer(EntityPlayer entityplayer) { + return true; + } + + @Override + public boolean hasCustomInventoryName() { + return true; + } + + @Override + public boolean isItemValidForSlot(int i, ItemStack itemstack) { + return true; + } + + @Override + public void openInventory() { + } + + @Override + public void closeInventory() { + } + + @Override + public ItemStack getStackInSlotOnClosing(int slot) { + if (inventoryStacks[slot] == null) + return null; + ItemStack toReturn = inventoryStacks[slot]; + inventoryStacks[slot] = null; + return toReturn; + } +} diff --git a/forestry_common/core/forestry/core/utils/ItemStackMap.java b/forestry_common/core/forestry/core/utils/ItemStackMap.java new file mode 100755 index 000000000..985867eb0 --- /dev/null +++ b/forestry_common/core/forestry/core/utils/ItemStackMap.java @@ -0,0 +1,48 @@ +/******************************************************************************* + * Copyright 2011-2014 by SirSengir + * + * This work is licensed under a Creative Commons Attribution-NonCommercial-NoDerivs 3.0 Unported License. + * + * To view a copy of this license, visit http://creativecommons.org/licenses/by-nc-nd/3.0/. + ******************************************************************************/ +package forestry.core.utils; + + +import net.minecraft.item.Item; +import net.minecraft.item.ItemStack; + +import net.minecraftforge.oredict.OreDictionary; + +public class ItemStackMap extends StackMap { + private static final long serialVersionUID = -8511966739130702305L; + + @Override + protected boolean areEqual(ItemStack a, Object b) { + if(b instanceof ItemStack) { + ItemStack b2 = (ItemStack) b; + return a.isItemEqual(b2) && ItemStack.areItemStackTagsEqual(a, b2); + } + if(b instanceof Item) { + return a.getItem() == (Item) b; + } + if(b instanceof String) { + for(ItemStack stack : OreDictionary.getOres((String) b)) { + if(areEqual(a, stack)) return true; + } + } + return false; + } + + @Override + protected boolean isValidKey(Object key) { + return key instanceof ItemStack || key instanceof Item || key instanceof String; + } + + @Override + protected ItemStack getStack(Object key) { + if(key instanceof ItemStack) + return (ItemStack) key; + return null; + } + +} diff --git a/forestry_common/core/forestry/core/utils/LiquidHelper.java b/forestry_common/core/forestry/core/utils/LiquidHelper.java new file mode 100755 index 000000000..c24149b24 --- /dev/null +++ b/forestry_common/core/forestry/core/utils/LiquidHelper.java @@ -0,0 +1,266 @@ +/******************************************************************************* + * Copyright 2011-2014 by SirSengir + * + * This work is licensed under a Creative Commons Attribution-NonCommercial-NoDerivs 3.0 Unported License. + * + * To view a copy of this license, visit http://creativecommons.org/licenses/by-nc-nd/3.0/. + ******************************************************************************/ +package forestry.core.utils; + +import java.util.HashMap; +import java.util.LinkedList; + +import net.minecraft.client.renderer.texture.IIconRegister; +import net.minecraft.entity.player.EntityPlayer; +import net.minecraft.inventory.IInventory; +import net.minecraft.item.ItemStack; +import net.minecraft.util.IIcon; + +import cpw.mods.fml.common.registry.LanguageRegistry; + +import net.minecraftforge.common.util.ForgeDirection; +import net.minecraftforge.fluids.Fluid; +import net.minecraftforge.fluids.FluidContainerRegistry; +import net.minecraftforge.fluids.FluidContainerRegistry.FluidContainerData; +import net.minecraftforge.fluids.FluidRegistry; +import net.minecraftforge.fluids.FluidStack; +import net.minecraftforge.fluids.IFluidHandler; + +import forestry.api.recipes.RecipeManagers; +import forestry.core.config.Defaults; +import forestry.core.config.ForestryItem; +import forestry.core.render.TextureManager; + +public class LiquidHelper { + + private static LinkedList myLiquids = new LinkedList(); + private static HashMap liquidMap = new HashMap(); + + public static boolean isEmptyLiquidData() { + return FluidContainerRegistry.getRegisteredFluidContainerData().length <= 0; + } + + public static boolean isEmptyContainer(ItemStack empty) { + return FluidContainerRegistry.isEmptyContainer(empty); + } + + public static FluidContainerData getEmptyContainer(ItemStack empty, FluidStack liquid) { + for (FluidContainerData cont : FluidContainerRegistry.getRegisteredFluidContainerData()) { + if (cont.fluid.isFluidEqual(liquid) && (cont.emptyContainer != null && cont.emptyContainer.isItemEqual(empty))) + return cont; + } + + return null; + } + + public static FluidContainerData getLiquidContainer(ItemStack container) { + for (FluidContainerData cont : FluidContainerRegistry.getRegisteredFluidContainerData()) { + if (cont.filledContainer.isItemEqual(container)) + return cont; + } + return null; + } + + public static FluidContainerData createLiquidData(String ident, FluidStack stillLiquid, ItemStack filled, ItemStack container) { + return new FluidContainerData(new FluidStack(getOrCreateLiquid(ident), Defaults.BUCKET_VOLUME), filled, container); + } + + public static boolean isLiquid(String ident, FluidStack stack) { + return FluidRegistry.getFluidID(ident) == stack.fluidID; + } + + public static boolean exists(String ident) { + return FluidRegistry.isFluidRegistered(ident); + } + + public static Fluid getFluid(String ident) { + Fluid fluid = FluidRegistry.getFluid(ident); + return fluid; + } + + public static Fluid getOrCreateLiquid(String ident) { + if (!FluidRegistry.isFluidRegistered(ident)) { + Fluid fluid = new Fluid(ident); + LanguageRegistry.instance().addStringLocalization(fluid.getUnlocalizedName(), Localization.instance.get(fluid.getUnlocalizedName())); + FluidRegistry.registerFluid(fluid); + myLiquids.add(ident); + } + liquidMap.put(ident, FluidRegistry.getFluid(ident)); + return FluidRegistry.getFluid(ident); + } + + public static FluidStack getLiquid(String name, int amount) { + return FluidRegistry.getFluidStack(name, amount); + } + + public static void injectLiquidContainer(String name, int volume, ItemStack filled, ItemStack empty) { + injectLiquidContainer(name, volume, filled, empty, null, 0); + } + + public static void injectWaxContainer(String name, int volume, ItemStack filled, ItemStack empty) { + injectLiquidContainer(name, volume, filled, empty, ForestryItem.beeswax.getItemStack(), 10); + } + + public static void injectRefractoryContainer(String name, int volume, ItemStack filled, ItemStack empty) { + injectLiquidContainer(name, volume, filled, empty, ForestryItem.refractoryWax.getItemStack(), 10); + } + + public static void injectTinContainer(String name, int volume, ItemStack filled, ItemStack empty) { + injectLiquidContainer(name, volume, filled, empty, ForestryItem.ingotTin.getItemStack(), 5); + } + + public static void injectLiquidContainer(String name, int volume, ItemStack filled, ItemStack empty, ItemStack remnant, int chance) { + FluidStack contained = getLiquid(name, volume); + if (contained == null) + throw new IllegalArgumentException(String.format("Attempted to inject a liquid container for the non-existent liquid '%s'.", name)); + + FluidContainerData container = new FluidContainerData(contained, filled, empty); + FluidContainerRegistry.registerFluidContainer(container); + + if (RecipeManagers.squeezerManager != null) + if (!container.filledContainer.getItem().hasContainerItem(container.filledContainer)) + if (remnant != null) + RecipeManagers.squeezerManager.addRecipe(10, new ItemStack[] { container.filledContainer }, container.fluid, remnant, chance); + else + RecipeManagers.squeezerManager.addRecipe(10, new ItemStack[] { container.filledContainer }, container.fluid); + } + + public static void resetLiquidIcons(IIconRegister register) { + for (String fluidString : myLiquids) { + Fluid fluid = getFluid(fluidString); + IIcon icon = TextureManager.getInstance().registerTex(register, "liquid/" + fluid.getName()); + fluid.setIcons(icon); + + } + } + + public static boolean handleRightClick(IFluidHandler tank, ForgeDirection side, EntityPlayer player, boolean fill, boolean drain) { + if (player == null) { + return false; + } + ItemStack current = player.inventory.getCurrentItem(); + if (current != null) { + + FluidStack liquid = FluidContainerRegistry.getFluidForFilledItem(current); + + if (fill && liquid != null) { + int used = tank.fill(side, liquid, true); + + if (used > 0) { + if (!player.capabilities.isCreativeMode) { + player.inventory.setInventorySlotContents(player.inventory.currentItem, StackUtils.consumeItem(current)); + player.inventory.markDirty(); + } + return true; + } + + } else if (drain) { + + FluidStack available = tank.drain(side, Integer.MAX_VALUE, false); + if (available != null) { + ItemStack filled = FluidContainerRegistry.fillFluidContainer(available, current); + + liquid = FluidContainerRegistry.getFluidForFilledItem(filled); + if (liquid != null) { + + if (current.stackSize > 1) { + if (!player.inventory.addItemStackToInventory(filled)) + return false; + player.inventory.setInventorySlotContents(player.inventory.currentItem, StackUtils.consumeItem(current)); + player.inventory.markDirty(); + } else { + player.inventory.setInventorySlotContents(player.inventory.currentItem, StackUtils.consumeItem(current)); + player.inventory.setInventorySlotContents(player.inventory.currentItem, filled); + player.inventory.markDirty(); + } + + tank.drain(side, liquid.amount, true); + return true; + } + } + } + } + return false; + } + + public static void processContainers(IFluidHandler fluidHandler, IInventory inv, int inputSlot, int outputSlot, Fluid fluidToFill, boolean processFilled, boolean processEmpty) { + ItemStack input = inv.getStackInSlot(inputSlot); + + if (input == null) + return; + + if (processFilled && drainContainers(fluidHandler, inv, inputSlot, outputSlot)) + return; + + if (processEmpty && fluidToFill != null) + fillContainers(fluidHandler, inv, inputSlot, outputSlot, fluidToFill); + } + + public static boolean fillContainers(IFluidHandler fluidHandler, IInventory inv, int inputSlot, int outputSlot, Fluid fluidToFill) { + return fillContainers(fluidHandler, inv, inputSlot, outputSlot, fluidToFill, true); + } + + public static boolean fillContainers(IFluidHandler fluidHandler, IInventory inv, int inputSlot, int outputSlot, Fluid fluidToFill, boolean doFill) { + ItemStack input = inv.getStackInSlot(inputSlot); + ItemStack output = inv.getStackInSlot(outputSlot); + ItemStack filled = getFilledContainer(fluidToFill, input); + if (filled != null && (output == null || (output.stackSize < output.getMaxStackSize() && StackUtils.isIdenticalItem(filled, output)))) { + FluidStack fluidInContainer = getFluidStackInContainer(filled); + FluidStack drain = fluidHandler.drain(ForgeDirection.UNKNOWN, fluidInContainer, false); + if (drain != null && drain.amount == fluidInContainer.amount) { + if (doFill) { + fluidHandler.drain(ForgeDirection.UNKNOWN, fluidInContainer, true); + if (output == null) + inv.setInventorySlotContents(outputSlot, filled); + else + output.stackSize++; + inv.decrStackSize(inputSlot, 1); + } + return true; + } + } + return false; + } + + public static boolean drainContainers(IFluidHandler fluidHandler, IInventory inv, int inputSlot, int outputSlot) { + ItemStack input = inv.getStackInSlot(inputSlot); + ItemStack output = inv.getStackInSlot(outputSlot); + + if (input != null) { + FluidStack fluidInContainer = getFluidStackInContainer(input); + ItemStack emptyItem = input.getItem().getContainerItem(input); + if (fluidInContainer != null && (emptyItem == null || output == null || (output.stackSize < output.getMaxStackSize() && StackUtils.isIdenticalItem(output, emptyItem)))) { + int used = fluidHandler.fill(ForgeDirection.UNKNOWN, fluidInContainer, false); + if (used >= fluidInContainer.amount) { + fluidHandler.fill(ForgeDirection.UNKNOWN, fluidInContainer, true); + if (emptyItem != null) + if (output == null) + inv.setInventorySlotContents(outputSlot, emptyItem); + else + output.stackSize++; + inv.decrStackSize(inputSlot, 1); + return true; + } + } + } + return false; + } + + public static ItemStack getFilledContainer(Fluid fluid, ItemStack empty) { + if (fluid == null || empty == null) + return null; + return FluidContainerRegistry.fillFluidContainer(new FluidStack(fluid, Integer.MAX_VALUE), empty); + } + + public static FluidStack getFluidStackInContainer(ItemStack stack) { + return FluidContainerRegistry.getFluidForFilledItem(stack); + } + + public static boolean containsFluidStack(ItemStack stack, FluidStack fluidStack) { + return FluidContainerRegistry.containsFluid(stack, fluidStack); + } + + public static boolean containsFluid(ItemStack stack, Fluid fluid) { + return FluidContainerRegistry.containsFluid(stack, new FluidStack(fluid, 1)); + } +} diff --git a/forestry_common/core/forestry/core/utils/Localization.java b/forestry_common/core/forestry/core/utils/Localization.java new file mode 100755 index 000000000..8cffa4970 --- /dev/null +++ b/forestry_common/core/forestry/core/utils/Localization.java @@ -0,0 +1,102 @@ +/******************************************************************************* + * Copyright 2011-2014 by SirSengir + * + * This work is licensed under a Creative Commons Attribution-NonCommercial-NoDerivs 3.0 Unported License. + * + * To view a copy of this license, visit http://creativecommons.org/licenses/by-nc-nd/3.0/. + ******************************************************************************/ +package forestry.core.utils; + +import java.io.InputStream; +import java.util.LinkedList; +import java.util.Properties; + +import forestry.core.proxy.Proxies; + +/** + * Simple mod localization class. + * + * @author Jimeo Wan / modified for Forestry by SirSengir + * @license Public domain + */ +public class Localization { + + public static Localization instance = new Localization(); + + private static final String DEFAULT_LANGUAGE = "en_US"; + + private String loadedLanguage = null; + private Properties defaultMappings = new Properties(); + private Properties mappings = new Properties(); + private LinkedList modules = new LinkedList(); + + /** + * Loads the mod's localization files. All language files must be stored in "[modname]/lang/", in .properties files. (ex: for the mod 'invtweaks', the + * french translation is in: "invtweaks/lang/fr_FR.properties") + * + * @param modName + * The mod name + */ + public Localization() { + addLocalization("/lang/forestry/core/"); + } + + public void addLocalization(String path) { + modules.add(path); + load(path, DEFAULT_LANGUAGE); + } + + private void load(String newLanguage) { + defaultMappings.clear(); + mappings.clear(); + + for (String path : this.modules) + load(path, newLanguage); + } + + private void load(String path, String newLanguage) { + + Properties modMappings = new Properties(); + + try { + InputStream langStream = Localization.class.getResourceAsStream(path + newLanguage + ".properties"); + InputStream defaultLangStream = Localization.class.getResourceAsStream(path + DEFAULT_LANGUAGE + ".properties"); + modMappings.load((langStream == null) ? defaultLangStream : langStream); + mappings.putAll(modMappings); + + modMappings.clear(); + modMappings.load(defaultLangStream); + defaultMappings.putAll(modMappings); + + if (langStream != null) + langStream.close(); + defaultLangStream.close(); + } catch (Exception e) { + e.printStackTrace(); + } + loadedLanguage = newLanguage; + } + + /** + * Get a string for the given key, in the currently active translation. + * + * @param key + * @return + */ + public synchronized String get(String key) { + String currentLanguage = getCurrentLanguage(); + if (currentLanguage == null || !currentLanguage.equals(loadedLanguage)) + load(currentLanguage); + + return mappings.getProperty(key, defaultMappings.getProperty(key, key)); + } + + public boolean hasMapping(String key) { + return mappings.containsKey(key) || defaultMappings.containsKey(key); + } + + private static String getCurrentLanguage() { + return Proxies.common.getCurrentLanguage(); + } + +} diff --git a/forestry_common/core/forestry/core/utils/PlainInventory.java b/forestry_common/core/forestry/core/utils/PlainInventory.java new file mode 100755 index 000000000..ea9e2754b --- /dev/null +++ b/forestry_common/core/forestry/core/utils/PlainInventory.java @@ -0,0 +1,111 @@ +/******************************************************************************* + * Copyright 2011-2014 by SirSengir + * + * This work is licensed under a Creative Commons Attribution-NonCommercial-NoDerivs 3.0 Unported License. + * + * To view a copy of this license, visit http://creativecommons.org/licenses/by-nc-nd/3.0/. + ******************************************************************************/ +package forestry.core.utils; + +import net.minecraft.entity.player.EntityPlayer; +import net.minecraft.inventory.IInventory; +import net.minecraft.item.ItemStack; + +public class PlainInventory implements IInventory { + + private final ItemStack[] contents; + private final String name; + private final int stackLimit; + + public PlainInventory(int size, String name) { + this(size, name, 64); + } + + public PlainInventory(int size, String name, int stackLimit) { + this.contents = new ItemStack[size]; + this.name = name; + this.stackLimit = stackLimit; + } + + public PlainInventory(IInventory tocopy) { + this(tocopy.getSizeInventory(), tocopy.getInventoryName(), tocopy.getInventoryStackLimit()); + for (int i = 0; i < tocopy.getSizeInventory(); i++) { + if (tocopy.getStackInSlot(i) != null) + this.setInventorySlotContents(i, tocopy.getStackInSlot(i).copy()); + else + this.setInventorySlotContents(i, null); + } + } + + public ItemStack[] getContents() { + return contents; + } + + @Override + public int getSizeInventory() { + return contents.length; + } + + @Override + public ItemStack getStackInSlot(int slotId) { + return contents[slotId]; + } + + @Override + public ItemStack decrStackSize(int slotId, int count) { + if (contents[slotId] == null) + return null; + if (contents[slotId].stackSize > count) + return contents[slotId].splitStack(count); + ItemStack stack = contents[slotId]; + contents[slotId] = null; + return stack; + } + + @Override + public void setInventorySlotContents(int slotId, ItemStack itemstack) { + contents[slotId] = itemstack; + } + + @Override + public String getInventoryName() { + return name; + } + + @Override + public int getInventoryStackLimit() { + return stackLimit; + } + + @Override + public void markDirty() { + } + + @Override + public boolean isUseableByPlayer(EntityPlayer entityplayer) { + return false; + } + + @Override + public ItemStack getStackInSlotOnClosing(int slotIndex) { + return this.getStackInSlot(slotIndex); + } + + @Override + public boolean hasCustomInventoryName() { + return true; + } + + @Override + public boolean isItemValidForSlot(int i, ItemStack itemstack) { + return true; + } + + @Override + public void openInventory() { + } + + @Override + public void closeInventory() { + } +} diff --git a/forestry_common/core/forestry/core/utils/RecipeUtil.java b/forestry_common/core/forestry/core/utils/RecipeUtil.java new file mode 100755 index 000000000..ce95cad57 --- /dev/null +++ b/forestry_common/core/forestry/core/utils/RecipeUtil.java @@ -0,0 +1,70 @@ +/******************************************************************************* + * Copyright 2011-2014 by SirSengir + * + * This work is licensed under a Creative Commons Attribution-NonCommercial-NoDerivs 3.0 Unported License. + * + * To view a copy of this license, visit http://creativecommons.org/licenses/by-nc-nd/3.0/. + ******************************************************************************/ +package forestry.core.utils; + +import net.minecraft.item.ItemStack; + +import forestry.api.recipes.RecipeManagers; +import forestry.core.config.Defaults; +import forestry.core.interfaces.IDescriptiveRecipe; +import forestry.core.proxy.Proxies; + +public class RecipeUtil { + + public static void injectLeveledRecipe(ItemStack resource, int fermentationValue, String output) { + if (RecipeManagers.fermenterManager == null) + return; + + RecipeManagers.fermenterManager.addRecipe(resource, fermentationValue, 1.0f, LiquidHelper.getLiquid(output, 1), LiquidHelper.getLiquid(Defaults.LIQUID_WATER, 1)); + + if (LiquidHelper.exists(Defaults.LIQUID_JUICE)) + RecipeManagers.fermenterManager.addRecipe(resource, fermentationValue, 1.5f, LiquidHelper.getLiquid(output, 1), LiquidHelper.getLiquid(Defaults.LIQUID_JUICE, 1)); + + if (LiquidHelper.exists(Defaults.LIQUID_HONEY)) + RecipeManagers.fermenterManager.addRecipe(resource, fermentationValue, 1.5f, LiquidHelper.getLiquid(output, 1), LiquidHelper.getLiquid(Defaults.LIQUID_HONEY, 1)); + } + + public static Object[] getCraftingRecipeAsArray(Object rec) { + + try { + + if (rec instanceof IDescriptiveRecipe) { + + IDescriptiveRecipe recipe = (IDescriptiveRecipe) rec; + return getShapedRecipeAsArray(recipe.getWidth(), recipe.getHeight(), recipe.getIngredients(), recipe.getRecipeOutput()); + + } + + } catch (Exception ex) { + Proxies.log.warning("Exception while trying to parse an ItemStack[10] from an IRecipe:"); + Proxies.log.warning(ex.getMessage()); + } + + return null; + } + + /* + * private static Object[] getSmallShapedRecipeAsArray(int width, int height, Object[] ingredients, ItemStack output) { Object[] result = new Object[5]; + * + * for(int y = 0; y < height; y++) for(int x = 0; x < width; x++) result[y * 2 + x] = ingredients[y * width + x]; + * + * result[4] = output; return result; } + */ + private static Object[] getShapedRecipeAsArray(int width, int height, Object[] ingredients, ItemStack output) { + Object[] result = new Object[10]; + + for (int y = 0; y < height; y++) { + for (int x = 0; x < width; x++) { + result[y * 3 + x] = ingredients[y * width + x]; + } + } + + result[9] = output; + return result; + } +} diff --git a/forestry_common/core/forestry/core/utils/Schemata.java b/forestry_common/core/forestry/core/utils/Schemata.java new file mode 100755 index 000000000..49d4cae42 --- /dev/null +++ b/forestry_common/core/forestry/core/utils/Schemata.java @@ -0,0 +1,139 @@ +/******************************************************************************* + * Copyright 2011-2014 by SirSengir + * + * This work is licensed under a Creative Commons Attribution-NonCommercial-NoDerivs 3.0 Unported License. + * + * To view a copy of this license, visit http://creativecommons.org/licenses/by-nc-nd/3.0/. + ******************************************************************************/ +package forestry.core.utils; + +import forestry.core.config.Config; + +public class Schemata { + public enum EnumStructureBlock { + ANY('X'), FOREIGN('F'), AIR('O'), MASTER('M'), GLASS('G'), BLOCK_A('A'), BLOCK_B('B'), BLOCK_C('C'), BLOCK_D('D'), BLOCK_E('E'); + + private char key; + + private EnumStructureBlock(char key) { + this.key = key; + } + + public char getKey() { + return this.key; + } + } + + private final String uid; + private EnumStructureBlock[][][] structure; + private int width, height, depth; + private int xOffset, yOffset, zOffset = -1; + + public Schemata(String uid, int width, int height, int depth, String... patterns) { + this(uid, width, height, depth); + this.setStructure(patterns); + } + + public Schemata(String uid, int width, int height, int depth) { + this.uid = uid; + this.structure = new EnumStructureBlock[width][height][depth]; + this.width = width; + this.height = height; + this.depth = depth; + } + + private void setStructure(String... patterns) { + + String fullpattern = ""; + + for (String pattern : patterns) + fullpattern = (new StringBuilder()).append(fullpattern).append(pattern).toString(); + + if (fullpattern.length() != getWidth() * getHeight() * getDepth()) + throw new RuntimeException("Incorrect pattern " + fullpattern + " (" + fullpattern.length() + ") for (" + getWidth() + "/" + getHeight() + "/" + + getDepth() + ")"); + + for (int i = 0; i < getWidth(); i++) + for (int j = 0; j < getHeight(); j++) + for (int k = 0; k < getDepth(); k++) + for (EnumStructureBlock type : EnumStructureBlock.values()) + if (type.getKey() == fullpattern.charAt(i * getHeight() * getDepth() + j * getDepth() + k)) { + structure[i][j][k] = type; + break; + } + + /* + * for(int i = 0; i < getWidth(); i++) { for(int j = 0; j < getHeight(); j++) { System.out.print("["); for(int k = 0; k < getDepth(); k++) { + * System.out.print(structure[i][j][k].getKey()); } System.out.print("]"); } System.out.println(); } + */ + + } + + public Schemata setOffsets(int xOffset, int yOffset, int zOffset) { + this.xOffset = xOffset; + this.yOffset = yOffset; + this.zOffset = zOffset; + + return this; + } + + public EnumStructureBlock getAt(int x, int y, int z, boolean rotate) { + if (rotate) + return structure[z][y][x]; + return structure[x][y][z]; + } + + public Vect getDimensions(boolean rotate) { + if (rotate) + return new Vect(getDepth(), getHeight(), getWidth()); + else + return new Vect(getWidth(), getHeight(), getDepth()); + } + + public boolean isEnabled() { + return !Config.disabledStructures.contains(uid); + } + + /** + * @return the width + */ + public int getWidth() { + return width; + } + + /** + * @return the height + */ + public int getHeight() { + return height; + } + + /** + * @return the depth + */ + public int getDepth() { + return depth; + } + + /** + * @return the xOffset + */ + public int getxOffset() { + return xOffset; + } + + /** + * @return the yOffset + */ + public int getyOffset() { + return yOffset; + } + + /** + * @return the zOffset + */ + public int getzOffset() { + return zOffset; + } + +} diff --git a/forestry_common/core/forestry/core/utils/ShapedRecipeCustom.java b/forestry_common/core/forestry/core/utils/ShapedRecipeCustom.java new file mode 100755 index 000000000..6e494f737 --- /dev/null +++ b/forestry_common/core/forestry/core/utils/ShapedRecipeCustom.java @@ -0,0 +1,251 @@ +/******************************************************************************* + * Copyright 2011-2014 by SirSengir + * + * This work is licensed under a Creative Commons Attribution-NonCommercial-NoDerivs 3.0 Unported License. + * + * To view a copy of this license, visit http://creativecommons.org/licenses/by-nc-nd/3.0/. + ******************************************************************************/ +package forestry.core.utils; + +import java.util.ArrayList; +import java.util.HashMap; + +import net.minecraft.block.Block; +import net.minecraft.inventory.InventoryCrafting; +import net.minecraft.item.Item; +import net.minecraft.item.ItemStack; +import net.minecraft.item.crafting.CraftingManager; +import net.minecraft.nbt.NBTTagCompound; +import net.minecraft.world.World; + +import net.minecraftforge.oredict.OreDictionary; + +import forestry.core.config.Defaults; +import forestry.core.config.ForestryItem; +import forestry.core.interfaces.IDescriptiveRecipe; + +public class ShapedRecipeCustom implements IDescriptiveRecipe { + + private final int width; + private final int height; + + private final Object ingredients[]; + private final ItemStack product; + + private boolean preserveNBT = false; + + public ShapedRecipeCustom(int width, int height, Object ingredients[], ItemStack product) { + this.width = width; + this.height = height; + this.ingredients = ingredients; + this.product = product; + } + + public ShapedRecipeCustom setPreserveNBT() { + this.preserveNBT = true; + return this; + } + + @Override + public int getWidth() { + return width; + } + + @Override + public int getHeight() { + return height; + } + + @Override + public ItemStack getRecipeOutput() { + return product; + } + + @Override + public Object[] getIngredients() { + return ingredients; + } + + @Override + public boolean matches(InventoryCrafting inventorycrafting, World world) { + ItemStack[][] resources = new ItemStack[3][3]; + for (int i = 0; i < 3; i++) + for (int j = 0; j < 3; j++) + resources[i][j] = inventorycrafting.getStackInRowAndColumn(i, j); + + return matches(resources); + } + + public boolean matches(ItemStack[][] resources) { + + for (int i = 0; i <= 3 - width; i++) + for (int j = 0; j <= 3 - height; j++) { + if (checkMatch(resources, i, j, true)) + return true; + + if (checkMatch(resources, i, j, false)) + return true; + } + + return false; + } + + @SuppressWarnings("unchecked") + private boolean checkMatch(ItemStack[][] resources, int xInGrid, int yInGrid, boolean flag) { + + for (int k = 0; k < 3; k++) + for (int l = 0; l < 3; l++) { + + int widthIt = k - xInGrid; + int heightIt = l - yInGrid; + Object compare = null; + + if (widthIt >= 0 && heightIt >= 0 && widthIt < width && heightIt < height) + if (flag) + compare = ingredients[(width - widthIt - 1) + heightIt * width]; + else + compare = ingredients[widthIt + heightIt * width]; + ItemStack resource = resources[k][l]; + + if (compare instanceof ItemStack) { + if (!checkItemMatch((ItemStack) compare, resource)) + return false; + } else if (compare instanceof ArrayList) { + boolean matched = false; + + for (ItemStack item : (ArrayList) compare) + matched = matched || checkItemMatch(item, resource); + + if (!matched) + return false; + + } else if (compare == null && resource != null) + return false; + } + + return true; + } + + private boolean checkItemMatch(ItemStack compare, ItemStack resource) { + + if (resource == null && compare == null) + return true; + + if (resource == null && compare != null || resource != null && compare == null) + return false; + + if (compare.getItem() != resource.getItem()) + return false; + + if (compare.getItemDamage() != Defaults.WILDCARD && compare.getItemDamage() != resource.getItemDamage()) + return false; + + return true; + } + + @Override + public ItemStack getCraftingResult(InventoryCrafting inventorycrafting) { + if (preserveNBT) + for (int i = 0; i < inventorycrafting.getSizeInventory(); i++) { + if (inventorycrafting.getStackInSlot(i) == null) + continue; + if (!inventorycrafting.getStackInSlot(i).hasTagCompound()) + continue; + + ItemStack crafted = product.copy(); + crafted.setTagCompound((NBTTagCompound) inventorycrafting.getStackInSlot(i).getTagCompound().copy()); + return crafted; + } + + return product.copy(); + } + + @Override + public int getRecipeSize() { + return width * height; + } + + /** + * @param resource + * @return true if resource is a valid ingredient in this recipe. + */ + @SuppressWarnings("unchecked") + public boolean isIngredient(ItemStack resource) { + + for (Object ingredient : ingredients) + if (ingredient instanceof ItemStack) { + if (checkItemMatch((ItemStack) ingredient, resource)) + return true; + + } else if (ingredient instanceof ArrayList) + for (ItemStack item : (ArrayList) ingredient) + if (checkItemMatch(item, resource)) + return true; + + return false; + + } + + public static ShapedRecipeCustom createShapedRecipe(ItemStack product, Object... materials) { + + String s = ""; + int index = 0; + int columns = 0; + int rows = 0; + if (materials[index] instanceof String[]) { + String as[] = (String[]) materials[index++]; + for (int l = 0; l < as.length; l++) { + String pattern = as[l]; + rows++; + columns = pattern.length(); + s = (new StringBuilder()).append(s).append(pattern).toString(); + } + + } else + while (materials[index] instanceof String) { + String pattern = (String) materials[index++]; + rows++; + columns = pattern.length(); + s = (new StringBuilder()).append(s).append(pattern).toString(); + } + + HashMap hashmap = new HashMap(); + for (; index < materials.length; index += 2) { + + Character character = (Character) materials[index]; + + // Item + if (materials[index + 1] instanceof Item) + hashmap.put(character, new ItemStack((Item) materials[index + 1])); + else if (materials[index + 1] instanceof ForestryItem) + hashmap.put(character, ((ForestryItem) materials[index + 1]).getItemStack()); + else if (materials[index + 1] instanceof Block) + hashmap.put(character, new ItemStack((Block) materials[index + 1], 1, Defaults.WILDCARD)); + else if (materials[index + 1] instanceof ItemStack) + hashmap.put(character, materials[index + 1]); + else if (materials[index + 1] instanceof String) + hashmap.put(character, OreDictionary.getOres((String) materials[index + 1])); + else + throw new RuntimeException("Invalid Recipe Defined!"); + + } + + Object ingredients[] = new Object[columns * rows]; + for (int l = 0; l < columns * rows; l++) { + char c = s.charAt(l); + if (hashmap.containsKey(Character.valueOf(c))) + ingredients[l] = hashmap.get(Character.valueOf(c)); + else + ingredients[l] = null; + } + + return new ShapedRecipeCustom(columns, rows, ingredients, product); + } + + @SuppressWarnings("unchecked") + public static ShapedRecipeCustom buildRecipe(ItemStack product, Object... materials){ + ShapedRecipeCustom recipe = createShapedRecipe(product, materials); + CraftingManager.getInstance().getRecipeList().add(recipe); + return recipe; + } +} diff --git a/forestry_common/core/forestry/core/utils/StackMap.java b/forestry_common/core/forestry/core/utils/StackMap.java new file mode 100755 index 000000000..c32290157 --- /dev/null +++ b/forestry_common/core/forestry/core/utils/StackMap.java @@ -0,0 +1,74 @@ +/******************************************************************************* + * Copyright 2011-2014 by SirSengir + * + * This work is licensed under a Creative Commons Attribution-NonCommercial-NoDerivs 3.0 Unported License. + * + * To view a copy of this license, visit http://creativecommons.org/licenses/by-nc-nd/3.0/. + ******************************************************************************/ +package forestry.core.utils; + +import java.util.HashMap; +import java.util.Map; + + +/** + * Map for fluids and items. Can add things like ore dictionary strings etc. + * @author Alex Binnie + * + * @param The thing this map maps onto + * @param

The stack class (i.e. ItemStack, FluidStack) used for lookups + */ +public abstract class StackMap extends HashMap{ + + @Override + public final T put(Object key, T value) { + if(isValidKey(key) && key != null && value != null) + return super.put(key, value); + return null; + } + + private static final long serialVersionUID = 5383477742290646466L; + + @Override + public final boolean containsKey(Object key) { + P stack = getStack(key); + if(stack == null) return false; + for (Map.Entry entry : this.entrySet()) + if (areEqual(stack, entry.getKey())) + return true; + return super.containsKey(key); + } + + @Override + public final T get(Object key) { + P stack = getStack(key); + if(stack == null) return null; + for (Map.Entry entry : this.entrySet()) + if (areEqual(stack, entry.getKey())) + return entry.getValue(); + return super.get(key); + } + + /** + * Is a, the key used to lookup, equivelant to the key b + * @param a + * @param b + * @return + */ + protected abstract boolean areEqual(P a, Object b); + + /** + * Can this key be added to the map + * @param key + * @return + */ + protected abstract boolean isValidKey(Object key); + + /** + * Converts a key used to lookup something into P (ItemStack or FluidStack) + * @param key + * @return + */ + protected abstract P getStack(Object key); + +} diff --git a/forestry_common/core/forestry/core/utils/StackUtils.java b/forestry_common/core/forestry/core/utils/StackUtils.java new file mode 100755 index 000000000..8cc0426a5 --- /dev/null +++ b/forestry_common/core/forestry/core/utils/StackUtils.java @@ -0,0 +1,431 @@ +/******************************************************************************* + * Copyright 2011-2014 by SirSengir + * + * This work is licensed under a Creative Commons Attribution-NonCommercial-NoDerivs 3.0 Unported License. + * + * To view a copy of this license, visit http://creativecommons.org/licenses/by-nc-nd/3.0/. + ******************************************************************************/ +package forestry.core.utils; + +import java.util.ArrayList; +import java.util.Random; + +import net.minecraft.block.Block; +import net.minecraft.entity.item.EntityItem; +import net.minecraft.entity.player.EntityPlayer; +import net.minecraft.inventory.IInventory; +import net.minecraft.item.Item; +import net.minecraft.item.ItemBlock; +import net.minecraft.item.ItemStack; +import net.minecraft.nbt.NBTTagCompound; +import net.minecraft.world.World; + +import net.minecraftforge.common.MinecraftForge; +import net.minecraftforge.event.entity.player.PlayerDestroyItemEvent; +import net.minecraftforge.fluids.FluidContainerRegistry.FluidContainerData; +import net.minecraftforge.oredict.OreDictionary; + +import forestry.core.config.Defaults; +import forestry.core.gadgets.TileForestry; + +public class StackUtils { + + public static final ItemStack[] EMPTY_STACK_ARRAY = new ItemStack[0]; + public static final ArrayList EMPTY_STACK_LIST = new ArrayList(); + + /** + * Compares item id, damage and NBT. Accepts wildcard damage. + * + * @param lhs + * @param rhs + * @return + */ + public static boolean isIdenticalItem(ItemStack lhs, ItemStack rhs) { + if (lhs == null || rhs == null) + return false; + + if (lhs.getItem() != rhs.getItem()) + return false; + + if (lhs.getItemDamage() != Defaults.WILDCARD) + if (lhs.getItemDamage() != rhs.getItemDamage()) + return false; + + return ItemStack.areItemStackTagsEqual(lhs, rhs); + } + + public static boolean stowInInventory(ItemStack itemstack, IInventory inventory, boolean doAdd) { + return stowInInventory(itemstack, inventory, doAdd, 0, inventory.getSizeInventory()); + } + + public static boolean stowInInventory(ItemStack itemstack, IInventory inventory, boolean doAdd, int slot1, int count) { + + boolean added = false; + + for (int i = slot1; i < slot1 + count; i++) { + ItemStack inventoryStack = inventory.getStackInSlot(i); + + // Grab those free slots + if (inventoryStack == null) { + if (doAdd) { + inventory.setInventorySlotContents(i, itemstack.copy()); + itemstack.stackSize = 0; + } + return true; + } + + // Already full + if (inventoryStack.stackSize >= inventoryStack.getMaxStackSize()) + continue; + + // Not same type + if (!inventoryStack.isItemEqual(itemstack)) + continue; + if (!ItemStack.areItemStackTagsEqual(inventoryStack, itemstack)) + continue; + + int space = inventoryStack.getMaxStackSize() - inventoryStack.stackSize; + + // Enough space to add all + if (space > itemstack.stackSize) { + if (doAdd) { + inventoryStack.stackSize += itemstack.stackSize; + itemstack.stackSize = 0; + } + return true; + // Only part can be added + } else { + if (doAdd) { + inventoryStack.stackSize = inventoryStack.getMaxStackSize(); + itemstack.stackSize -= space; + } + added = true; + } + + } + + return added; + + } + + public static int addToInventory(ItemStack itemstack, IInventory inventory, boolean doAdd, int slot1, int count) { + + int added = 0; + + for (int i = slot1; i < slot1 + count; i++) { + ItemStack inventoryStack = inventory.getStackInSlot(i); + + // Grab those free slots + if (inventoryStack == null) { + if (doAdd) + inventory.setInventorySlotContents(i, itemstack.copy()); + return itemstack.stackSize; + } + + // Already full + if (inventoryStack.stackSize >= inventoryStack.getMaxStackSize()) + continue; + + // Not same type + if (!inventoryStack.isItemEqual(itemstack)) + continue; + + int space = inventoryStack.getMaxStackSize() - inventoryStack.stackSize; + + // Enough space to add all + if (space > itemstack.stackSize - added) { + if (doAdd) + inventoryStack.stackSize += itemstack.stackSize; + return itemstack.stackSize; + // Only part can be added + } else { + if (doAdd) + inventoryStack.stackSize = inventoryStack.getMaxStackSize(); + added += space; + } + + } + + return added; + + } + + /** + * Merges the giving stack into the receiving stack as far as possible + * + * @param giver + * @param receptor + */ + public static void mergeStacks(ItemStack giver, ItemStack receptor) { + if (receptor.stackSize >= 64) + return; + + if (!receptor.isItemEqual(giver)) + return; + + if (giver.stackSize <= (receptor.getMaxStackSize() - receptor.stackSize)) { + receptor.stackSize += giver.stackSize; + giver.stackSize = 0; + return; + } + + ItemStack temp = giver.splitStack(receptor.getMaxStackSize() - receptor.stackSize); + receptor.stackSize += temp.stackSize; + temp.stackSize = 0; + return; + } + + public static boolean freeSpaceInStack(ItemStack stack, int maxSize) { + if (stack == null) + return true; + + if (stack.stackSize >= maxSize) + return false; + + return true; + } + + /** + * Creates a split stack of the specified amount, preserving NBT data, + * without decreasing the source stack. + * + * @param stack + * @param i + * @return + */ + public static ItemStack createSplitStack(ItemStack stack, int amount) { + ItemStack split = new ItemStack(stack.getItem(), amount, stack.getItemDamage()); + if (stack.getTagCompound() != null) { + NBTTagCompound nbttagcompound = (NBTTagCompound) stack.getTagCompound().copy(); + split.setTagCompound(nbttagcompound); + } + return split; + } + + public static ItemStack[] condenseStacks(ItemStack[] stacks) { + return condenseStacks(stacks, -1, false); + } + + /** + * + * @param stacks + * @param maxCountedPerStack The maximum stacksize counted in a single + * stack. -1 for unlimited. + * @return + */ + public static ItemStack[] condenseStacks(ItemStack[] stacks, int maxCountedPerStack, boolean craftingEquivalency) { + ArrayList condensed = new ArrayList(); + + for (ItemStack stack : stacks) { + if (stack == null) + continue; + if (stack.stackSize <= 0) + continue; + + boolean matched = false; + for (ItemStack cached : condensed) { + if (cached.isItemEqual(stack) + || (craftingEquivalency && isCraftingEquivalent(cached, stack, true, false))) { + cached.stackSize += maxCountedPerStack > 0 && stack.stackSize > maxCountedPerStack ? maxCountedPerStack : stack.stackSize; + matched = true; + } + } + + if (!matched) { + ItemStack cached = stack.copy(); + if (maxCountedPerStack > 0) + cached.stackSize = maxCountedPerStack; + condensed.add(cached); + } + + } + + return condensed.toArray(EMPTY_STACK_ARRAY); + } + + /** + * Counts how many full sets are contained in the passed stock + * + * @param set + * @param stock + * @return + */ + public static int containsSets(ItemStack[] set, ItemStack[] stock) { + return containsSets(set, stock, null, false, false); + } + + /** + * Counts how many full sets are contained in the passed stock + * + * @param set + * @param stock + * @return + */ + public static int containsSets(ItemStack[] set, ItemStack[] stock, ItemStack exclude, boolean oreDictionary, boolean craftingTools) { + int count = 0; + + ItemStack[] condensedRequired = StackUtils.condenseStacks(set); + ItemStack[] condensedOffered = StackUtils.condenseStacks(stock, -1, oreDictionary); + + for (ItemStack req : condensedRequired) { + + boolean matched = false; + for (ItemStack offer : condensedOffered) { + + if (exclude != null && isIdenticalItem(offer, exclude)) + continue; + + if (isCraftingEquivalent(req, offer, oreDictionary, craftingTools)) { + matched = true; + + int stackCount = (int) Math.floor(offer.stackSize / req.stackSize); + if (stackCount <= 0) + return 0; + else if (count == 0) + count = stackCount; + else if (count > stackCount) + count = stackCount; + } + } + if (!matched) + return 0; + } + + return count; + } + + /** + * Compare two item stacks for crafting equivalency. + * + * @param base + * @param comparison + * @param oreDictionary + * @return + */ + public static boolean isCraftingEquivalent(ItemStack base, ItemStack comparison, boolean oreDictionary, boolean craftingTools) { + if (isIdenticalItem(base, comparison)) + return true; + + if (oreDictionary) { + int idBase = OreDictionary.getOreID(base); + if (idBase >= 0) { + for (ItemStack itemstack : OreDictionary.getOres(idBase)) { + if (comparison.getItem() == itemstack.getItem() && (itemstack.getItemDamage() == OreDictionary.WILDCARD_VALUE || comparison.getItemDamage() == itemstack.getItemDamage())) + return true; + } + } + } + + if (craftingTools) { + return isThisCraftingTool(base, comparison); + } + + return false; + } + + public static boolean isCraftingTool(ItemStack itemstack) { + return itemstack.getItem().hasContainerItem(itemstack) + && itemstack.getItem().isDamageable() + && !itemstack.getItem().doesContainerItemLeaveCraftingGrid(itemstack); + } + + public static boolean isThisCraftingTool(ItemStack phantom, ItemStack actual) { + return isCraftingTool(phantom) && phantom.getItem() == actual.getItem(); + } + + public static void stowContainerItem(ItemStack itemstack, InventoryAdapter stowing, int slotIndex, EntityPlayer player) { + if (!itemstack.getItem().hasContainerItem(itemstack)) + return; + + ItemStack container = itemstack.getItem().getContainerItem(itemstack); + + if (container.isItemStackDamageable() && container.getItemDamage() > container.getMaxDamage()) { + MinecraftForge.EVENT_BUS.post(new PlayerDestroyItemEvent(player, container)); + container = null; + } + + if (container != null) { + + if (itemstack.getItem().doesContainerItemLeaveCraftingGrid(itemstack)) { + if (!stowing.tryAddStack(container, true)) + if (!player.inventory.addItemStackToInventory(container)) + player.dropPlayerItemWithRandomChoice(container, true); + } else { + if (!stowing.tryAddStack(container, slotIndex, 1, true)) + if (!stowing.tryAddStack(container, true)) + player.dropPlayerItemWithRandomChoice(container, true); + } + } + } + + public static void dropItemStackAsEntity(ItemStack items, World world, double x, double y, double z) { + if (items.stackSize <= 0) + return; + + float f1 = 0.7F; + double d = (world.rand.nextFloat() * f1) + (1.0F - f1) * 0.5D; + double d1 = (world.rand.nextFloat() * f1) + (1.0F - f1) * 0.5D; + double d2 = (world.rand.nextFloat() * f1) + (1.0F - f1) * 0.5D; + EntityItem entityitem = new EntityItem(world, x + d, y + d1, z + d2, items); + entityitem.delayBeforeCanPickup = 10; + + world.spawnEntityInWorld(entityitem); + + } + + public static void replenishByContainer(TileForestry tile, ItemStack inventoryStack, ForestryTank tank) { + FluidContainerData container = LiquidHelper.getLiquidContainer(inventoryStack); + replenishByContainer(tile, inventoryStack, container, tank); + } + + public static ItemStack replenishByContainer(TileForestry tile, ItemStack inventoryStack, FluidContainerData container, ForestryTank tank) { + if (container == null) + return inventoryStack; + + if (tank.fill(container.fluid, false) >= container.fluid.amount) { + tank.fill(container.fluid, true); + if (container.filledContainer != null && container.filledContainer.getItem().hasContainerItem(container.filledContainer)) + inventoryStack = container.emptyContainer.copy(); + else + inventoryStack.stackSize--; + tile.sendNetworkUpdate(); + } + + return inventoryStack; + } + + public static ItemStack copyWithRandomSize(ItemStack template, int max, Random rand) { + int size = rand.nextInt(max); + ItemStack created = template.copy(); + created.stackSize = size <= 0 ? 1 : size > created.getMaxStackSize() ? created.getMaxStackSize() : size; + return created; + } + + public static ItemStack consumeItem(ItemStack stack) { + if (stack.stackSize == 1) { + if (stack.getItem().hasContainerItem(stack)) { + return stack.getItem().getContainerItem(stack); + } else { + return null; + } + } else { + stack.splitStack(1); + + return stack; + } + } + + public static Block getBlock(ItemStack stack) { + Item item = stack.getItem(); + + if (item instanceof ItemBlock) { + return ((ItemBlock) item).field_150939_a; + } else { + return null; + } + } + + public static boolean equals(Block block, ItemStack stack) { + return block == getBlock(stack); + } +} diff --git a/forestry_common/core/forestry/core/utils/StringUtil.java b/forestry_common/core/forestry/core/utils/StringUtil.java new file mode 100755 index 000000000..1fe6a653a --- /dev/null +++ b/forestry_common/core/forestry/core/utils/StringUtil.java @@ -0,0 +1,46 @@ +/******************************************************************************* + * Copyright 2011-2014 by SirSengir + * + * This work is licensed under a Creative Commons Attribution-NonCommercial-NoDerivs 3.0 Unported License. + * + * To view a copy of this license, visit http://creativecommons.org/licenses/by-nc-nd/3.0/. + ******************************************************************************/ +package forestry.core.utils; + +public class StringUtil { + + public static String localize(String key) { + return Localization.instance.get(key); + } + + public static String localizeAndFormat(String key, Object... args) { + return String.format(Localization.instance.get(key), args); + } + + public static String capitalize(String s) { + if (s.length() == 0) + return s; + return s.substring(0, 1).toUpperCase() + s.substring(1).toLowerCase(); + } + + public static String append(String delim, String source, String appendix) { + if (source.length() <= 0) + return appendix; + + if (appendix.length() <= 0) + return source; + + return source + delim + appendix; + } + + public static String readableBoolean(boolean flag, String trueStr, String falseStr) { + if (flag) + return trueStr; + else + return falseStr; + } + + public static String floatAsPercent(float val) { + return (int) (val * 100) + " %"; + } +} diff --git a/forestry_common/core/forestry/core/utils/TileInventoryAdapter.java b/forestry_common/core/forestry/core/utils/TileInventoryAdapter.java new file mode 100755 index 000000000..086a2f9e8 --- /dev/null +++ b/forestry_common/core/forestry/core/utils/TileInventoryAdapter.java @@ -0,0 +1,38 @@ +/******************************************************************************* + * Copyright 2011-2014 by SirSengir + * + * This work is licensed under a Creative Commons Attribution-NonCommercial-NoDerivs 3.0 Unported License. + * + * To view a copy of this license, visit http://creativecommons.org/licenses/by-nc-nd/3.0/. + ******************************************************************************/ +package forestry.core.utils; + +import net.minecraft.entity.player.EntityPlayer; + +import forestry.core.gadgets.TileForestry; + +public class TileInventoryAdapter extends InventoryAdapter { + + TileForestry tile; + + public TileInventoryAdapter(TileForestry tile, int size, String name) { + super(size, name); + this.tile = tile; + } + + public TileInventoryAdapter(TileForestry tile, int size, String name, int stackLimit) { + super(size, name, stackLimit); + this.tile = tile; + } + + @Override + public boolean isUseableByPlayer(EntityPlayer entityplayer) { + return tile.isUseableByPlayer(entityplayer); + } + + @Override + public void markDirty() { + super.markDirty(); + tile.markDirty(); + } +} diff --git a/forestry_common/core/forestry/core/utils/Utils.java b/forestry_common/core/forestry/core/utils/Utils.java new file mode 100755 index 000000000..d0634dc56 --- /dev/null +++ b/forestry_common/core/forestry/core/utils/Utils.java @@ -0,0 +1,410 @@ +/******************************************************************************* + * Copyright 2011-2014 by SirSengir + * + * This work is licensed under a Creative Commons Attribution-NonCommercial-NoDerivs 3.0 Unported License. + * + * To view a copy of this license, visit http://creativecommons.org/licenses/by-nc-nd/3.0/. + ******************************************************************************/ +package forestry.core.utils; + +import java.security.MessageDigest; +import java.security.cert.Certificate; +import java.util.Arrays; +import java.util.Iterator; +import java.util.Map; +import java.util.Random; + +import net.minecraft.block.Block; +import net.minecraft.entity.Entity; +import net.minecraft.entity.EntityList; +import net.minecraft.entity.EntityLiving; +import net.minecraft.entity.IEntityLivingData; +import net.minecraft.entity.item.EntityItem; +import net.minecraft.entity.player.EntityPlayer; +import net.minecraft.init.Blocks; +import net.minecraft.inventory.IInventory; +import net.minecraft.inventory.InventoryLargeChest; +import net.minecraft.item.ItemStack; +import net.minecraft.server.MinecraftServer; +import net.minecraft.tileentity.TileEntity; +import net.minecraft.tileentity.TileEntityChest; +import net.minecraft.util.ChatComponentText; +import net.minecraft.util.ChunkCoordinates; +import net.minecraft.util.IChatComponent; +import net.minecraft.util.MathHelper; +import net.minecraft.world.World; +import net.minecraft.world.biome.BiomeGenBase; + +import cpw.mods.fml.common.registry.EntityRegistry; + +import buildcraft.api.tools.IToolWrench; +import com.mojang.authlib.GameProfile; + +import forestry.api.arboriculture.EnumGermlingType; +import forestry.api.arboriculture.ITree; +import forestry.api.core.ForestryAPI; +import forestry.api.core.IArmorNaturalist; +import forestry.api.core.ITileStructure; +import forestry.api.genetics.AlleleManager; +import forestry.api.genetics.IIndividual; +import forestry.api.genetics.IPollinatable; +import forestry.core.config.Config; +import forestry.core.gadgets.TileForestry; +import forestry.core.proxy.Proxies; +import forestry.plugins.PluginArboriculture; + +public class Utils { + + private static EntityPlayer modPlayer; + + public static EntityPlayer getForestryPlayer(World world, int x, int y, int z) { + if (modPlayer == null) { + modPlayer = new EntityPlayer(world, new GameProfile(Config.fakeUserLogin, Config.fakeUserLogin)) { + @Override + public boolean canCommandSenderUseCommand(int var1, String var2) { + return false; + } + + @Override + public ChunkCoordinates getPlayerCoordinates() { + return null; + } + + @Override + public void addChatMessage(IChatComponent var1) { + } + }; + modPlayer.posX = x; + modPlayer.posY = y; + modPlayer.posZ = z; + Proxies.log.info("Created player '%s' for Forestry.", modPlayer.getGameProfile().getId()); + if (Config.fakeUserAutoop) { + MinecraftServer.getServer().getConfigurationManager().addOp(modPlayer.getGameProfile().getId()); + Proxies.log.info("Opped player '%s'.", modPlayer.getGameProfile().getId()); + } + } + + return modPlayer; + } + private static Random rand; + + public static int getUID() { + if (rand == null) + rand = new Random(); + + int uid = rand.nextInt(); + return uid; + } + + public static void dropInventory(TileForestry tile, World world, int x, int y, int z) { + if (tile == null) + return; + + // Release inventory + if (tile instanceof ITileStructure) { + + IInventory inventory = ((ITileStructure) tile).getInventory(); + if (inventory != null) + for (int i = 0; i < inventory.getSizeInventory(); i++) { + if (inventory.getStackInSlot(i) == null) + continue; + + StackUtils.dropItemStackAsEntity(inventory.getStackInSlot(i), world, x, y, z); + inventory.setInventorySlotContents(i, null); + } + + } else { + + IInventory inventory; + if (tile instanceof IInventory) + inventory = (IInventory) tile; + else + inventory = tile.getInternalInventory(); + + if (inventory != null) { + for (int slot = 0; slot < inventory.getSizeInventory(); slot++) { + + ItemStack itemstack = inventory.getStackInSlot(slot); + + if (itemstack == null) + continue; + + float f = world.rand.nextFloat() * 0.8F + 0.1F; + float f1 = world.rand.nextFloat() * 0.8F + 0.1F; + float f2 = world.rand.nextFloat() * 0.8F + 0.1F; + + while (itemstack.stackSize > 0) { + + int stackPartial = world.rand.nextInt(21) + 10; + if (stackPartial > itemstack.stackSize) + stackPartial = itemstack.stackSize; + ItemStack drop = itemstack.splitStack(stackPartial); + EntityItem entityitem = new EntityItem(world, x + f, y + f1, z + f2, drop); + float accel = 0.05F; + entityitem.motionX = (float) world.rand.nextGaussian() * accel; + entityitem.motionY = (float) world.rand.nextGaussian() * accel + 0.2F; + entityitem.motionZ = (float) world.rand.nextGaussian() * accel; + world.spawnEntityInWorld(entityitem); + + } + + inventory.setInventorySlotContents(slot, null); + } + } + } + + } + + public static boolean hasNaturalistEye(EntityPlayer player) { + ItemStack armorItem = player.inventory.armorInventory[3]; + return armorItem != null && armorItem.getItem() instanceof IArmorNaturalist + && ((IArmorNaturalist) armorItem.getItem()).canSeePollination(player, armorItem, true); + } + + @SuppressWarnings("rawtypes") + public static void broadcastMessage(World world, String message) { + for (Iterator iterator = world.playerEntities.iterator(); iterator.hasNext();) { + EntityPlayer entityplayer = (EntityPlayer) iterator.next(); + entityplayer.addChatMessage(new ChatComponentText(message)); + } + } + + public static IInventory getChest(IInventory inventory) { + if (!(inventory instanceof TileEntityChest)) + return inventory; + + TileEntityChest chest = (TileEntityChest) inventory; + + Vect[] adjacent = new Vect[] { new Vect(chest.xCoord + 1, chest.yCoord, chest.zCoord), new Vect(chest.xCoord - 1, chest.yCoord, chest.zCoord), + new Vect(chest.xCoord, chest.yCoord, chest.zCoord + 1), new Vect(chest.xCoord, chest.yCoord, chest.zCoord - 1) }; + + for (Vect pos : adjacent) { + TileEntity otherchest = chest.getWorldObj().getTileEntity(pos.x, pos.y, pos.z); + if (otherchest instanceof TileEntityChest) + return new InventoryLargeChest("", chest, (TileEntityChest) otherchest); + } + + return inventory; + } + + public static T[] concat(T[] first, T[] second) { + T[] result = Arrays.copyOf(first, first.length + second.length); + System.arraycopy(second, 0, result, first.length, second.length); + return result; + } + + public static int[] concat(int[] first, int[] second) { + int[] result = Arrays.copyOf(first, first.length + second.length); + System.arraycopy(second, 0, result, first.length, second.length); + return result; + } + + public static short[] concat(short[] first, short[] second) { + short[] result = Arrays.copyOf(first, first.length + second.length); + System.arraycopy(second, 0, result, first.length, second.length); + return result; + } + + public static float[] concat(float[] first, float[] second) { + float[] result = Arrays.copyOf(first, first.length + second.length); + System.arraycopy(second, 0, result, first.length, second.length); + return result; + } + + public static boolean canWrench(EntityPlayer player, int x, int y, int z) { + + ItemStack itemstack = player.getCurrentEquippedItem(); + if (itemstack == null) + return false; + + if (!(itemstack.getItem() instanceof IToolWrench)) + return false; + + IToolWrench wrench = (IToolWrench) itemstack.getItem(); + if (!wrench.canWrench(player, x, y, z)) + return false; + + return true; + } + + public static void useWrench(EntityPlayer player, int x, int y, int z) { + ItemStack itemstack = player.getCurrentEquippedItem(); + + if (itemstack == null) + return; + + if (!(itemstack.getItem() instanceof IToolWrench)) + return; + + ((IToolWrench) itemstack.getItem()).wrenchUsed(player, x, y, z); + } + + public static EnumTankLevel rateTankLevel(int scaled) { + + if (scaled < 5) + return EnumTankLevel.EMPTY; + else if (scaled < 30) + return EnumTankLevel.LOW; + else if (scaled < 60) + return EnumTankLevel.MEDIUM; + else if (scaled < 90) + return EnumTankLevel.HIGH; + else + return EnumTankLevel.MAXIMUM; + } + + public static boolean isReplaceableBlock(World world, int x, int y, int z) { + Block block = world.getBlock(x, y, z); + + return block == Blocks.vine || block == Blocks.tallgrass || block == Blocks.deadbush || block == Blocks.snow_layer + || block.isReplaceable(world, x, y, z); + } + + public static boolean isLiquidBlock(World world, int x, int y, int z) { + return isLiquidBlock(world.getBlock(x, y, z)); + } + + public static boolean isLiquidBlock(Block block) { + return block == Blocks.water || block == Blocks.flowing_water || block == Blocks.lava || block == Blocks.flowing_lava; + } + + public static boolean isUseableByPlayer(EntityPlayer player, TileEntity tile, World world, int x, int y, int z) { + if (world.getTileEntity(x, y, z) != tile) + return false; + + return player.getDistanceSq(x + 0.5D, y + 0.5D, z + 0.5D) <= 64.0D; + + } + + public static BiomeGenBase getBiomeAt(World world, int x, int z) { + return world.getBiomeGenForCoordsBody(x, z); + } + + public static Entity spawnEntity(World world, Class entityClass, double x, double y, double z) { + if (!EntityList.classToStringMapping.containsKey(entityClass)) + return null; + + return spawnEntity(world, EntityList.createEntityByName((String) EntityList.classToStringMapping.get(entityClass), world), x, y, z); + } + + public static Entity spawnEntity(World world, Entity spawn, double x, double y, double z) { + + if (spawn != null && spawn instanceof EntityLiving) { + + EntityLiving living = (EntityLiving) spawn; + spawn.setLocationAndAngles(x, y, z, MathHelper.wrapAngleTo180_float(world.rand.nextFloat() * 360.0f), 0.0f); + living.rotationYawHead = living.rotationYaw; + living.renderYawOffset = living.rotationYaw; + living.onSpawnWithEgg((IEntityLivingData) null); + world.spawnEntityInWorld(spawn); + living.playLivingSound(); + } + + return spawn; + } + + public static void registerEntity(Class entityClass, String ident, int id, int eggForeground, int eggBackground, int trackingRange, int updateFrequency, boolean sendVelocity) { + EntityRegistry.registerModEntity(entityClass, ident, id, ForestryAPI.instance, trackingRange, updateFrequency, sendVelocity); + Proxies.log.finer("Registered entity %s (%s) with id %s.", ident, entityClass.toString(), id); + } + + public static int addRGBComponents(int colour, int r, int g, int b) { + r = ((colour & 0xff0000) >> 16) + r; + g = ((colour & 0xff00) >> 8) + b; + b = ((colour & 0xff)) + b; + + r = r <= 255 ? r : 255; + g = g <= 255 ? g : 255; + b = b <= 255 ? b : 255; + + return ((r & 0x0ff) << 16) | ((g & 0x0ff) << 8) | (b & 0x0ff); + } + + public static int multiplyRGBComponents(int colour, float factor) { + int r = (int) (((colour & 0xff0000) >> 16) * factor); + int g = (int) (((colour & 0xff00) >> 8) * factor); + int b = (int) (((colour & 0xff)) * factor); + + r = r <= 255 ? r : 255; + g = g <= 255 ? g : 255; + b = b <= 255 ? b : 255; + + return ((r & 0x0ff) << 16) | ((g & 0x0ff) << 8) | (b & 0x0ff); + } + + public static String getFingerprint(Certificate certificate) { + if (certificate == null) + return "Certificate invalid"; + + try { + MessageDigest md = MessageDigest.getInstance("SHA-1"); + byte[] der = certificate.getEncoded(); + md.update(der); + byte[] digest = md.digest(); + return tohex(digest); + } catch (Exception ex) { + return null; + } + } + private static final String HEX = "0123456789abcdef"; + + private static String tohex(byte[] checksum) { + + final StringBuilder hex = new StringBuilder(2 * checksum.length); + for (byte bty : checksum) { + hex.append(HEX.charAt((bty & 0xf0) >> 4)).append(HEX.charAt((bty & 0x0f))); + } + return hex.toString(); + } + + public static ItemStack convertSaplingToGeneticEquivalent(ItemStack foreign) { + + ItemStack ersatz = null; + ITree tree = null; + + for (Map.Entry entry : AlleleManager.ersatzSaplings.entrySet()) { + if (entry.getKey().getItem() != foreign.getItem()) + continue; + if (entry.getKey().getItemDamage() != foreign.getItemDamage()) + continue; + + if (entry.getValue() instanceof ITree) + tree = (ITree) entry.getValue(); + + ersatz = PluginArboriculture.treeInterface.getMemberStack(tree, EnumGermlingType.SAPLING.ordinal()); + ersatz.stackSize = foreign.stackSize; + } + + return ersatz; + } + + public static IPollinatable getOrCreatePollinatable(String owner, World world, int x, int y, int z) { + TileEntity tile = world.getTileEntity(x, y, z); + + IPollinatable receiver = null; + if (tile instanceof IPollinatable) + receiver = (IPollinatable) tile; + else if (!world.isAirBlock(x, y, z)) { + + // Test for ersatz genomes + for (Map.Entry entry : AlleleManager.ersatzSpecimen.entrySet()) { + if (!StackUtils.equals(world.getBlock(x, y, z), entry.getKey())) + continue; + + int meta = world.getBlockMetadata(x, y, z); + if (StackUtils.equals(Blocks.leaves, entry.getKey())) + meta = meta & 3; + if (entry.getKey().getItemDamage() != meta) + continue; + + // We matched, replace the leaf block with ours and set the ersatz genome + PluginArboriculture.treeInterface.setLeaves(world, entry.getValue(), owner, x, y, z); + // Now let's pollinate + receiver = (IPollinatable) world.getTileEntity(x, y, z); + } + + } + + return receiver; + } +} diff --git a/forestry_common/core/forestry/core/utils/Vect.java b/forestry_common/core/forestry/core/utils/Vect.java new file mode 100755 index 000000000..91843b481 --- /dev/null +++ b/forestry_common/core/forestry/core/utils/Vect.java @@ -0,0 +1,81 @@ +/******************************************************************************* + * Copyright 2011-2014 by SirSengir + * + * This work is licensed under a Creative Commons Attribution-NonCommercial-NoDerivs 3.0 Unported License. + * + * To view a copy of this license, visit http://creativecommons.org/licenses/by-nc-nd/3.0/. + ******************************************************************************/ +package forestry.core.utils; + +/** + * Generic class to represent a position or dimensions. + */ +public class Vect { + public int x; + public int y; + public int z; + + public Vect(int[] dim) { + if (dim.length != 3) + throw new RuntimeException("Cannot instantiate a vector with less or more than 3 points."); + + this.x = dim[0]; + this.y = dim[1]; + this.z = dim[2]; + } + + public Vect(int x, int y, int z) { + this.x = x; + this.y = y; + this.z = z; + } + + public Vect add(Vect other) { + Vect result = new Vect(x, y, z); + result.x += other.x; + result.y += other.y; + result.z += other.z; + return result; + } + + public Vect multiply(float factor) { + Vect result = new Vect(x, y, z); + result.x *= factor; + result.y *= factor; + result.z *= factor; + return result; + } + + @Override + public String toString() { + return String.format("%sx%sx%s;", x, y, z); + } + + @Override + public int hashCode() { + final int prime = 31; + int result = 1; + result = prime * result + x; + result = prime * result + y; + result = prime * result + z; + return result; + } + + @Override + public boolean equals(Object obj) { + if (this == obj) + return true; + if (obj == null) + return false; + if (getClass() != obj.getClass()) + return false; + Vect other = (Vect) obj; + if (x != other.x) + return false; + if (y != other.y) + return false; + if (z != other.z) + return false; + return true; + } +} diff --git a/forestry_common/core/forestry/core/worldgen/BlockType.java b/forestry_common/core/forestry/core/worldgen/BlockType.java new file mode 100755 index 000000000..7fb817eaa --- /dev/null +++ b/forestry_common/core/forestry/core/worldgen/BlockType.java @@ -0,0 +1,31 @@ +/******************************************************************************* + * Copyright 2011-2014 by SirSengir + * + * This work is licensed under a Creative Commons Attribution-NonCommercial-NoDerivs 3.0 Unported License. + * + * To view a copy of this license, visit http://creativecommons.org/licenses/by-nc-nd/3.0/. + ******************************************************************************/ +package forestry.core.worldgen; + +import net.minecraft.block.Block; +import net.minecraft.world.World; + +import forestry.api.world.ITreeGenData; +import forestry.core.config.Defaults; + +public class BlockType { + + Block block; + int meta; + + public BlockType(Block block, int meta) { + this.block = block; + this.meta = meta; + } + + public void setBlock(World world, ITreeGenData tree, int x, int y, int z) { + world.setBlock(x, y, z, block, meta, Defaults.FLAG_BLOCK_SYNCH); + if (world.getTileEntity(x, y, z) != null) + world.removeTileEntity(x, y, z); + } +} diff --git a/forestry_common/core/forestry/core/worldgen/WorldGenBase.java b/forestry_common/core/forestry/core/worldgen/WorldGenBase.java new file mode 100755 index 000000000..8637203ad --- /dev/null +++ b/forestry_common/core/forestry/core/worldgen/WorldGenBase.java @@ -0,0 +1,117 @@ +/******************************************************************************* + * Copyright 2011-2014 by SirSengir + * + * This work is licensed under a Creative Commons Attribution-NonCommercial-NoDerivs 3.0 Unported License. + * + * To view a copy of this license, visit http://creativecommons.org/licenses/by-nc-nd/3.0/. + ******************************************************************************/ +package forestry.core.worldgen; + +import java.util.Random; + +import net.minecraft.world.World; +import net.minecraft.world.gen.feature.WorldGenerator; + +public abstract class WorldGenBase extends WorldGenerator { + + protected enum EnumReplaceMode { + + NONE, ALL, SOFT + } + + public static class Vector { + + public Vector(float f, float h, float g) { + this.x = f; + this.y = h; + this.z = g; + } + float x; + float y; + float z; + + public static double distance(Vector a, Vector b) { + return Math.sqrt(Math.pow(a.x - b.x, 2) + Math.pow(a.y - b.y, 2) + Math.pow(a.z - b.z, 2)); + } + } + protected World world; + protected Random rand; + + @Override + public final boolean generate(World world, Random random, int x, int y, int z) { + this.world = world; + this.rand = random; + boolean result = subGenerate(x, y, z); + this.world = null; + this.rand = null; + return result; + } + + public boolean subGenerate(int x, int y, int z) { + return false; + } + + protected abstract void addBlock(int x, int y, int z, BlockType type, EnumReplaceMode replace); + + protected final void generateCuboid(Vector start, Vector area, BlockType block, EnumReplaceMode replace) { + for (int x = (int) start.x; x < (int) start.x + area.x; x++) { + for (int y = (int) start.y; y < (int) start.y + area.y; y++) { + for (int z = (int) start.z; z < (int) start.z + area.z; z++) { + addBlock(x, y, z, block, replace); + } + } + } + } + + /* + * Center is the bottom middle of the cylinder + */ + protected final void generateCylinder(Vector center, float radius, int height, BlockType block, EnumReplaceMode replace) { + Vector start = new Vector(center.x - radius, center.y, center.z - radius); + Vector area = new Vector(radius * 2 + 1, height, radius * 2 + 1); + for (int x = (int) start.x; x < (int) start.x + area.x; x++) { + for (int y = (int) start.y; y < (int) start.y + area.y; y++) { + for (int z = (int) start.z; z < (int) start.z + area.z; z++) { + if (Vector.distance(new Vector(x, y, z), new Vector(center.x, y, center.z)) <= (radius) + 0.01) + addBlock(x, y, z, block, replace); + } + } + } + } + + protected final void generateCircle(Vector center, float radius, int width, int height, BlockType block, EnumReplaceMode replace) { + generateCircle(center, radius, width, height, block, 1.0f, replace); + } + + protected final void generateCircle(Vector center, float radius, int width, int height, BlockType block, float chance, EnumReplaceMode replace) { + Vector start = new Vector(center.x - radius, center.y, center.z - radius); + Vector area = new Vector(radius * 2 + 1, height, radius * 2 + 1); + + for (int x = (int) start.x; x < (int) start.x + area.x; x++) { + for (int y = (int) start.y; y < (int) start.y + area.y; y++) { + for (int z = (int) start.z; z < (int) start.z + area.z; z++) { + + if (rand.nextFloat() > chance) + continue; + + double distance = Vector.distance(new Vector(x, y, z), new Vector(center.x, y, center.z)); + if ((radius - width - 0.01 < distance && distance <= (radius) + 0.01)) + addBlock(x, y, z, block, replace); + } + } + } + } + + protected final void generateSphere(Vector center, int radius, BlockType block, EnumReplaceMode replace) { + Vector start = new Vector(center.x - radius, center.y - radius, center.z - radius); + Vector area = new Vector(radius * 2 + 1, radius * 2 + 1, radius * 2 + 1); + for (int x = (int) start.x; x < (int) start.x + area.x; x++) { + for (int y = (int) start.y; y < (int) start.y + area.y; y++) { + for (int z = (int) start.z; z < (int) start.z + area.z; z++) { + if (Vector.distance(new Vector(x, y, z), new Vector(center.x, center.y, center.z)) <= (radius) + 0.01) + addBlock(x, y, z, block, replace); + } + } + } + } +} diff --git a/forestry_common/core/forestry/core/worldgen/WorldGenMinableMeta.java b/forestry_common/core/forestry/core/worldgen/WorldGenMinableMeta.java new file mode 100755 index 000000000..4b35a2310 --- /dev/null +++ b/forestry_common/core/forestry/core/worldgen/WorldGenMinableMeta.java @@ -0,0 +1,83 @@ +/******************************************************************************* + * Copyright 2011-2014 by SirSengir + * + * This work is licensed under a Creative Commons Attribution-NonCommercial-NoDerivs 3.0 Unported License. + * + * To view a copy of this license, visit http://creativecommons.org/licenses/by-nc-nd/3.0/. + ******************************************************************************/ +package forestry.core.worldgen; + +import java.util.Random; + +import net.minecraft.block.Block; +import net.minecraft.init.Blocks; +import net.minecraft.util.MathHelper; +import net.minecraft.world.World; +import net.minecraft.world.gen.feature.WorldGenerator; + +import forestry.core.config.Defaults; + +public class WorldGenMinableMeta extends WorldGenerator { + + private final Block mineableBlock; + private final int mineableBlockMeta; + private final int numberOfBlocks; + + public WorldGenMinableMeta(Block block, int meta, int numberOfBlocks) { + mineableBlock = block; + mineableBlockMeta = meta; + this.numberOfBlocks = numberOfBlocks; + } + + @Override + public boolean generate(World world, Random random, int i, int j, int k) { + + boolean hasGenerated = false; + + float randomBase = random.nextFloat() * 3.141593F; + double d = (i + 8) + (MathHelper.sin(randomBase) * numberOfBlocks) / 8F; + double d1 = (i + 8) - (MathHelper.sin(randomBase) * numberOfBlocks) / 8F; + double d2 = (k + 8) + (MathHelper.cos(randomBase) * numberOfBlocks) / 8F; + double d3 = (k + 8) - (MathHelper.cos(randomBase) * numberOfBlocks) / 8F; + double d4 = (j + random.nextInt(3)) - 2; + double d5 = (j + random.nextInt(3)) - 2; + + for (int l = 0; l <= numberOfBlocks; l++) { + double d6 = d + ((d1 - d) * l) / numberOfBlocks; + double d7 = d4 + ((d5 - d4) * l) / numberOfBlocks; + double d8 = d2 + ((d3 - d2) * l) / numberOfBlocks; + double d9 = (random.nextDouble() * numberOfBlocks) / 16D; + double d10 = (MathHelper.sin((l * 3.141593F) / numberOfBlocks) + 1.0F) * d9 + 1.0D; + double d11 = (MathHelper.sin((l * 3.141593F) / numberOfBlocks) + 1.0F) * d9 + 1.0D; + int xStart = MathHelper.floor_double(d6 - d10 / 2D); + int yStart = MathHelper.floor_double(d7 - d11 / 2D); + int zStart = MathHelper.floor_double(d8 - d10 / 2D); + int xEnd = MathHelper.floor_double(d6 + d10 / 2D); + int yEnd = MathHelper.floor_double(d7 + d11 / 2D); + int zEnd = MathHelper.floor_double(d8 + d10 / 2D); + + for (int targetX = xStart; targetX <= xEnd; targetX++) { + double d12 = ((targetX + 0.5D) - d6) / (d10 / 2D); + if (d12 * d12 >= 1.0D) + continue; + + for (int targetY = yStart; targetY <= yEnd; targetY++) { + double d13 = ((targetY + 0.5D) - d7) / (d11 / 2D); + if (d12 * d12 + d13 * d13 >= 1.0D) + continue; + + for (int targetZ = zStart; targetZ <= zEnd; targetZ++) { + double d14 = ((targetZ + 0.5D) - d8) / (d10 / 2D); + if (d12 * d12 + d13 * d13 + d14 * d14 < 1.0D && world.getBlock(targetX, targetY, targetZ) == Blocks.stone) { + world.setBlock(targetX, targetY, targetZ, mineableBlock, mineableBlockMeta, Defaults.FLAG_BLOCK_SYNCH); + hasGenerated = true; + } + } + } + } + } + + return hasGenerated; + } + +} diff --git a/forestry_common/core/forestry/plugins/NativePlugin.java b/forestry_common/core/forestry/plugins/NativePlugin.java new file mode 100755 index 000000000..6d78e510c --- /dev/null +++ b/forestry_common/core/forestry/plugins/NativePlugin.java @@ -0,0 +1,86 @@ +/******************************************************************************* + * Copyright 2011-2014 by SirSengir + * + * This work is licensed under a Creative Commons Attribution-NonCommercial-NoDerivs 3.0 Unported License. + * + * To view a copy of this license, visit http://creativecommons.org/licenses/by-nc-nd/3.0/. + ******************************************************************************/ +package forestry.plugins; + +import java.util.Random; + +import net.minecraft.command.ICommand; +import net.minecraft.world.World; + +import cpw.mods.fml.common.event.FMLInterModComms.IMCMessage; +import cpw.mods.fml.common.network.IGuiHandler; + +import forestry.api.core.IPlugin; +import forestry.core.interfaces.IOreDictionaryHandler; +import forestry.core.interfaces.IPacketHandler; +import forestry.core.interfaces.IPickupHandler; +import forestry.core.interfaces.IResupplyHandler; +import forestry.core.interfaces.ISaveEventHandler; + +public abstract class NativePlugin implements IPlugin { + + @Override + public void preInit() { + registerItems(); + } + + @Override + public void doInit() { + registerBackpackItems(); + registerCrates(); + } + + @Override + public void postInit() { + registerRecipes(); + } + + public boolean processIMCMessage(IMCMessage message) { + return false; + } + + public IGuiHandler getGuiHandler() { + return null; + } + + public ISaveEventHandler getSaveEventHandler() { + return null; + } + + public IOreDictionaryHandler getDictionaryHandler() { + return null; + } + + public void generateSurface(World world, Random rand, int chunkX, int chunkZ) { + } + + public IPacketHandler getPacketHandler() { + return null; + } + + public IPickupHandler getPickupHandler() { + return null; + } + + public IResupplyHandler getResupplyHandler() { + return null; + } + + public ICommand[] getConsoleCommands() { + return null; + } + + protected abstract void registerItems(); + + protected abstract void registerBackpackItems(); + + protected abstract void registerCrates(); + + protected abstract void registerRecipes(); + +} diff --git a/forestry_common/core/forestry/plugins/PluginBuildCraft.java b/forestry_common/core/forestry/plugins/PluginBuildCraft.java new file mode 100755 index 000000000..d95e36654 --- /dev/null +++ b/forestry_common/core/forestry/plugins/PluginBuildCraft.java @@ -0,0 +1,159 @@ +/******************************************************************************* + * Copyright 2011-2014 by SirSengir + * + * This work is licensed under a Creative Commons Attribution-NonCommercial-NoDerivs 3.0 Unported License. + * + * To view a copy of this license, visit http://creativecommons.org/licenses/by-nc-nd/3.0/. + ******************************************************************************/ +package forestry.plugins; + +import java.util.LinkedList; + +import net.minecraft.block.Block; +import net.minecraft.item.Item; +import net.minecraft.item.ItemStack; +import net.minecraft.tileentity.TileEntity; + +import net.minecraftforge.common.util.ForgeDirection; +import net.minecraftforge.fluids.Fluid; +import net.minecraftforge.fluids.FluidStack; + +import buildcraft.api.fuels.IronEngineCoolant; +import buildcraft.api.fuels.IronEngineFuel; +import buildcraft.api.gates.ActionManager; +import buildcraft.api.gates.ITrigger; +import buildcraft.api.gates.ITriggerProvider; +import buildcraft.api.power.PowerHandler; +import buildcraft.api.power.PowerHandler.PowerReceiver; +import buildcraft.api.recipes.BuildcraftRecipes; +import buildcraft.api.transport.IPipeTile; + +import forestry.api.core.IPlugin; +import forestry.api.core.PluginInfo; +import forestry.core.GameMode; +import forestry.core.config.Config; +import forestry.core.config.Configuration; +import forestry.core.config.Defaults; +import forestry.core.config.ForestryItem; +import forestry.core.config.Property; +import forestry.core.gadgets.TileForestry; +import forestry.core.proxy.Proxies; +import forestry.core.utils.LiquidHelper; + +@PluginInfo(pluginID = "BC3", name = "BuildCraft 3", author = "SirSengir", url = Defaults.URL, description = "Compatibility plugin for BuildCraft 3.") +public class PluginBuildCraft implements IPlugin, ITriggerProvider { + + public static PluginBuildCraft instance; + public static Configuration config; + // Ignore Buildcraft? + public static boolean ignore; + public static Item wrench; + public static Item stoneGear; + public static Item pipeWaterproof; + + public PluginBuildCraft() { + if (PluginBuildCraft.instance == null) + PluginBuildCraft.instance = this; + } + + /** + * @return true if BuildCraftCore is installed. + */ + @Override + public boolean isAvailable() { + return (Proxies.common.isModLoaded("BuildCraft|Core") && Proxies.common.isModLoaded("BuildCraft|Transport")); + } + + @Override + public void doInit() { + config = Config.config; + + Property buildcraftignore = config.get("buildcraft.ignore", Config.CATEGORY_COMMON, false); + buildcraftignore.Comment = "set to true to ignore buildcraft"; + PluginBuildCraft.ignore = Boolean.parseBoolean(buildcraftignore.Value); + + IronEngineCoolant.addCoolant(LiquidHelper.getLiquid(Defaults.LIQUID_ICE, 1).getFluid(), 10.0f); + + addIronEngineFuel(LiquidHelper.getLiquid(Defaults.LIQUID_ETHANOL, 1).getFluid(), 4, + Defaults.ENGINE_CYCLE_DURATION_ETHANOL * GameMode.getGameMode().getFloatSetting("fuel.ethanol.combustion")); + + // Add recipe for ethanol + addRefineryRecipe(LiquidHelper.getLiquid(Defaults.LIQUID_BIOMASS, 4), null, LiquidHelper.getLiquid(Defaults.LIQUID_ETHANOL, 1), 10, 1); + + // Add custom trigger handler + ActionManager.registerTriggerProvider(this); + + initStoneGear(); + initWaterproof(); + initLiquids(); + } + + @Override + public void postInit() { + } + + private void initLiquids() { + LiquidHelper.injectWaxContainer(Defaults.LIQUID_OIL, Defaults.BUCKET_VOLUME, ForestryItem.waxCapsuleOil.getItemStack(), ForestryItem.waxCapsule.getItemStack()); + LiquidHelper.injectWaxContainer(Defaults.LIQUID_FUEL, Defaults.BUCKET_VOLUME, ForestryItem.waxCapsuleFuel.getItemStack(), ForestryItem.waxCapsule.getItemStack()); + LiquidHelper.injectRefractoryContainer(Defaults.LIQUID_OIL, Defaults.BUCKET_VOLUME, ForestryItem.refractoryOil.getItemStack(), ForestryItem.refractoryEmpty.getItemStack()); + LiquidHelper.injectRefractoryContainer(Defaults.LIQUID_FUEL, Defaults.BUCKET_VOLUME, ForestryItem.refractoryFuel.getItemStack(), ForestryItem.refractoryEmpty.getItemStack()); + LiquidHelper.injectTinContainer(Defaults.LIQUID_OIL, Defaults.BUCKET_VOLUME, ForestryItem.canOil.getItemStack(), ForestryItem.canEmpty.getItemStack()); + LiquidHelper.injectTinContainer(Defaults.LIQUID_FUEL, Defaults.BUCKET_VOLUME, ForestryItem.canFuel.getItemStack(), ForestryItem.canEmpty.getItemStack()); + + } + + private void addIronEngineFuel(Fluid fuel, float powerPerCycle, float totalBurningTime) { + IronEngineFuel.addFuel(fuel, (int) powerPerCycle, (int) totalBurningTime); + } + + private void addRefineryRecipe(FluidStack ingredient1, FluidStack ingredient2, FluidStack result, int energy, int delay) { + BuildcraftRecipes.refinery.addRecipe(ingredient1, ingredient2, result, energy, delay); + + } + + private void initStoneGear() { + try { + stoneGear = (Item) Class.forName("buildcraft.BuildCraftCore").getField("stoneGearItem").get(null); + } catch (Exception ex) { + Proxies.log.fine("No BuildCraft stone gear found."); + return; + } + } + + private void initWaterproof() { + try { + pipeWaterproof = (Item) Class.forName("buildcraft.BuildCraftTransport").getField("pipeWaterproof").get(null); + } catch (Exception ex) { + Proxies.log.fine("No BuildCraft pipe waterproof found."); + return; + } + + Proxies.common.addRecipe(new ItemStack(pipeWaterproof), new Object[] { "#", Character.valueOf('#'), ForestryItem.beeswax }); + } + + public double invokeUseEnergyMethod(PowerHandler workProvider, float min, float max, boolean doUse) { + return workProvider.useEnergy(min, max, doUse); + } + + public void invokeReceiveEnergyMethod(PowerHandler.Type type, PowerReceiver receiver, double extractedEnergy, ForgeDirection from) { + receiver.receiveEnergy(type, extractedEnergy, from); + } + + // / ITRIGGERPROVIDER + @Override + public LinkedList getPipeTriggers(IPipeTile pipe) { + return null; + } + + @Override + public LinkedList getNeighborTriggers(Block block, TileEntity tile) { + if (tile instanceof TileForestry) + return ((TileForestry) tile).getCustomTriggers(); + + return null; + } + + @Override + public void preInit() { + } +} diff --git a/forestry_common/core/forestry/plugins/PluginCore.java b/forestry_common/core/forestry/plugins/PluginCore.java new file mode 100755 index 000000000..cf93aaf6b --- /dev/null +++ b/forestry_common/core/forestry/plugins/PluginCore.java @@ -0,0 +1,608 @@ +/******************************************************************************* + * Copyright 2011-2014 by SirSengir + * + * This work is licensed under a Creative Commons Attribution-NonCommercial-NoDerivs 3.0 Unported License. + * + * To view a copy of this license, visit http://creativecommons.org/licenses/by-nc-nd/3.0/. + ******************************************************************************/ +package forestry.plugins; + +import java.security.cert.Certificate; +import java.util.ArrayList; +import java.util.LinkedList; + +import net.minecraft.block.Block; +import net.minecraft.block.material.Material; +import net.minecraft.command.ICommand; +import net.minecraft.init.Blocks; +import net.minecraft.init.Items; +import net.minecraft.item.ItemStack; +import net.minecraft.item.crafting.FurnaceRecipes; +import net.minecraft.item.crafting.IRecipe; + +import cpw.mods.fml.common.FMLCommonHandler; +import cpw.mods.fml.common.IFuelHandler; +import cpw.mods.fml.common.Loader; +import cpw.mods.fml.common.Mod; +import cpw.mods.fml.common.ModContainer; +import cpw.mods.fml.common.network.IGuiHandler; +import cpw.mods.fml.common.registry.GameRegistry; + +import net.minecraftforge.common.MinecraftForge; +import net.minecraftforge.oredict.OreDictionary; + +import forestry.api.circuits.ChipsetManager; +import forestry.api.core.PluginInfo; +import forestry.api.core.Tabs; +import forestry.api.genetics.AlleleManager; +import forestry.core.CommandForestry; +import forestry.core.CreativeTabForestry; +import forestry.core.GameMode; +import forestry.core.PickupHandlerCore; +import forestry.core.SaveEventHandlerCore; +import forestry.core.circuits.CircuitRegistry; +import forestry.core.circuits.ItemCircuitBoard; +import forestry.core.circuits.ItemSolderingIron; +import forestry.core.config.Config; +import forestry.core.config.Defaults; +import forestry.core.config.ForestryBlock; +import forestry.core.config.ForestryItem; +import forestry.core.gadgets.BlockBase; +import forestry.core.gadgets.BlockResource; +import forestry.core.gadgets.BlockSoil; +import forestry.core.gadgets.BlockStainedGlass; +import forestry.core.gadgets.MachineDefinition; +import forestry.core.gadgets.TileAnalyzer; +import forestry.core.gadgets.TileEscritoire; +import forestry.core.genetics.Allele; +import forestry.core.genetics.AlleleRegistry; +import forestry.core.genetics.ItemResearchNote; +import forestry.core.interfaces.IOreDictionaryHandler; +import forestry.core.interfaces.IPickupHandler; +import forestry.core.interfaces.ISaveEventHandler; +import forestry.core.items.ItemArmorNaturalist; +import forestry.core.items.ItemAssemblyKit; +import forestry.core.items.ItemCrated; +import forestry.core.items.ItemForestry; +import forestry.core.items.ItemForestryBlock; +import forestry.core.items.ItemForestryPickaxe; +import forestry.core.items.ItemForestryShovel; +import forestry.core.items.ItemFruit; +import forestry.core.items.ItemLiquidContainer; +import forestry.core.items.ItemLiquidContainer.EnumContainerType; +import forestry.core.items.ItemMisc; +import forestry.core.items.ItemOverlay; +import forestry.core.items.ItemOverlay.OverlayInfo; +import forestry.core.items.ItemPipette; +import forestry.core.items.ItemScoop; +import forestry.core.items.ItemWrench; +import forestry.core.proxy.Proxies; +import forestry.core.utils.ForestryModEnvWarningCallable; +import forestry.core.utils.ShapedRecipeCustom; +import forestry.core.utils.Utils; + +@PluginInfo(pluginID = "Core", name = "Core", author = "SirSengir", url = Defaults.URL, description = "Core mechanics for Forestry. Required by all other plugins.") +public class PluginCore extends NativePlugin implements IFuelHandler { + + public static MachineDefinition definitionAnalyzer; + public static MachineDefinition definitionEscritoire; + // ICrashCallable for highlighting certain mods during crashes. + public static ForestryModEnvWarningCallable crashCallable; + + @Override + public void preInit() { + super.preInit(); + + ChipsetManager.solderManager = new ItemSolderingIron.SolderManager(); + + CircuitRegistry circuitRegistry = new CircuitRegistry(); + ChipsetManager.circuitRegistry = circuitRegistry; + circuitRegistry.initialize(); + + AlleleRegistry alleleRegistry = new AlleleRegistry(); + AlleleManager.alleleRegistry = alleleRegistry; + alleleRegistry.initialize(); + + Allele.initialize(); + + ForestryBlock.core = new BlockBase(Material.iron, true); + ForestryBlock.core.setBlockName("for.core"); + Proxies.common.registerBlock(ForestryBlock.core, ItemForestryBlock.class); + + definitionAnalyzer = ForestryBlock.core.addDefinition(new MachineDefinition(Defaults.DEFINITION_ANALYZER_META, "forestry.Analyzer", TileAnalyzer.class, + PluginApiculture.proxy.getRendererAnalyzer(Defaults.TEXTURE_PATH_BLOCKS + "/analyzer_"), new IRecipe[0])); + definitionEscritoire = ForestryBlock.core.addDefinition(new MachineDefinition(Defaults.DEFINITION_ESCRITOIRE_META, "forestry.Escritoire", TileEscritoire.class, + Proxies.render.getRenderEscritoire(), new IRecipe[0])); + + if (FMLCommonHandler.instance().getEffectiveSide().isClient()) + $$______$$(); + + + + ForestryBlock.soil = new BlockSoil().setBlockName("soil"); + Proxies.common.registerBlock(ForestryBlock.soil, ItemForestryBlock.class); + ForestryBlock.soil.setHarvestLevel("shovel", 0, 0); + ForestryBlock.soil.setHarvestLevel("shovel", 0, 1); + + ForestryBlock.resources = new BlockResource().setBlockName("resources"); + Proxies.common.registerBlock(ForestryBlock.resources, ItemForestryBlock.class); + ForestryBlock.resources.setHarvestLevel("pickaxe", 1, 0); + ForestryBlock.resources.setHarvestLevel("pickaxe", 1, 1); + ForestryBlock.resources.setHarvestLevel("pickaxe", 1, 2); + + if (FMLCommonHandler.instance().getEffectiveSide().isClient()) + $$____$$(); + + OreDictionary.registerOre("oreApatite", new ItemStack(ForestryBlock.resources, 1, 0)); + OreDictionary.registerOre("oreCopper", new ItemStack(ForestryBlock.resources, 1, 1)); + OreDictionary.registerOre("oreTin", new ItemStack(ForestryBlock.resources, 1, 2)); + + ForestryBlock.glass = new BlockStainedGlass().setBlockName("stained"); + Proxies.common.registerBlock(ForestryBlock.glass, ItemForestryBlock.class); + + /* SMELTING RECIPES */ + FurnaceRecipes.smelting().func_151394_a(new ItemStack(ForestryBlock.resources, 1), ForestryItem.ingotCopper.getItemStack(), 0.5f); + FurnaceRecipes.smelting().func_151394_a(new ItemStack(ForestryBlock.resources, 2), ForestryItem.ingotTin.getItemStack(), 0.5f); + + GameRegistry.registerFuelHandler(this); + + } + + @Override + public void doInit() { + super.doInit(); + definitionAnalyzer.recipes = $$_____$$(ForestryBlock.core, Defaults.DEFINITION_ANALYZER_META); + + for ($___$ prop : $________$) { + prop.$$_______$$(); + } + + definitionAnalyzer.register(); + definitionEscritoire.register(); + crashCallable = new ForestryModEnvWarningCallable(); + } + + @Override + public boolean isAvailable() { + return true; + } + + @Override + public IGuiHandler getGuiHandler() { + return null; + } + + @Override + public ISaveEventHandler getSaveEventHandler() { + return new SaveEventHandlerCore(); + } + + @Override + protected void registerItems() { + + // / FERTILIZERS + ForestryItem.fertilizerBio.registerItem((new ItemForestry()), "fertilizerBio"); + ForestryItem.fertilizerCompound.registerItem((new ItemForestry()).setBonemeal(true), "fertilizerCompound"); + + // / GEMS + ForestryItem.apatite.registerItem((new ItemForestry()), "apatite"); + OreDictionary.registerOre("gemApatite", ForestryItem.apatite.getItemStack()); + + ForestryItem.researchNote.registerItem(new ItemResearchNote(), "researchNote"); + + // / INGOTS + ForestryItem.ingotCopper.registerItem(new ItemForestry(), "ingotCopper"); + ForestryItem.ingotTin.registerItem(new ItemForestry(), "ingotTin"); + ForestryItem.ingotBronze.registerItem(new ItemForestry(), "ingotBronze"); + + OreDictionary.registerOre("ingotCopper", ForestryItem.ingotCopper.getItemStack()); + OreDictionary.registerOre("ingotTin", ForestryItem.ingotTin.getItemStack()); + OreDictionary.registerOre("ingotBronze", ForestryItem.ingotBronze.getItemStack()); + + // / TOOLS + ForestryItem.wrench.registerItem((new ItemWrench()), "wrench"); + ForestryItem.pipette.registerItem(new ItemPipette(), "pipette"); + ForestryItem.scoop.registerItem(new ItemScoop(), "scoop"); + ForestryItem.scoop.item().setHarvestLevel("scoop", 3); + + // / MACHINES + ForestryItem.sturdyCasing.registerItem((new ItemForestry()), "sturdyMachine"); + ForestryItem.hardenedCasing.registerItem((new ItemForestry()), "hardenedMachine"); + ForestryItem.impregnatedCasing.registerItem((new ItemForestry()), "impregnatedCasing"); + + ForestryItem.craftingMaterial.registerItem(new ItemMisc(), "craftingMaterial"); + + /* ARMOR */ + ForestryItem.naturalistHat.registerItem(new ItemArmorNaturalist(0), "naturalistHelmet"); + + // / DISCONTINUED + // ForestryItem.vialEmpty = (new + // ItemForestry(Config.getOrCreateIntProperty("vialEmpty", + // Config.CATEGORY_ITEM, Defaults.ID_ITEM_VIAL_EMPTY))) + // .setItemName("vialEmpty").setIconIndex(10); + ForestryItem.vialCatalyst.registerItem((new ItemForestry()), "vialCatalyst"); + + + $$_________$$(); + + // / EMPTY LIQUID CONTAINERS + ForestryItem.waxCapsule.registerItem(new ItemLiquidContainer(EnumContainerType.CAPSULE, -1).setMaxStackSize(64), "waxCapsule"); + ForestryItem.canEmpty.registerItem(new ItemLiquidContainer(EnumContainerType.CAN, -1).setMaxStackSize(64), "canEmpty"); + ForestryItem.refractoryEmpty.registerItem(new ItemLiquidContainer(EnumContainerType.REFRACTORY, -1).setMaxStackSize(64), "refractoryEmpty"); + + // / BUCKETS + ForestryItem.bucketBiomass.registerItem(new ItemForestry().setContainerItem(Items.bucket).setMaxStackSize(1), "bucketBiomass"); + ForestryItem.bucketBiofuel.registerItem(new ItemForestry().setContainerItem(Items.bucket).setMaxStackSize(1), "bucketBiofuel"); + + // / WAX CAPSULES + ForestryItem.waxCapsuleWater.registerItem((new ItemLiquidContainer(EnumContainerType.CAPSULE, 0x2432ec)), "waxCapsuleWater"); + ForestryItem.waxCapsuleBiomass.registerItem((new ItemLiquidContainer(EnumContainerType.CAPSULE, 0x83d41c)), "waxCapsuleBiomass"); + ForestryItem.waxCapsuleBiofuel.registerItem((new ItemLiquidContainer(EnumContainerType.CAPSULE, 0xff7909)), "waxCapsuleBiofuel"); + ForestryItem.waxCapsuleOil.registerItem((new ItemLiquidContainer(EnumContainerType.CAPSULE, 0x404040)), "waxCapsuleOil"); + ForestryItem.waxCapsuleFuel.registerItem((new ItemLiquidContainer(EnumContainerType.CAPSULE, 0xffff00)), "waxCapsuleFuel"); + ForestryItem.waxCapsuleSeedOil.registerItem((new ItemLiquidContainer(EnumContainerType.CAPSULE, 0xffffa9)), "waxCapsuleSeedOil"); + ForestryItem.waxCapsuleHoney.registerItem((new ItemLiquidContainer(EnumContainerType.CAPSULE, 0xffda47)).setDrink(Defaults.FOOD_HONEY_HEAL, Defaults.FOOD_HONEY_SATURATION), "waxCapsuleHoney"); + ForestryItem.waxCapsuleJuice.registerItem((new ItemLiquidContainer(EnumContainerType.CAPSULE, 0x99d04e)).setDrink(Defaults.FOOD_JUICE_HEAL, Defaults.FOOD_JUICE_SATURATION), "waxCapsuleJuice"); + ForestryItem.waxCapsuleIce.registerItem((new ItemLiquidContainer(EnumContainerType.CAPSULE, 0xdcffff)), "waxCapsuleIce"); + + // / CANS + ForestryItem.canWater.registerItem((new ItemLiquidContainer(EnumContainerType.CAN, 0x2432ec)), "waterCan"); + ForestryItem.canBiomass.registerItem((new ItemLiquidContainer(EnumContainerType.CAN, 0x83d41c)), "biomassCan"); + ForestryItem.canBiofuel.registerItem((new ItemLiquidContainer(EnumContainerType.CAN, 0xff7909)), "biofuelCan"); + ForestryItem.canOil.registerItem((new ItemLiquidContainer(EnumContainerType.CAN, 0x404040)), "canOil"); + ForestryItem.canFuel.registerItem((new ItemLiquidContainer(EnumContainerType.CAN, 0xffff00)), "canFuel"); + ForestryItem.canLava.registerItem((new ItemLiquidContainer(EnumContainerType.CAN, 0xfd461f)), "canLava"); + ForestryItem.canSeedOil.registerItem((new ItemLiquidContainer(EnumContainerType.CAN, 0xffffa9)), "canSeedOil"); + ForestryItem.canHoney.registerItem((new ItemLiquidContainer(EnumContainerType.CAN, 0xffda47)).setDrink(Defaults.FOOD_HONEY_HEAL, Defaults.FOOD_HONEY_SATURATION), "canHoney"); + ForestryItem.canJuice.registerItem((new ItemLiquidContainer(EnumContainerType.CAN, 0x99d04e)).setDrink(Defaults.FOOD_JUICE_HEAL, Defaults.FOOD_JUICE_SATURATION), "canJuice"); + ForestryItem.canIce.registerItem((new ItemLiquidContainer(EnumContainerType.CAN, 0xdcffff)), "canIce"); + + // / REFRACTORY CAPSULES + ForestryItem.refractoryWater.registerItem((new ItemLiquidContainer(EnumContainerType.REFRACTORY, 0x2432ec)), "refractoryWater"); + ForestryItem.refractoryBiomass.registerItem((new ItemLiquidContainer(EnumContainerType.REFRACTORY, 0x83d41c)), "refractoryBiomass"); + ForestryItem.refractoryBiofuel.registerItem((new ItemLiquidContainer(EnumContainerType.REFRACTORY, 0xff7909)), "refractoryBiofuel"); + ForestryItem.refractoryOil.registerItem((new ItemLiquidContainer(EnumContainerType.REFRACTORY, 0x404040)), "refractoryOil"); + ForestryItem.refractoryFuel.registerItem((new ItemLiquidContainer(EnumContainerType.REFRACTORY, 0xffff00)), "refractoryFuel"); + ForestryItem.refractoryLava.registerItem((new ItemLiquidContainer(EnumContainerType.REFRACTORY, 0xfd461f)), "refractoryLava"); + ForestryItem.refractorySeedOil.registerItem((new ItemLiquidContainer(EnumContainerType.REFRACTORY, 0xffffa9)), "refractorySeedOil"); + ForestryItem.refractoryHoney.registerItem((new ItemLiquidContainer(EnumContainerType.REFRACTORY, 0xffda47)).setDrink(Defaults.FOOD_HONEY_HEAL, Defaults.FOOD_HONEY_SATURATION), "refractoryHoney"); + ForestryItem.refractoryJuice.registerItem((new ItemLiquidContainer(EnumContainerType.REFRACTORY, 0x99d04e)).setDrink(Defaults.FOOD_JUICE_HEAL, Defaults.FOOD_JUICE_SATURATION), "refractoryJuice"); + ForestryItem.refractoryIce.registerItem((new ItemLiquidContainer(EnumContainerType.REFRACTORY, 0xdcffff)), "refractoryIce"); + + } + + private void $$_________$$() { + + // / PEAT PRODUCTION + ForestryItem.peat.registerItem((new ItemForestry()), "peat"); + OreDictionary.registerOre("brickPeat", ForestryItem.peat.getItemStack()); + + ForestryItem.ash.registerItem((new ItemForestry()), "ash"); + OreDictionary.registerOre("dustAsh", ForestryItem.ash.getItemStack()); + + Proxies.common.addSmelting(ForestryItem.peat.getItemStack(), ForestryItem.ash.getItemStack()); + ForestryItem.bituminousPeat.registerItem(new ItemForestry(), "bituminousPeat"); + + // / GEARS + ForestryItem.gearBronze.registerItem((new ItemForestry()), "gearBronze"); + OreDictionary.registerOre("gearBronze", ForestryItem.gearBronze.getItemStack()); + ForestryItem.gearCopper.registerItem((new ItemForestry()), "gearCopper"); + OreDictionary.registerOre("gearCopper", ForestryItem.gearCopper.getItemStack()); + ForestryItem.gearTin.registerItem((new ItemForestry()), "gearTin"); + OreDictionary.registerOre("gearTin", ForestryItem.gearTin.getItemStack()); + + // / CIRCUIT BOARDS + ForestryItem.circuitboards.registerItem(new ItemCircuitBoard(), "chipsets"); + ForestryItem.solderingIron.registerItem(new ItemSolderingIron(), "solderingIron"); + ForestryItem.tubes.registerItem(new ItemOverlay(CreativeTabForestry.tabForestry, + new OverlayInfo[] { new OverlayInfo("ex-0", 0xffffff, 0xe3b78e), new OverlayInfo("ex-1", 0xffffff, 0xe1eef4), + new OverlayInfo("ex-2", 0xffffff, 0xddc276), new OverlayInfo("ex-3", 0xffffff, 0xd8d8d8), new OverlayInfo("ex-4", 0xffffff, 0xffff8b), + new OverlayInfo("ex-5", 0xffffff, 0x7bd1b8), new OverlayInfo("ex-6", 0xffffff, 0x866bc0), new OverlayInfo("ex-7", 0xfff87e, 0xd96600), + new OverlayInfo("ex-8", 0xffffff, 0x444444), new OverlayInfo("ex-9", 0xffffff, 0xbfffdd), new OverlayInfo("ex-10", 0xffffff, 0x68ccee), + new OverlayInfo("ex-11", 0xffffff, 0x1c57c6) }), "thermionicTubes"); + + // / CRATES AND CARTONS + ForestryItem.carton.registerItem((new ItemForestry()), "carton"); + ForestryItem.crate.registerItem((new ItemForestry()), "crate"); + + // / CRAFTING CARPENTER + ForestryItem.stickImpregnated.registerItem((new ItemForestry()), "oakStick"); + ForestryItem.woodPulp.registerItem((new ItemForestry()), "woodPulp"); + OreDictionary.registerOre("pulpWood", ForestryItem.woodPulp.getItemStack()); + + // / RECLAMATION + ForestryItem.brokenBronzePickaxe.registerItem((new ItemForestry()), "brokenBronzePickaxe"); + ForestryItem.brokenBronzeShovel.registerItem((new ItemForestry()), "brokenBronzeShovel"); + + // / TOOLS + ForestryItem.bronzePickaxe.registerItem(new ItemForestryPickaxe(ForestryItem.brokenBronzePickaxe.getItemStack()), "bronzePickaxe"); + ForestryItem.bronzePickaxe.item().setHarvestLevel("pickaxe", 3); + MinecraftForge.EVENT_BUS.register(ForestryItem.bronzePickaxe.item()); + ForestryItem.bronzeShovel.registerItem(new ItemForestryShovel(ForestryItem.brokenBronzeShovel.getItemStack()), "bronzeShovel"); + ForestryItem.bronzeShovel.item().setHarvestLevel("shovel", 3); + MinecraftForge.EVENT_BUS.register(ForestryItem.bronzeShovel.item()); + + // / ASSEMBLY KITS + ForestryItem.kitShovel.registerItem(new ItemAssemblyKit(ForestryItem.bronzeShovel.getItemStack()), "kitShovel"); + ForestryItem.kitPickaxe.registerItem(new ItemAssemblyKit(ForestryItem.bronzePickaxe.getItemStack()), "kitPickaxe"); + + // / MOISTENER RESOURCES + ForestryItem.mouldyWheat.registerItem((new ItemForestry()), "mouldyWheat"); + ForestryItem.decayingWheat.registerItem((new ItemForestry()), "decayingWheat"); + ForestryItem.mulch.registerItem((new ItemForestry()), "mulch"); + + // / RAINMAKER SUBSTRATES + ForestryItem.iodineCharge.registerItem((new ItemForestry()), "iodineCapsule"); + + ForestryItem.phosphor.registerItem((new ItemForestry()), "phosphor"); + + // / BEE RESOURCES + ForestryItem.beeswax.registerItem(new ItemForestry().setCreativeTab(Tabs.tabApiculture), "beeswax"); + OreDictionary.registerOre("itemBeeswax", ForestryItem.beeswax.getItemStack()); + + ForestryItem.refractoryWax.registerItem(new ItemForestry(), "refractoryWax"); + + // FRUITS + ForestryItem.fruits.registerItem(new ItemFruit(), "fruits"); + + } + + @Override + protected void registerBackpackItems() { + } + + @Override + protected void registerCrates() { + // / CRATES + ForestryItem.cratedWood.registerItem(new ItemCrated(new ItemStack(Blocks.log)), "cratedWood"); + ForestryItem.cratedCobblestone.registerItem(new ItemCrated(new ItemStack(Blocks.cobblestone)), "cratedCobblestone"); + ForestryItem.cratedDirt.registerItem(new ItemCrated(new ItemStack(Blocks.dirt)), "cratedDirt"); + ForestryItem.cratedStone.registerItem(new ItemCrated(new ItemStack(Blocks.stone)), "cratedStone"); + ForestryItem.cratedBrick.registerItem(new ItemCrated(new ItemStack(Blocks.brick_block)), "cratedBrick"); + ForestryItem.cratedCacti.registerItem(new ItemCrated(new ItemStack(Blocks.cactus)), "cratedCacti"); + ForestryItem.cratedSand.registerItem(new ItemCrated(new ItemStack(Blocks.sand)), "cratedSand"); + ForestryItem.cratedObsidian.registerItem(new ItemCrated(new ItemStack(Blocks.obsidian)), "cratedObsidian"); + ForestryItem.cratedNetherrack.registerItem(new ItemCrated(new ItemStack(Blocks.netherrack)), "cratedNetherrack"); + ForestryItem.cratedSoulsand.registerItem(new ItemCrated(new ItemStack(Blocks.soul_sand)), "cratedSoulsand"); + ForestryItem.cratedSandstone.registerItem(new ItemCrated(new ItemStack(Blocks.sandstone)), "cratedSandstone"); + ForestryItem.cratedBogearth.registerItem(new ItemCrated(new ItemStack(ForestryBlock.soil, 1, 1)), "cratedBogearth"); + ForestryItem.cratedHumus.registerItem(new ItemCrated(new ItemStack(ForestryBlock.soil, 1, 0)), "cratedHumus"); + ForestryItem.cratedNetherbrick.registerItem(new ItemCrated(new ItemStack(Blocks.nether_brick)), "cratedNetherbrick"); + ForestryItem.cratedPeat.registerItem(new ItemCrated(ForestryItem.peat.getItemStack()), "cratedPeat"); + ForestryItem.cratedApatite.registerItem(new ItemCrated(ForestryItem.apatite.getItemStack()), "cratedApatite"); + ForestryItem.cratedFertilizer.registerItem(new ItemCrated(ForestryItem.fertilizerCompound.getItemStack()), "cratedFertilizer"); + ForestryItem.cratedTin.registerItem(new ItemCrated(ForestryItem.ingotTin.getItemStack()), "cratedTin"); + ForestryItem.cratedCopper.registerItem(new ItemCrated(ForestryItem.ingotCopper.getItemStack()), "cratedCopper"); + ForestryItem.cratedBronze.registerItem(new ItemCrated(ForestryItem.ingotBronze.getItemStack()), "cratedBronze"); + ForestryItem.cratedWheat.registerItem(new ItemCrated(new ItemStack(Items.wheat)), "cratedWheat"); + ForestryItem.cratedMycelium.registerItem(new ItemCrated(new ItemStack(Blocks.mycelium)), "cratedMycelium"); + ForestryItem.cratedMulch.registerItem(new ItemCrated(ForestryItem.mulch.getItemStack()), "cratedMulch"); + ForestryItem.cratedSilver.registerItem(new ItemCrated(), "cratedSilver"); + ForestryItem.cratedBrass.registerItem(new ItemCrated(), "cratedBrass"); + ForestryItem.cratedNikolite.registerItem(new ItemCrated(), "cratedNikolite"); + ForestryItem.cratedCookies.registerItem(new ItemCrated(new ItemStack(Items.cookie)), "cratedCookies"); + ForestryItem.cratedRedstone.registerItem(new ItemCrated(new ItemStack(Items.redstone)), "cratedRedstone"); + ForestryItem.cratedLapis.registerItem(new ItemCrated(new ItemStack(Items.dye, 1, 4)), "cratedLapis"); + ForestryItem.cratedReeds.registerItem(new ItemCrated(new ItemStack(Items.reeds)), "cratedReeds"); + ForestryItem.cratedClay.registerItem(new ItemCrated(new ItemStack(Items.clay_ball)), "cratedClay"); + ForestryItem.cratedGlowstone.registerItem(new ItemCrated(new ItemStack(Items.glowstone_dust)), "cratedGlowstone"); + ForestryItem.cratedApples.registerItem(new ItemCrated(new ItemStack(Items.apple)), "cratedApples"); + ForestryItem.cratedNetherwart.registerItem(new ItemCrated(new ItemStack(Items.nether_wart)), "cratedNetherwart"); + ForestryItem.cratedResin.registerItem(new ItemCrated(), "cratedResin"); + ForestryItem.cratedRubber.registerItem(new ItemCrated(), "cratedRubber"); + ForestryItem.cratedScrap.registerItem(new ItemCrated(), "cratedScrap"); + ForestryItem.cratedUUM.registerItem(new ItemCrated(), "cratedUUM"); + ForestryItem.cratedPhosphor.registerItem(new ItemCrated(ForestryItem.phosphor.getItemStack()), "cratedPhosphor"); + ForestryItem.cratedAsh.registerItem(new ItemCrated(ForestryItem.ash.getItemStack()), "cratedAsh"); + ForestryItem.cratedCharcoal.registerItem(new ItemCrated(new ItemStack(Items.coal, 1, 1)), "cratedCharcoal"); + ForestryItem.cratedGravel.registerItem(new ItemCrated(new ItemStack(Blocks.gravel)), "cratedGravel"); + ForestryItem.cratedCoal.registerItem(new ItemCrated(new ItemStack(Items.coal, 1, 0)), "cratedCoal"); + ForestryItem.cratedSeeds.registerItem(new ItemCrated(new ItemStack(Items.wheat_seeds)), "cratedSeeds"); + ForestryItem.cratedSaplings.registerItem(new ItemCrated(new ItemStack(Blocks.sapling)), "cratedSaplings"); + } + + @Override + protected void registerRecipes() { + + /* BRONZE INGOTS */ + if (Config.getCraftingBronzeEnabled()) { + Proxies.common.addShapelessRecipe(ForestryItem.ingotBronze.getItemStack(4), "ingotTin", "ingotCopper", "ingotCopper", "ingotCopper"); + } + + /* STURDY MACHINE */ + Proxies.common.addRecipe(ForestryItem.sturdyCasing.getItemStack(), "###", "# #", "###", '#', "ingotBronze"); + + // / EMPTY CANS + Proxies.common.addRecipe(GameMode.getGameMode().getStackSetting("recipe.output.can"), " # ", "# #", '#', "ingotTin"); + + // / GEARS + if (PluginBuildCraft.stoneGear != null) { + + Proxies.common.addRecipe(ForestryItem.gearBronze.getItemStack(), " # ", "#Y#", " # ", '#', "ingotBronze", 'Y', PluginBuildCraft.stoneGear); + Proxies.common.addRecipe(ForestryItem.gearCopper.getItemStack(), " # ", "#Y#", " # ", '#', "ingotCopper", 'Y', PluginBuildCraft.stoneGear); + Proxies.common.addRecipe(ForestryItem.gearTin.getItemStack(), " # ", "#Y#", " # ", '#', "ingotTin", 'Y', PluginBuildCraft.stoneGear); + + } else { + + Proxies.common.addRecipe(ForestryItem.gearBronze.getItemStack(), " # ", "#X#", " # ", '#', "ingotBronze", 'X', "ingotCopper"); + Proxies.common.addRecipe(ForestryItem.gearCopper.getItemStack(), " # ", "#X#", " # ", '#', "ingotCopper", 'X', "ingotCopper"); + Proxies.common.addRecipe(ForestryItem.gearTin.getItemStack(), " # ", "#X#", " # ", '#', "ingotTin", 'X', "ingotCopper"); + } + + // / SURVIVALIST TOOLS + Proxies.common.addRecipe(ForestryItem.bronzePickaxe.getItemStack(), " X ", " X ", "###", '#', "ingotBronze", 'X', "stickWood"); + Proxies.common.addRecipe(ForestryItem.bronzeShovel.getItemStack(), " X ", " X ", " # ", '#', "ingotBronze", 'X', "stickWood"); + Proxies.common.addShapelessRecipe(ForestryItem.kitPickaxe.getItemStack(), ForestryItem.bronzePickaxe, ForestryItem.carton); + Proxies.common.addShapelessRecipe(ForestryItem.kitShovel.getItemStack(), ForestryItem.bronzeShovel, ForestryItem.carton); + + /* NATURALIST'S ARMOR */ + Proxies.common.addRecipe(ForestryItem.naturalistHat.getItemStack(), " X ", "Y Y", 'X', "ingotBronze", 'Y', Blocks.glass_pane); + + // / WRENCH + Proxies.common.addRecipe(ForestryItem.wrench.getItemStack(), "# #", " # ", " # ", '#', "ingotBronze"); + + // Manure and Fertilizer + if (GameMode.getGameMode().getStackSetting("recipe.output.compost.wheat").stackSize > 0) + Proxies.common.addRecipe(GameMode.getGameMode().getStackSetting("recipe.output.compost.wheat"), " X ", "X#X", " X ", '#', Blocks.dirt, 'X', Items.wheat); + if (GameMode.getGameMode().getStackSetting("recipe.output.compost.ash").stackSize > 0) + Proxies.common.addRecipe(GameMode.getGameMode().getStackSetting("recipe.output.compost.ash"), " X ", "X#X", " X ", '#', Blocks.dirt, 'X', "dustAsh"); + if (GameMode.getGameMode().getStackSetting("recipe.output.fertilizer.apatite").stackSize > 0) + Proxies.common.addRecipe(GameMode.getGameMode().getStackSetting("recipe.output.fertilizer.apatite"), " # ", " X ", " # ", '#', Blocks.sand, 'X', "gemApatite"); + if (GameMode.getGameMode().getStackSetting("recipe.output.fertilizer.ash").stackSize > 0) + Proxies.common.addRecipe(GameMode.getGameMode().getStackSetting("recipe.output.fertilizer.ash"), "###", "#X#", "###", '#', "dustAsh", 'X', "gemApatite"); + + // Humus + if (GameMode.getGameMode().getStackSetting("recipe.output.humus.compost").stackSize > 0) + Proxies.common.addRecipe(GameMode.getGameMode().getStackSetting("recipe.output.humus.compost"), "###", "#X#", "###", '#', Blocks.dirt, 'X', ForestryItem.fertilizerBio); + if (GameMode.getGameMode().getStackSetting("recipe.output.humus.fertilizer").stackSize > 0) + Proxies.common.addRecipe(GameMode.getGameMode().getStackSetting("recipe.output.humus.fertilizer"), "###", "#X#", "###", '#', Blocks.dirt, 'X', ForestryItem.fertilizerCompound); + + // Bog earth + if (GameMode.getGameMode().getStackSetting("recipe.output.bogearth.bucket").stackSize > 0) + Proxies.common.addRecipe(GameMode.getGameMode().getStackSetting("recipe.output.bogearth.bucket"), "#Y#", "YXY", "#Y#", '#', Blocks.dirt, 'X', Items.water_bucket, 'Y', Blocks.sand); + + if (GameMode.getGameMode().getStackSetting("recipe.output.bogearth.can").stackSize > 0) { + Proxies.common.addRecipe(GameMode.getGameMode().getStackSetting("recipe.output.bogearth.can"), "#Y#", "YXY", "#Y#", '#', Blocks.dirt, 'X', ForestryItem.canWater, 'Y', Blocks.sand); + Proxies.common.addRecipe(GameMode.getGameMode().getStackSetting("recipe.output.bogearth.can"), "#Y#", "YXY", "#Y#", '#', Blocks.dirt, 'X', ForestryItem.waxCapsuleWater, 'Y', Blocks.sand); + Proxies.common.addRecipe(GameMode.getGameMode().getStackSetting("recipe.output.bogearth.can"), "#Y#", "YXY", "#Y#", '#', Blocks.dirt, 'X', ForestryItem.refractoryWater, 'Y', Blocks.sand); + } + + // Vials and catalyst + Proxies.common.addRecipe(ForestryItem.vialCatalyst.getItemStack(3), "###", "YXY", '#', ForestryItem.waxCapsule.item(), 'X', Items.bone, 'Y', ForestryItem.fertilizerCompound); + Proxies.common.addRecipe(ForestryItem.vialCatalyst.getItemStack(3), "###", "YXY", '#', ForestryItem.canEmpty.item(), 'X', Items.bone, 'Y', ForestryItem.fertilizerCompound); + + // Crafting Material + Proxies.common.addRecipe(new ItemStack(Items.string), "#", "#", "#", '#', ForestryItem.craftingMaterial.getItemStack(1, 2)); + + // / Pipette + Proxies.common.addRecipe(ForestryItem.pipette.getItemStack(), " #", " X ", "X ", 'X', Blocks.glass_pane, '#', new ItemStack(Blocks.wool, 1, Defaults.WILDCARD)); + } + + @Override + public IOreDictionaryHandler getDictionaryHandler() { + return null; + } + + @Override + public IPickupHandler getPickupHandler() { + return new PickupHandlerCore(); + } + + @Override + public ICommand[] getConsoleCommands() { + return new ICommand[] { new CommandForestry() }; + } + + @Override + public int getBurnTime(ItemStack fuel) { + if (fuel != null && fuel.getItem() == ForestryItem.peat.item()) + return 2000; + if (fuel != null && fuel.getItem() == ForestryItem.bituminousPeat.item()) + return 4200; + + return 0; + } + + /*@Override + public boolean processIMCMessage(IMCMessage message) { + if (message.key.equals(new String(new byte[] { 115, 101, 99, 117, 114, 105, 116, 121, 86, 105, 111, 108, 97, 116, 105, 111, 110 }))) + Config.invalidFingerprint = true; + return false; + }*/ + public IRecipe[] $$_____$$(Block block, int meta) { + ArrayList recipes = new ArrayList(); + if (ForestryItem.beealyzer != null) + recipes.add(ShapedRecipeCustom.createShapedRecipe(new ItemStack(block, 1, meta), "XTX", " Y ", "X X", 'Y', ForestryItem.sturdyCasing, 'T', ForestryItem.beealyzer, 'X', "ingotBronze")); + + if (ForestryItem.treealyzer != null) + recipes.add(ShapedRecipeCustom.createShapedRecipe(new ItemStack(block, 1, meta), "XTX", " Y ", "X X", 'Y', ForestryItem.sturdyCasing, 'T', ForestryItem.treealyzer, 'X', "ingotBronze")); + + return recipes.toArray(new IRecipe[0]); + } + + private abstract class $___$ { + + private final String fingerprint; + private final String corename; + + public $___$(String fingerprint) { + this("", fingerprint); + } + + public $___$(String coreName, String fingerprint) { + this.fingerprint = fingerprint; + this.corename = coreName; + } + + protected String $$__________$$() { + return corename; + } + + public void $$_______$$() { + try { + Class core = Class.forName($$__________$$()); + if (core != null) { + Certificate[] cert = core.getProtectionDomain().getCodeSource().getCertificates(); + if (cert == null || !Utils.getFingerprint(cert[0]).equals(new String(fingerprint))) { + Proxies.log + .severe("%s failed validation. Halting runtime for security reasons. Please replace your mods with untampered versions from the official download sites.", + $$__________$$()); + //Runtime.getRuntime().halt(1); + } + } + } catch (ClassNotFoundException ex) { + } + } + } + private static ArrayList<$___$> $________$ = new ArrayList<$___$>(); + + private void $$____$$() { + + $________$.add(new $___$(new String(new byte[] { 100, 101, 48, 52, 49, 102, 57, 102, 54, 49, 56, 55, 100, 101, 98, 98, 99, 55, 55, 48, 51, 52, 97, 51, + 52, 52, 49, 51, 52, 48, 53, 51, 50, 55, 55, 97, 97, 51, 98, 48 })) { + @Override + protected String $$__________$$() { + return "ic2.core.IC2"; + } + }); + $________$.add(new $___$(new String(new byte[] { 97, 48, 99, 50, 53, 53, 97, 99, 53, 48, 49, 98, 50, 55, 52, 57, 53, 51, 55, 100, 53, 56, 50, 52, 98, + 98, 48, 102, 48, 53, 56, 56, 98, 102, 48, 51, 50, 48, 102, 97 })) { + @Override + protected String $$__________$$() { + return "mods.railcraft.common.core.Railcraft"; + } + }); + } + + private void $$______$$() { + LinkedList fossExceptions = new LinkedList(); + fossExceptions.add("logisticspipes.LogisticsPipes"); + fossExceptions.add("com.pahimar.ee3.EquivalentExchange3"); + + for (ModContainer modContainer : Loader.instance().getModList()) { + + Object modInstance = modContainer.getMod(); + if (modInstance == null) + continue; + Mod modAnnotation = modInstance.getClass().getAnnotation(Mod.class); + if (modAnnotation == null) + continue; + + String fingerprint = modAnnotation.certificateFingerprint(); + if (fingerprint == null || fingerprint.equals("") || fingerprint.startsWith("@") || fingerprint.startsWith("%")) + continue; + + boolean isExcepted = false; + for (String exception : fossExceptions) { + if (exception.startsWith(modInstance.getClass().getCanonicalName())) { + isExcepted = true; + break; + } + } + + if (!isExcepted) + $________$.add(new $___$(modInstance.getClass().getCanonicalName(), fingerprint) { + }); + } + } +} diff --git a/forestry_common/core/forestry/plugins/PluginIC2.java b/forestry_common/core/forestry/plugins/PluginIC2.java new file mode 100755 index 000000000..f7b0b705c --- /dev/null +++ b/forestry_common/core/forestry/plugins/PluginIC2.java @@ -0,0 +1,194 @@ +/******************************************************************************* + * Copyright 2011-2014 by SirSengir + * + * This work is licensed under a Creative Commons Attribution-NonCommercial-NoDerivs 3.0 Unported License. + * + * To view a copy of this license, visit http://creativecommons.org/licenses/by-nc-nd/3.0/. + ******************************************************************************/ +package forestry.plugins; + +import net.minecraft.init.Blocks; +import net.minecraft.item.ItemStack; +import net.minecraft.nbt.NBTTagCompound; + +import cpw.mods.fml.common.event.FMLInterModComms; +import cpw.mods.fml.common.registry.GameData; + +import ic2.api.item.IC2Items; + +import forestry.api.core.IPlugin; +import forestry.api.core.PluginInfo; +import forestry.api.recipes.RecipeManagers; +import forestry.api.storage.BackpackManager; +import forestry.core.GameMode; +import forestry.core.config.Config; +import forestry.core.config.Configuration; +import forestry.core.config.Defaults; +import forestry.core.config.ForestryItem; +import forestry.core.items.ItemCrated; +import forestry.core.proxy.Proxies; +import forestry.core.utils.LiquidHelper; +import forestry.core.utils.RecipeUtil; +import forestry.core.utils.StackUtils; + +@PluginInfo(pluginID = "IC2", name = "IndustrialCraft2", author = "SirSengir", url = Defaults.URL, description = "Compatibility plugin for IC2.") +public class PluginIC2 implements IPlugin { + + public static PluginIC2 instance; + public static Configuration config; + // Ignore IC2? + public static boolean ignore; + // IC2 stuff + public static ItemStack plantBall; + public static ItemStack compressedPlantBall; + public static ItemStack wrench; + public static ItemStack treetap; + public static ItemStack resin; + public static ItemStack rubbersapling; + public static ItemStack rubberwood; + public static ItemStack rubberleaves; + public static ItemStack fuelcanFilled; + public static ItemStack fuelcanEmpty; + public static ItemStack emptyCell; + public static ItemStack lavaCell; + public static ItemStack waterCell; + public static ItemStack rubber; + public static ItemStack scrap; + public static int fuelcanMeta; + + public PluginIC2() { + if (PluginIC2.instance == null) + PluginIC2.instance = this; + } + + @Override + public boolean isAvailable() { + return Proxies.common.isModLoaded("IC2"); + } + + @Override + public void doInit() { + + config = Config.config; + + initLiquidContainers(); + initRubberChain(); + initFermentation(); + initCrates(); + + //Ic2Recipes.addRecyclerBlacklistItem(ForestryItem.beeQueenGE); + //Ic2Recipes.addRecyclerBlacklistItem(ForestryItem.beePrincessGE); + + // Remove some items from the recycler + registerBackpackItems(); + + if (rubbersapling != null && resin != null) { + String imc = String.format("farmArboreal@%s.%s.%s.%s", + GameData.blockRegistry.getNameForObject(StackUtils.getBlock(rubbersapling)), + rubbersapling.getItemDamage(), + GameData.itemRegistry.getNameForObject(resin.getItem()), + resin.getItemDamage()); + Proxies.log.finest("Sending IMC '%s'.", imc); + FMLInterModComms.sendMessage(Defaults.MOD, "add-farmable-sapling", imc); + } + } + + private void initFermentation() { + plantBall = IC2Items.getItem("plantBall"); + compressedPlantBall = IC2Items.getItem("compressedPlantBall"); + if (plantBall == null || compressedPlantBall == null) { + Proxies.log.fine("No IC2 plantballs found."); + return; + } + + // Add extra recipes + RecipeUtil.injectLeveledRecipe(plantBall, GameMode.getGameMode().getIntegerSetting("fermenter.yield.wheat") * 4, Defaults.LIQUID_BIOMASS); + RecipeUtil.injectLeveledRecipe(compressedPlantBall, GameMode.getGameMode().getIntegerSetting("fermenter.yield.wheat") * 5, Defaults.LIQUID_BIOMASS); + } + + private void initLiquidContainers() { + emptyCell = IC2Items.getItem("cell"); + lavaCell = IC2Items.getItem("lavaCell"); + waterCell = IC2Items.getItem("waterCell"); + if (emptyCell == null || lavaCell == null || waterCell == null) { + Proxies.log.fine("Any of the following IC2 items could not be found: empty cell, water cell, lava cell. Skipped adding IC2 liquid containers."); + return; + } + + LiquidHelper.injectTinContainer(Defaults.LIQUID_LAVA, Defaults.BUCKET_VOLUME, lavaCell, emptyCell); + LiquidHelper.injectTinContainer(Defaults.LIQUID_WATER, Defaults.BUCKET_VOLUME, waterCell, emptyCell); + if (GameMode.getGameMode().getStackSetting("recipe.output.bogearth.can").stackSize > 0) + Proxies.common + .addRecipe(GameMode.getGameMode().getStackSetting("recipe.output.bogearth.can"), + new Object[] { "#Y#", "YXY", "#Y#", Character.valueOf('#'), Blocks.dirt, Character.valueOf('X'), waterCell, Character.valueOf('Y'), + Blocks.sand }); + } + + private void initRubberChain() { + treetap = IC2Items.getItem("treetap"); + resin = IC2Items.getItem("resin"); + rubberwood = IC2Items.getItem("rubberWood"); + rubbersapling = IC2Items.getItem("rubberSapling"); + rubberleaves = IC2Items.getItem("rubberLeaves"); + fuelcanFilled = IC2Items.getItem("filledFuelCan"); + fuelcanEmpty = IC2Items.getItem("fuelCan"); + if (treetap == null || resin == null || rubberwood == null || rubbersapling == null || rubberleaves == null || fuelcanFilled == null + || fuelcanEmpty == null) { + Proxies.log + .fine("Any of the following IC2 blocks and items could not be found: resin, rubber wood, saplings or leaves, filled fuel cans, empty fuel cans. Skipped adding rubber chain."); + return; + } + + // Add extra recipes + RecipeManagers.centrifugeManager.addRecipe(20, ForestryItem.propolis.getItemStack(), resin); + ItemStack fuelcanStack = new ItemStack(fuelcanFilled.getItem(), 1, 0); + NBTTagCompound compound = new NBTTagCompound(); + compound.setInteger("value", 15288); + fuelcanStack.setTagCompound(compound); + RecipeManagers.bottlerManager.addRecipe(20, LiquidHelper.getLiquid(Defaults.LIQUID_ETHANOL, Defaults.BOTTLER_FUELCAN_VOLUME), fuelcanEmpty, fuelcanStack); + + RecipeUtil.injectLeveledRecipe(rubbersapling, GameMode.getGameMode().getIntegerSetting("fermenter.yield.sapling"), Defaults.LIQUID_BIOMASS); + + // Add backpack items + BackpackManager.backpackItems[2].add(rubbersapling); + BackpackManager.backpackItems[2].add(rubberleaves); + // Rubber wood is added via ore dictionary. + } + + private void initCrates() { + resin = IC2Items.getItem("resin"); + rubber = IC2Items.getItem("rubber"); + scrap = IC2Items.getItem("scrap"); + + // Add crates for the IC2 items that exist. + if (resin != null) { + ((ItemCrated) ForestryItem.cratedResin.item()).setContained(ForestryItem.cratedResin.getItemStack(), resin); + } + + if (rubber != null) { + ((ItemCrated) ForestryItem.cratedRubber.item()).setContained(ForestryItem.cratedRubber.getItemStack(), rubber); + } + + if (scrap != null) { + ((ItemCrated) ForestryItem.cratedScrap.item()).setContained(ForestryItem.cratedScrap.getItemStack(), scrap); + } + } + + private void registerBackpackItems() { + if (BackpackManager.backpackItems == null) + return; + + if (resin != null) + BackpackManager.definitions.get("forester").addValidItem(resin); + if (rubber != null) + BackpackManager.definitions.get("forester").addValidItem(rubber); + } + + @Override + public void preInit() { + } + + @Override + public void postInit() { + } +} diff --git a/forestry_common/core/forestry/plugins/PluginManager.java b/forestry_common/core/forestry/plugins/PluginManager.java new file mode 100755 index 000000000..65dfd233f --- /dev/null +++ b/forestry_common/core/forestry/plugins/PluginManager.java @@ -0,0 +1,256 @@ +/******************************************************************************* + * Copyright 2011-2014 by SirSengir + * + * This work is licensed under a Creative Commons Attribution-NonCommercial-NoDerivs 3.0 Unported License. + * + * To view a copy of this license, visit http://creativecommons.org/licenses/by-nc-nd/3.0/. + ******************************************************************************/ +package forestry.plugins; + +import java.io.File; +import java.io.FileInputStream; +import java.util.ArrayList; +import java.util.Arrays; +import java.util.Comparator; +import java.util.zip.ZipEntry; +import java.util.zip.ZipInputStream; + +import cpw.mods.fml.common.IFuelHandler; +import cpw.mods.fml.common.network.IGuiHandler; +import cpw.mods.fml.common.registry.GameRegistry; + +import forestry.api.core.IPlugin; +import forestry.core.ForestryCore; +import forestry.core.interfaces.IOreDictionaryHandler; +import forestry.core.interfaces.IPacketHandler; +import forestry.core.interfaces.IPickupHandler; +import forestry.core.interfaces.IResupplyHandler; +import forestry.core.interfaces.ISaveEventHandler; +import forestry.core.proxy.Proxies; + +public class PluginManager { + + /** + * You can use the API from your own mod or write a simple plugin mod using + * this plugin interface. Adding a plugin here will have Forestry call the + * registered object during ModsLoaded(). See {@link IPlugin} for further + * details. + */ + public static ArrayList plugins = new ArrayList(); + public static ArrayList guiHandlers = new ArrayList(); + public static ArrayList packetHandlers = new ArrayList(); + public static ArrayList pickupHandlers = new ArrayList(); + public static ArrayList saveEventHandlers = new ArrayList(); + public static ArrayList resupplyHandlers = new ArrayList(); + public static ArrayList dictionaryHandlers = new ArrayList(); + + public static void loadPlugins(File modLocation) { + loadIncludedPlugins(modLocation); + loadExternalPlugins(modLocation); + } + + private static void loadIncludedPlugins(File modLocation) { + + ClassLoader classLoader = ForestryCore.class.getClassLoader(); + + // Internal plugin when Forestry is a jar or zip + if (modLocation.isFile() && (modLocation.getName().endsWith(".jar") || modLocation.getName().endsWith(".zip"))) + loadPluginsFromFile(modLocation, classLoader); + else if (modLocation.isDirectory()) + loadPluginsFromBin(modLocation, classLoader); + + } + + private static void loadExternalPlugins(File modLocation) { + + try { + + File pluginDir = new File(Proxies.common.getForestryRoot() + "/mods"); + ClassLoader classLoader = ForestryCore.class.getClassLoader(); + + // Abort if the plugin directory is not there. + if (!pluginDir.isDirectory()) + return; + + File[] fileList = pluginDir.listFiles(); + if (fileList == null) + return; + + for (File file : fileList) { + + if (!file.isFile()) + continue; + + if (!file.getName().endsWith(".jar") && !file.getName().endsWith(".zip")) + continue; + + if (file.getName().equals(modLocation.getName())) + continue; + + loadPluginsFromFile(file, classLoader); + + } + + } catch (Exception ex) { + ex.printStackTrace(); + } + + } + + private static void loadPluginsFromFile(File file, ClassLoader classLoader) { + + String pluginName; + + try { + ZipEntry entry = null; + FileInputStream fileIO = new FileInputStream(file); + ZipInputStream zipIO = new ZipInputStream(fileIO); + + while (true) { + entry = zipIO.getNextEntry(); + + if (entry == null) { + fileIO.close(); + break; + } + + String entryName = entry.getName(); + File entryFile = new File(entryName); + pluginName = entryFile.getName(); + if (!entry.isDirectory() && pluginName.startsWith("Plugin") && pluginName.endsWith(".class")) + PluginManager.addPlugin(classLoader, pluginName, entryFile.getPath().replace(File.separatorChar, '.')); + + } + } catch (Exception ex) { + throw new RuntimeException(ex); + } + + } + + private static String parseClassName(String binpath) { + + String[] tokens = binpath.split("[\\\\/]"); + String packageName = ""; + + for (int i = 0; i < tokens.length; i++) { + if (tokens[i] == null) + break; + if (!tokens[i].equals("bin")) + continue; + + // We are at bin, build the rest and return + for (int j = i + 1; j < tokens.length; j++) { + if (packageName.length() > 0) + packageName += "."; + packageName += tokens[j]; + } + break; + } + + return packageName; + } + + private static void loadPluginsFromBin(File bin, ClassLoader classLoader) { + File[] fileList = bin.listFiles(); + + // ensure consistent sorting across all platforms + Arrays.sort(fileList, new Comparator() { + @Override + public int compare(File a, File b) { + return a.getName().toLowerCase().compareTo(b.getName().toLowerCase()); + } + }); + + for (File file : fileList) { + String pluginName = file.getName(); + + if (file.isFile() && pluginName.startsWith("Plugin") && pluginName.endsWith(".class")) { + PluginManager.addPlugin(classLoader, pluginName, parseClassName(file.getPath())); + } else if (file.isDirectory()) { + loadPluginsFromBin(file, classLoader); + } + } + } + + public static void addPlugin(ClassLoader classLoader, String pluginName, String packageName) { + + if (pluginName.equals("PluginManager.class") || pluginName.equals("PluginInfo.class")) + return; + + String pluginClassName = packageName.replace(".class", "").replace("minecraft.", ""); + + try { + + Class pluginClass = null; + try { + pluginClass = classLoader.loadClass(pluginClassName); + } catch (Throwable error) { + } + + if (pluginClass == null) { + pluginClass = Class.forName(pluginClassName); + } + + if (pluginClass != null) { + + Class clz = pluginClass; + boolean isPlugin = false; + do { + for (Class i : clz.getInterfaces()) { + if (i == IPlugin.class) { + isPlugin = true; + break; + } + } + + clz = clz.getSuperclass(); + } while (clz != null && !isPlugin); + + if (!isPlugin) + return; + + IPlugin plugin = (IPlugin) pluginClass.newInstance(); + if (plugin != null) { + + Proxies.log.fine("Found plugin " + plugin.toString()); + plugins.add(plugin); + + if (plugin instanceof NativePlugin) { + + NativePlugin nplugin = (NativePlugin) plugin; + IGuiHandler guiHandler = nplugin.getGuiHandler(); + if (guiHandler != null) + guiHandlers.add(guiHandler); + + IPacketHandler packetHandler = nplugin.getPacketHandler(); + if (packetHandler != null) + packetHandlers.add(packetHandler); + + IPickupHandler pickupHandler = nplugin.getPickupHandler(); + if (pickupHandler != null) + pickupHandlers.add(pickupHandler); + + ISaveEventHandler saveHandler = nplugin.getSaveEventHandler(); + if (saveHandler != null) + saveEventHandlers.add(saveHandler); + + IResupplyHandler resupplyHandler = nplugin.getResupplyHandler(); + if (resupplyHandler != null) + resupplyHandlers.add(resupplyHandler); + + IOreDictionaryHandler dictionaryHandler = nplugin.getDictionaryHandler(); + if (dictionaryHandler != null) + dictionaryHandlers.add(dictionaryHandler); + } + + if (plugin instanceof IFuelHandler) + GameRegistry.registerFuelHandler((IFuelHandler) plugin); + + } + } + + } catch (Throwable ex) { + // ex.printStackTrace(); + } + } +} diff --git a/forestry_common/energy/forestry/energy/GuiHandlerEnergy.java b/forestry_common/energy/forestry/energy/GuiHandlerEnergy.java new file mode 100755 index 000000000..57e12cbc1 --- /dev/null +++ b/forestry_common/energy/forestry/energy/GuiHandlerEnergy.java @@ -0,0 +1,86 @@ +/******************************************************************************* + * Copyright 2011-2014 by SirSengir + * + * This work is licensed under a Creative Commons Attribution-NonCommercial-NoDerivs 3.0 Unported License. + * + * To view a copy of this license, visit http://creativecommons.org/licenses/by-nc-nd/3.0/. + ******************************************************************************/ +package forestry.energy; + +import net.minecraft.entity.player.EntityPlayer; +import net.minecraft.world.World; + +import forestry.core.GuiHandlerBase; +import forestry.core.network.GuiId; +import forestry.core.network.PacketIds; +import forestry.core.network.PacketSocketUpdate; +import forestry.core.proxy.Proxies; +import forestry.energy.gadgets.EngineBronze; +import forestry.energy.gadgets.EngineCopper; +import forestry.energy.gadgets.EngineTin; +import forestry.energy.gadgets.MachineGenerator; +import forestry.energy.gui.ContainerEngineBronze; +import forestry.energy.gui.ContainerEngineCopper; +import forestry.energy.gui.ContainerEngineTin; +import forestry.energy.gui.ContainerGenerator; +import forestry.energy.gui.GuiEngineBronze; +import forestry.energy.gui.GuiEngineCopper; +import forestry.energy.gui.GuiEngineTin; +import forestry.energy.gui.GuiGenerator; + +public class GuiHandlerEnergy extends GuiHandlerBase { + + @Override + public Object getClientGuiElement(int id, EntityPlayer player, World world, int x, int y, int z) { + + if (id >= GuiId.values().length) + return null; + + switch (GuiId.values()[id]) { + + case EngineBronzeGUI: + return new GuiEngineBronze(player.inventory, (EngineBronze) getTileForestry(world, x, y, z)); + + case EngineCopperGUI: + return new GuiEngineCopper(player.inventory, (EngineCopper) getTileForestry(world, x, y, z)); + + case EngineTinGUI: + return new GuiEngineTin(player.inventory, (EngineTin) getTileForestry(world, x, y, z)); + + case GeneratorGUI: + return new GuiGenerator(player.inventory, (MachineGenerator) getTileForestry(world, x, y, z)); + + default: + return null; + } + } + + @Override + public Object getServerGuiElement(int id, EntityPlayer player, World world, int x, int y, int z) { + + if (id >= GuiId.values().length) + return null; + + switch (GuiId.values()[id]) { + + case EngineBronzeGUI: + return new ContainerEngineBronze(player.inventory, (EngineBronze) getTileForestry(world, x, y, z)); + + case EngineCopperGUI: + return new ContainerEngineCopper(player.inventory, (EngineCopper) getTileForestry(world, x, y, z)); + + case EngineTinGUI: + EngineTin tile = (EngineTin) getTileForestry(world, x, y, z); + Proxies.net.sendToPlayer(new PacketSocketUpdate(PacketIds.SOCKET_UPDATE, x, y, z, tile), player); + return new ContainerEngineTin(player.inventory, tile); + + case GeneratorGUI: + return new ContainerGenerator(player.inventory, (MachineGenerator) getTileForestry(world, x, y, z)); + + default: + return null; + + } + } + +} diff --git a/forestry_common/energy/forestry/energy/circuits/CircuitElectricBoost.java b/forestry_common/energy/forestry/energy/circuits/CircuitElectricBoost.java new file mode 100755 index 000000000..d10ebd54e --- /dev/null +++ b/forestry_common/energy/forestry/energy/circuits/CircuitElectricBoost.java @@ -0,0 +1,18 @@ +/******************************************************************************* + * Copyright 2011-2014 by SirSengir + * + * This work is licensed under a Creative Commons Attribution-NonCommercial-NoDerivs 3.0 Unported License. + * + * To view a copy of this license, visit http://creativecommons.org/licenses/by-nc-nd/3.0/. + ******************************************************************************/ +package forestry.energy.circuits; + +public class CircuitElectricBoost extends CircuitElectricChange { + + public CircuitElectricBoost(String uid, int limit, int eu, int mj, String name, String[] description) { + super(uid, false, name, description); + this.setLimit(limit); + this.configureChange(eu, mj); + } + +} diff --git a/forestry_common/energy/forestry/energy/circuits/CircuitElectricChange.java b/forestry_common/energy/forestry/energy/circuits/CircuitElectricChange.java new file mode 100755 index 000000000..f15acf4f7 --- /dev/null +++ b/forestry_common/energy/forestry/energy/circuits/CircuitElectricChange.java @@ -0,0 +1,60 @@ +/******************************************************************************* + * Copyright 2011-2014 by SirSengir + * + * This work is licensed under a Creative Commons Attribution-NonCommercial-NoDerivs 3.0 Unported License. + * + * To view a copy of this license, visit http://creativecommons.org/licenses/by-nc-nd/3.0/. + ******************************************************************************/ +package forestry.energy.circuits; + +import net.minecraft.tileentity.TileEntity; + +import forestry.core.circuits.Circuit; +import forestry.energy.gadgets.EngineTin; + +public abstract class CircuitElectricChange extends Circuit { + + int euChange = 7; + int mjChange = 2; + + public CircuitElectricChange(String uid, boolean requiresDiscovery, String name, String[] descriptions) { + super(uid, requiresDiscovery, name, descriptions); + } + + protected void configureChange(int euChange, int mjChange) { + this.euChange = euChange; + this.mjChange = mjChange; + } + + @Override + public boolean isCircuitable(TileEntity tile) { + return tile instanceof EngineTin; + } + + @Override + public void onInsertion(int slot, TileEntity tile) { + if (!isCircuitable(tile)) + return; + + EngineTin engine = (EngineTin) tile; + engine.changeEnergyConfig(euChange, mjChange, 2 * euChange); + } + + @Override + public void onLoad(int slot, TileEntity tile) { + onInsertion(slot, tile); + } + + @Override + public void onRemoval(int slot, TileEntity tile) { + if (!isCircuitable(tile)) + return; + + EngineTin engine = (EngineTin) tile; + engine.changeEnergyConfig(-euChange, -mjChange, -(2 * euChange)); + } + + @Override + public void onTick(int slot, TileEntity tile) { + } +} diff --git a/forestry_common/energy/forestry/energy/circuits/CircuitElectricChoke.java b/forestry_common/energy/forestry/energy/circuits/CircuitElectricChoke.java new file mode 100755 index 000000000..e3653514d --- /dev/null +++ b/forestry_common/energy/forestry/energy/circuits/CircuitElectricChoke.java @@ -0,0 +1,17 @@ +/******************************************************************************* + * Copyright 2011-2014 by SirSengir + * + * This work is licensed under a Creative Commons Attribution-NonCommercial-NoDerivs 3.0 Unported License. + * + * To view a copy of this license, visit http://creativecommons.org/licenses/by-nc-nd/3.0/. + ******************************************************************************/ +package forestry.energy.circuits; + +public class CircuitElectricChoke extends CircuitElectricChange { + + public CircuitElectricChoke(String uid) { + super(uid, false, "electric.choke.1", new String[] { "Reduces ouput by 1 MJ/t", "Reduces intake by 2 EU/t" }); + this.configureChange(-2, -1); + this.setLimit(1); + } +} diff --git a/forestry_common/energy/forestry/energy/circuits/CircuitElectricEfficiency.java b/forestry_common/energy/forestry/energy/circuits/CircuitElectricEfficiency.java new file mode 100755 index 000000000..5c7dced1f --- /dev/null +++ b/forestry_common/energy/forestry/energy/circuits/CircuitElectricEfficiency.java @@ -0,0 +1,18 @@ +/******************************************************************************* + * Copyright 2011-2014 by SirSengir + * + * This work is licensed under a Creative Commons Attribution-NonCommercial-NoDerivs 3.0 Unported License. + * + * To view a copy of this license, visit http://creativecommons.org/licenses/by-nc-nd/3.0/. + ******************************************************************************/ +package forestry.energy.circuits; + +public class CircuitElectricEfficiency extends CircuitElectricChange { + + public CircuitElectricEfficiency(String uid) { + super(uid, false, "electric.efficiency.1", new String[] { "Reduces intake by 1 EU/t" }); + this.setLimit(1); + this.configureChange(-1, 0); + } + +} diff --git a/forestry_common/energy/forestry/energy/circuits/CircuitFireDampener.java b/forestry_common/energy/forestry/energy/circuits/CircuitFireDampener.java new file mode 100755 index 000000000..5b53df9a2 --- /dev/null +++ b/forestry_common/energy/forestry/energy/circuits/CircuitFireDampener.java @@ -0,0 +1,46 @@ +/******************************************************************************* + * Copyright 2011-2014 by SirSengir + * + * This work is licensed under a Creative Commons Attribution-NonCommercial-NoDerivs 3.0 Unported License. + * + * To view a copy of this license, visit http://creativecommons.org/licenses/by-nc-nd/3.0/. + ******************************************************************************/ +package forestry.energy.circuits; + +import net.minecraft.tileentity.TileEntity; + +import forestry.core.circuits.Circuit; +import forestry.energy.gadgets.EngineCopper; + +public class CircuitFireDampener extends Circuit { + + public CircuitFireDampener(String uid) { + super(uid, false, "dampener.1", new String[] { "Reduces maximum output to 1 MJ/t", "Preserves fuel output" }); + } + + @Override + public boolean isCircuitable(TileEntity tile) { + return tile instanceof EngineCopper; + } + + @Override + public void onInsertion(int slot, TileEntity tile) { + if (!isCircuitable(tile)) + return; + + } + + @Override + public void onLoad(int slot, TileEntity tile) { + onInsertion(slot, tile); + } + + @Override + public void onRemoval(int slot, TileEntity tile) { + } + + @Override + public void onTick(int slot, TileEntity tile) { + } + +} diff --git a/forestry_common/energy/forestry/energy/gadgets/EngineBronze.java b/forestry_common/energy/forestry/energy/gadgets/EngineBronze.java new file mode 100755 index 000000000..c6ce3931e --- /dev/null +++ b/forestry_common/energy/forestry/energy/gadgets/EngineBronze.java @@ -0,0 +1,464 @@ +/******************************************************************************* + * Copyright 2011-2014 by SirSengir + * + * This work is licensed under a Creative Commons Attribution-NonCommercial-NoDerivs 3.0 Unported License. + * + * To view a copy of this license, visit http://creativecommons.org/licenses/by-nc-nd/3.0/. + ******************************************************************************/ +package forestry.energy.gadgets; + +import net.minecraft.entity.player.EntityPlayer; +import net.minecraft.inventory.Container; +import net.minecraft.inventory.ICrafting; +import net.minecraft.item.ItemStack; +import net.minecraft.nbt.NBTTagCompound; + +import net.minecraftforge.common.util.ForgeDirection; +import net.minecraftforge.fluids.Fluid; +import net.minecraftforge.fluids.FluidContainerRegistry.FluidContainerData; +import net.minecraftforge.fluids.FluidRegistry; +import net.minecraftforge.fluids.FluidStack; + +import buildcraft.api.inventory.ISpecialInventory; + +import forestry.api.core.ForestryAPI; +import forestry.api.fuels.EngineBronzeFuel; +import forestry.api.fuels.FuelManager; +import forestry.core.EnumErrorCode; +import forestry.core.config.Config; +import forestry.core.config.Defaults; +import forestry.core.gadgets.Engine; +import forestry.core.gadgets.TileBase; +import forestry.core.interfaces.ILiquidTankContainer; +import forestry.core.network.GuiId; +import forestry.core.network.PacketPayload; +import forestry.core.utils.ForestryTank; +import forestry.core.utils.LiquidHelper; +import forestry.core.utils.TileInventoryAdapter; + +public class EngineBronze extends Engine implements ISpecialInventory, ILiquidTankContainer { + + /* CONSTANTS */ + public static final short SLOT_CAN = 0; + + /* NETWORK */ + @Override + public PacketPayload getPacketPayload() { + PacketPayload payload = super.getPacketPayload(); + + if (shutdown) + payload.append(new int[] { 1 }); + else + payload.append(new int[] { 0 }); + + return payload; + } + + @Override + public void fromPacketPayload(PacketPayload payload) { + super.fromPacketPayload(payload); + + if (payload.intPayload[3] > 0) + shutdown = true; + else + shutdown = false; + } + public ForestryTank fuelTank = new ForestryTank(Defaults.ENGINE_TANK_CAPACITY); + public ForestryTank heatingTank = new ForestryTank(Defaults.ENGINE_TANK_CAPACITY); + private final TileInventoryAdapter inventory; + public int burnTime; + public int totalTime; + public int currentFluidId = -1; + /** + * true if the engine is too cold and needs to warm itself up. + */ + private boolean shutdown; + + public EngineBronze() { + super(Defaults.ENGINE_BRONZE_HEAT_MAX, 30000, 500); + setHints(Config.hints.get("engine.bronze")); + + inventory = new TileInventoryAdapter(this, 1, "Items"); + } + + @Override + public void openGui(EntityPlayer player, TileBase tile) { + player.openGui(ForestryAPI.instance, GuiId.EngineBronzeGUI.ordinal(), player.worldObj, xCoord, yCoord, zCoord); + } + + @Override + public void updateServerSide() { + + super.updateServerSide(); + + // Check if we have suitable items waiting in the item slot + if (inventory.getStackInSlot(SLOT_CAN) != null) { + + FluidContainerData container = LiquidHelper.getLiquidContainer(inventory.getStackInSlot(SLOT_CAN)); + if (container != null) { + + ForestryTank tank = null; + + if (container.fluid.isFluidEqual(LiquidHelper.getLiquid(Defaults.LIQUID_LAVA, 1))) + tank = heatingTank; + else if (FuelManager.bronzeEngineFuel.containsKey(container.fluid)) + tank = fuelTank; + + if (tank != null) { + inventory.setInventorySlotContents(SLOT_CAN, replenishByContainer(inventory.getStackInSlot(SLOT_CAN), container, tank)); + if (inventory.getStackInSlot(SLOT_CAN).stackSize <= 0) + inventory.setInventorySlotContents(0, null); + } + } + } + + if (worldObj.getTotalWorldTime() % 20 * 10 != 0) + return; + + if (getHeatLevel() <= 0.2 && heatingTank.getFluidAmount() <= 0) + setErrorState(EnumErrorCode.NOHEAT); + else if (burnTime <= 0 && fuelTank.getFluidAmount() <= 0) + setErrorState(EnumErrorCode.NOFUEL); + else + setErrorState(EnumErrorCode.OK); + } + + /** + * Burns fuel increasing stored energy + */ + @Override + public void burn() { + + currentOutput = 0; + + if (isActivated() && (fuelTank.getFluidAmount() >= Defaults.BUCKET_VOLUME || burnTime > 0)) { + + double heatStage = getHeatLevel(); + + // If we have reached a safe temperature, we reenable energy + // transfer + if (heatStage > 0.25 && shutdown) + shutdown(false); + else if (shutdown) + if (heatingTank.getFluidAmount() > 0 && heatingTank.getFluid().getFluid().getName().equals(Defaults.LIQUID_LAVA)) { + addHeat(Defaults.ENGINE_HEAT_VALUE_LAVA); + heatingTank.drain(1, true); + } + + // We need a minimum temperature to generate energy + if (heatStage > 0.2) { + + if (burnTime > 0) { + burnTime--; + currentOutput = determineFuelValue(FluidRegistry.getFluid(currentFluidId)); + addEnergy(currentOutput); + } else { + burnTime = totalTime = this.determineBurnTime(fuelTank.getFluid().getFluid()); + currentFluidId = fuelTank.getFluid().getFluid().getID(); + fuelTank.drain(Defaults.BUCKET_VOLUME, true); + } + + } else + shutdown(true); + } + + if(burnTime <= 0) + currentFluidId = -1; + } + + private void shutdown(boolean val) { + shutdown = val; + } + + @Override + public int dissipateHeat() { + if (heat <= 0) + return 0; + + int loss = 1; // Basic loss even when running + + if (!isBurning()) + loss++; + + double heatStage = getHeatLevel(); + if (heatStage > 0.55) + loss++; + + // Lose extra heat when using water as fuel. + EngineBronzeFuel fuel = FuelManager.bronzeEngineFuel.get(fuelTank.getFluid()); + if (fuel != null) + loss = loss * fuel.dissipationMultiplier; + + heat -= loss; + return loss; + } + + @Override + public int generateHeat() { + + int generate = 0; + + if (isActivated() && burnTime > 0) { + double heatStage = getHeatLevel(); + if (heatStage >= 0.75) + generate += Defaults.ENGINE_BRONZE_HEAT_GENERATION_ENERGY * 3; + else if (heatStage > 0.24) + generate += Defaults.ENGINE_BRONZE_HEAT_GENERATION_ENERGY * 2; + else if (heatStage > 0.2) + generate += Defaults.ENGINE_BRONZE_HEAT_GENERATION_ENERGY; + } + + heat += generate; + return generate; + + } + + /** + * Returns the fuel value (power per cycle) an item of the passed ItemStack + * provides + * + * @param item + * @return + */ + private int determineFuelValue(Fluid fluid) { + if (FuelManager.bronzeEngineFuel.containsKey(fluid)) + return FuelManager.bronzeEngineFuel.get(fluid).powerPerCycle; + else + return 0; + } + + /** + * + * @param fuelid + * @return Duration of burn cycle of one bucket + */ + private int determineBurnTime(Fluid item) { + if (FuelManager.bronzeEngineFuel.containsKey(item)) + return FuelManager.bronzeEngineFuel.get(item).burnDuration; + else + return 0; + } + + // / STATE INFORMATION + @Override + public boolean isBurning() { + return mayBurn() && burnTime > 0; + } + + @Override + public int getBurnTimeRemainingScaled(int i) { + if (totalTime == 0) + return 0; + + return (burnTime * i) / totalTime; + } + + public int getOperatingTemperatureScaled(int i) { + return (int) Math.round((heat * i) / (maxHeat * 0.2)); + } + + public int getFuelScaled(int i) { + return (fuelTank.getFluidAmount() * i) / Defaults.ENGINE_TANK_CAPACITY; + } + + public int getHeatingFuelScaled(int i) { + return (heatingTank.getFluidAmount() * i) / Defaults.ENGINE_TANK_CAPACITY; + } + + /** + * Reads saved data + */ + @Override + public void readFromNBT(NBTTagCompound nbt) { + + super.readFromNBT(nbt); + + burnTime = nbt.getInteger("EngineBurnTime"); + totalTime = nbt.getInteger("EngineTotalTime"); + + if (nbt.hasKey("currentFluid")) { + Fluid fluid = FluidRegistry.getFluid(nbt.getString("currentFluid")); + if (fluid != null) + currentFluidId = fluid.getID(); + } + + fuelTank = new ForestryTank(Defaults.ENGINE_TANK_CAPACITY); + heatingTank = new ForestryTank(Defaults.ENGINE_TANK_CAPACITY); + if (nbt.hasKey("FuelSlot")) { + fuelTank.readFromNBT(nbt.getCompoundTag("FuelSlot")); + heatingTank.readFromNBT(nbt.getCompoundTag("HeatingSlot")); + } + + inventory.readFromNBT(nbt); + + } + + /** + * Writes data to save + */ + @Override + public void writeToNBT(NBTTagCompound nbt) { + + super.writeToNBT(nbt); + + nbt.setInteger("EngineBurnTime", burnTime); + nbt.setInteger("EngineTotalTime", totalTime); + + Fluid fluid = FluidRegistry.getFluid(currentFluidId); + if (fluid != null) + nbt.setString("currentFluid", fluid.getName()); + + NBTTagCompound nbtFuelSlot = new NBTTagCompound(); + NBTTagCompound nbtHeatingSlot = new NBTTagCompound(); + + fuelTank.writeToNBT(nbtFuelSlot); + heatingTank.writeToNBT(nbtHeatingSlot); + + nbt.setTag("FuelSlot", nbtFuelSlot); + nbt.setTag("HeatingSlot", nbtHeatingSlot); + + inventory.writeToNBT(nbt); + } + + /* GUI */ + @Override + public void getGUINetworkData(int id, int data) { + + switch (id) { + case 0: + burnTime = data; + break; + case 1: + totalTime = data; + break; + case 2: + currentOutput = data; + break; + case 3: + storedEnergy = data; + break; + case 4: + heat = data; + break; + case 5: + currentFluidId = data; + break; + } + } + + @Override + public void sendGUINetworkData(Container containerEngine, ICrafting iCrafting) { + iCrafting.sendProgressBarUpdate(containerEngine, 0, burnTime); + iCrafting.sendProgressBarUpdate(containerEngine, 1, totalTime); + iCrafting.sendProgressBarUpdate(containerEngine, 2, currentOutput); + iCrafting.sendProgressBarUpdate(containerEngine, 3, (int) storedEnergy); + iCrafting.sendProgressBarUpdate(containerEngine, 4, heat); + iCrafting.sendProgressBarUpdate(containerEngine, 5, currentFluidId); + } + + /* IINVENTORY */ + @Override + public int getSizeInventory() { + return inventory.getSizeInventory(); + } + + @Override + public ItemStack getStackInSlot(int i) { + return inventory.getStackInSlot(i); + } + + @Override + public void setInventorySlotContents(int i, ItemStack itemstack) { + inventory.setInventorySlotContents(i, itemstack); + } + + @Override + public ItemStack decrStackSize(int i, int j) { + return inventory.decrStackSize(i, j); + } + + @Override + public ItemStack getStackInSlotOnClosing(int slot) { + return inventory.getStackInSlotOnClosing(slot); + } + + @Override + public int getInventoryStackLimit() { + return inventory.getInventoryStackLimit(); + } + + @Override + public void openInventory() { + } + + @Override + public void closeInventory() { + } + + /** + * TODO: just a specialsource workaround + */ + @Override + public boolean isUseableByPlayer(EntityPlayer player) { + return super.isUseableByPlayer(player); + } + + /** + * TODO: just a specialsource workaround + */ + @Override + public String getInventoryName() { + return super.getInventoryName(); + } + + /** + * TODO: just a specialsource workaround + */ + @Override + public boolean hasCustomInventoryName() { + return super.hasCustomInventoryName(); + } + + /** + * TODO: just a specialsource workaround + */ + @Override + public boolean isItemValidForSlot(int slotIndex, ItemStack itemstack) { + return super.isItemValidForSlot(slotIndex, itemstack); + } + + /* ISPECIALINVENTORY */ + @Override + public int addItem(ItemStack stack, boolean doAdd, ForgeDirection from) { + FluidContainerData container = LiquidHelper.getLiquidContainer(stack); + if (container == null) + return 0; + + return inventory.addStack(stack, false, doAdd); + } + + @Override + public ItemStack[] extractItem(boolean doRemove, ForgeDirection from, int maxItemCount) { + return null; + } + + // / ITANKCONTAINER + @Override + public int fill(ForgeDirection from, FluidStack resource, boolean doFill) { + // We only accept biomass and water as fuel + int used = 0; + + if (FuelManager.bronzeEngineFuel.containsKey(resource)) + used = fuelTank.fill(resource, doFill); + + if (LiquidHelper.isLiquid(Defaults.LIQUID_LAVA, resource)) + used = heatingTank.fill(resource, doFill); + + return used; + } + + @Override + public ForestryTank[] getTanks() { + return new ForestryTank[] { fuelTank, heatingTank }; + } +} diff --git a/forestry_common/energy/forestry/energy/gadgets/EngineClockwork.java b/forestry_common/energy/forestry/energy/gadgets/EngineClockwork.java new file mode 100755 index 000000000..c190bbd24 --- /dev/null +++ b/forestry_common/energy/forestry/energy/gadgets/EngineClockwork.java @@ -0,0 +1,148 @@ +/******************************************************************************* + * Copyright 2011-2014 by SirSengir + * + * This work is licensed under a Creative Commons Attribution-NonCommercial-NoDerivs 3.0 Unported License. + * + * To view a copy of this license, visit http://creativecommons.org/licenses/by-nc-nd/3.0/. + ******************************************************************************/ +package forestry.energy.gadgets; + +import net.minecraft.entity.player.EntityPlayer; +import net.minecraft.entity.player.EntityPlayerMP; +import net.minecraft.inventory.Container; +import net.minecraft.inventory.ICrafting; +import net.minecraft.nbt.NBTTagCompound; + +import forestry.core.TemperatureState; +import forestry.core.config.Defaults; +import forestry.core.gadgets.Engine; +import forestry.core.gadgets.TileBase; +import forestry.core.utils.DamageSourceForestry; + +public class EngineClockwork extends Engine { + + private final static float WIND_EXHAUSTION = 0.05f; + private final static float WIND_TENSION_BASE = 0.5f; + private final static int WIND_DELAY = 10; + + private static final int ENGINE_CLOCKWORK_HEAT_MAX = 300000; + private static final float ENGINE_CLOCKWORK_ENERGY_PER_CYCLE = 0.25f; + private static final float ENGINE_CLOCKWORK_WIND_MAX = 8f; + + private static final DamageSourceForestry damageSourceEngineClockwork = new DamageSourceForestry("engine.clockwork"); + + private float tension = 0.0f; + private short delay = 0; + + public EngineClockwork() { + super(ENGINE_CLOCKWORK_HEAT_MAX, 1000, 50); + } + + @Override + public void openGui(EntityPlayer player, TileBase tile) { + + if(!(player instanceof EntityPlayerMP)) + return; + + if(tension <= 0) + tension = WIND_TENSION_BASE; + else if(tension < ENGINE_CLOCKWORK_WIND_MAX + WIND_TENSION_BASE) { + tension += (ENGINE_CLOCKWORK_WIND_MAX + WIND_TENSION_BASE - tension) / (ENGINE_CLOCKWORK_WIND_MAX + WIND_TENSION_BASE) * WIND_TENSION_BASE; + } else + return; + + player.addExhaustion(WIND_EXHAUSTION); + if(tension > ENGINE_CLOCKWORK_WIND_MAX + (0.1*WIND_TENSION_BASE)) + player.attackEntityFrom(damageSourceEngineClockwork, 6); + tension = tension > ENGINE_CLOCKWORK_WIND_MAX + WIND_TENSION_BASE ? ENGINE_CLOCKWORK_WIND_MAX + WIND_TENSION_BASE : tension; + delay = WIND_DELAY; + sendNetworkUpdate(); + } + + /* LOADING & SAVING */ + @Override + public void readFromNBT(NBTTagCompound nbttagcompound) { + super.readFromNBT(nbttagcompound); + tension = nbttagcompound.getFloat("Wound"); + } + + @Override + public void writeToNBT(NBTTagCompound nbttagcompound) { + super.writeToNBT(nbttagcompound); + nbttagcompound.setFloat("Wound", tension); + } + + @Override + public boolean isActivated() { + return true; + } + + @Override + public int dissipateHeat() { + return 0; + } + + @Override + public int generateHeat() { + return 0; + } + + @Override + public boolean mayBurn() { + return true; + } + + @Override + public void burn() { + + heat = (int)(tension * 10000); + + if(delay > 0) { + delay--; + return; + } + + if(!isBurning()) + return; + + if(tension > 0.01f) + tension *= 0.9995f; + else + tension = 0; + addEnergy(ENGINE_CLOCKWORK_ENERGY_PER_CYCLE * tension); + } + + @Override + public boolean isBurning() { + return tension > 0; + } + + @Override + public TemperatureState getTemperatureState() { + double scaled = (heat / 10000) / ENGINE_CLOCKWORK_WIND_MAX; + + if (scaled < 0.20) + return TemperatureState.COOL; + else if (scaled < 0.45) + return TemperatureState.WARMED_UP; + else if (scaled < 0.65) + return TemperatureState.OPERATING_TEMPERATURE; + else if (scaled < 0.85) + return TemperatureState.RUNNING_HOT; + else + return TemperatureState.OVERHEATING; + } + + @Override + public float getPistonSpeed() { + if(delay > 0) + return 0; + + float fromClockwork = (tension / ENGINE_CLOCKWORK_WIND_MAX) * Defaults.ENGINE_PISTON_SPEED_MAX; + return fromClockwork >= 0.01f ? fromClockwork : storedEnergy > 0 ? 0.01f : 0; + } + + @Override public void getGUINetworkData(int i, int j) {} + @Override public void sendGUINetworkData(Container containerEngine, ICrafting iCrafting) {} + +} diff --git a/forestry_common/energy/forestry/energy/gadgets/EngineCopper.java b/forestry_common/energy/forestry/energy/gadgets/EngineCopper.java new file mode 100755 index 000000000..6d86111a5 --- /dev/null +++ b/forestry_common/energy/forestry/energy/gadgets/EngineCopper.java @@ -0,0 +1,511 @@ +/******************************************************************************* + * Copyright 2011-2014 by SirSengir + * + * This work is licensed under a Creative Commons Attribution-NonCommercial-NoDerivs 3.0 Unported License. + * + * To view a copy of this license, visit http://creativecommons.org/licenses/by-nc-nd/3.0/. + ******************************************************************************/ +package forestry.energy.gadgets; + +import java.util.ArrayList; +import java.util.LinkedList; + +import net.minecraft.entity.player.EntityPlayer; +import net.minecraft.inventory.Container; +import net.minecraft.inventory.ICrafting; +import net.minecraft.inventory.ISidedInventory; +import net.minecraft.item.Item; +import net.minecraft.item.ItemStack; +import net.minecraft.nbt.NBTTagCompound; + +import cpw.mods.fml.common.registry.GameData; + +import net.minecraftforge.common.util.ForgeDirection; + +import buildcraft.api.gates.ITrigger; +import buildcraft.api.inventory.ISpecialInventory; + +import forestry.api.core.ForestryAPI; +import forestry.api.fuels.FuelManager; +import forestry.core.EnumErrorCode; +import forestry.core.TemperatureState; +import forestry.core.config.Config; +import forestry.core.config.Defaults; +import forestry.core.config.ForestryItem; +import forestry.core.gadgets.Engine; +import forestry.core.gadgets.TileBase; +import forestry.core.network.GuiId; +import forestry.core.triggers.ForestryTrigger; +import forestry.core.utils.BlockUtil; +import forestry.core.utils.InventoryAdapter; +import forestry.core.utils.TileInventoryAdapter; + +public class EngineCopper extends Engine implements ISpecialInventory, ISidedInventory { + + /* CONSTANTS */ + public static final short SLOT_FUEL = 0; + public static final short SLOT_WASTE_1 = 1; + public static final short SLOT_WASTE_COUNT = 4; + + /* MEMBERS */ + private Item fuelItem; + private int fuelItemMeta; + private int burnTime; + private int totalBurnTime; + private int ashProduction; + private final int ashForItem; + + private final TileInventoryAdapter inventory; + + public EngineCopper() { + super(Defaults.ENGINE_COPPER_HEAT_MAX, 20000, 400); + setHints(Config.hints.get("engine.copper")); + + ashForItem = Defaults.ENGINE_COPPER_ASH_FOR_ITEM; + inventory = new TileInventoryAdapter(this, 5, "Items"); + } + + @Override + public void openGui(EntityPlayer player, TileBase tile) { + player.openGui(ForestryAPI.instance, GuiId.EngineCopperGUI.ordinal(), player.worldObj, xCoord, yCoord, zCoord); + } + + private int getFuelSlot() { + + if (inventory.getStackInSlot(SLOT_FUEL) == null) + return -1; + + if (determineFuelValue(inventory.getStackInSlot(SLOT_FUEL)) > 0) + return SLOT_FUEL; + + return -1; + } + + private int getFreeWasteSlot() { + + for (int i = SLOT_WASTE_1; i <= SLOT_WASTE_COUNT; i++) { + if (inventory.getStackInSlot(i) == null) + return i; + if (!ForestryItem.ash.isItemEqual(inventory.getStackInSlot(i))) + continue; + + if (inventory.getStackInSlot(i).stackSize < 64) + return i; + } + + return -1; + } + + @Override + public void updateServerSide() { + + super.updateServerSide(); + + if (worldObj.getTotalWorldTime() % 20 * 10 != 0) + return; + + if (mayBurn() && burnTime > 0) { + setErrorState(EnumErrorCode.OK); + return; + } else if (forceCooldown) { + setErrorState(EnumErrorCode.FORCEDCOOLDOWN); + return; + } + + int fuelSlot = getFuelSlot(); + if (fuelSlot >= 0 && determineBurnDuration(inventory.getStackInSlot(fuelSlot)) > 0) + setErrorState(EnumErrorCode.OK); + else + setErrorState(EnumErrorCode.NOFUEL); + } + + @Override + public void burn() { + + currentOutput = 0; + + if (burnTime > 0) { + burnTime--; + addAsh(1); + + if (isActivated()) { + currentOutput = determineFuelValue(new ItemStack(fuelItem, 1, fuelItemMeta)); + addEnergy(currentOutput); + } + } else if (isActivated()) { + int fuelslot = getFuelSlot(); + int wasteslot = getFreeWasteSlot(); + + if (fuelslot >= 0 && wasteslot >= 0) { + burnTime = totalBurnTime = determineBurnDuration(inventory.getStackInSlot(fuelslot)); + if (burnTime > 0) { + fuelItem = inventory.getStackInSlot(fuelslot).getItem(); + decrStackSize(fuelslot, 1); + } + } + } + } + + @Override + public int dissipateHeat() { + if (heat <= 0) + return 0; + + int loss = 0; + + if (!isBurning()) + loss += 1; + + TemperatureState tempState = getTemperatureState(); + if (tempState == TemperatureState.OVERHEATING || tempState == TemperatureState.OPERATING_TEMPERATURE) + loss += 1; + + heat -= loss; + return loss; + } + + @Override + public int generateHeat() { + + int heat = 0; + + if (isBurning()) { + heat++; + if (((double) storedEnergy / (double) maxEnergy) > 0.5) + heat++; + } + + addHeat(heat); + return heat; + } + + private void addAsh(int amount) { + + ashProduction += amount; + if (ashProduction < ashForItem) + return; + + // If we have reached the necessary amount, we need to add ash + int wasteslot = getFreeWasteSlot(); + if (wasteslot >= 0) + if (inventory.getStackInSlot(wasteslot) == null) + inventory.setInventorySlotContents(wasteslot, ForestryItem.ash.getItemStack()); + else + inventory.getStackInSlot(wasteslot).stackSize++; + // Reset + ashProduction = 0; + // try to dump stash + dumpStash(); + } + + /** + * Returns the fuel value (power per cycle) an item of the passed ItemStack provides + * + * @param item + * @return + */ + private int determineFuelValue(ItemStack fuel) { + if (FuelManager.copperEngineFuel.containsKey(fuel)) + return FuelManager.copperEngineFuel.get(fuel).powerPerCycle; + else + return 0; + } + + /** + * Returns the fuel value (power per cycle) an item of the passed ItemStack provides + * + * @param item + * @return + */ + private int determineBurnDuration(ItemStack fuel) { + if (FuelManager.copperEngineFuel.containsKey(fuel)) + return FuelManager.copperEngineFuel.get(fuel).burnDuration; + else + return 0; + } + + private void dumpStash() { + ForgeDirection[] pipes = BlockUtil.getPipeDirections(worldObj, Coords(), ForgeDirection.UNKNOWN); + + if (pipes.length > 0) + dumpToPipe(pipes); + } + + private void dumpToPipe(ForgeDirection[] pipes) { + + for (int i = SLOT_WASTE_1; i < SLOT_WASTE_1 + SLOT_WASTE_COUNT; i++) { + if (inventory.getStackInSlot(i) == null) + continue; + if (inventory.getStackInSlot(i).stackSize <= 0) + continue; + + ArrayList filtered; + filtered = BlockUtil.filterPipeDirections(pipes, new ForgeDirection[] { getOrientation() }); + + while (inventory.getStackInSlot(i).stackSize > 0 && filtered.size() > 0) + BlockUtil.putFromStackIntoPipe(this, filtered, inventory.getStackInSlot(i)); + + if (inventory.getStackInSlot(i).stackSize <= 0) + inventory.setInventorySlotContents(i, null); + } + } + + // / STATE INFORMATION + + @Override + public boolean isBurning() { + return mayBurn() && burnTime > 0; + } + + @Override + public int getBurnTimeRemainingScaled(int i) { + if (totalBurnTime == 0) + return 0; + + return (burnTime * i) / totalBurnTime; + } + + @Override + public boolean hasFuelMin(float percentage) { + int fuelSlot = this.getFuelSlot(); + if (fuelSlot < 0) + return false; + + return ((float) inventory.getStackInSlot(fuelSlot).stackSize / (float) inventory.getStackInSlot(fuelSlot).getMaxStackSize()) > percentage; + } + + // / LOADING AND SAVING + /** + * Reads saved data + */ + @Override + public void readFromNBT(NBTTagCompound nbttagcompound) { + super.readFromNBT(nbttagcompound); + + String fuelItemName = nbttagcompound.getString("EngineFuelItem"); + + if (!fuelItemName.isEmpty()) fuelItem = GameData.itemRegistry.getObject(fuelItemName); + + fuelItemMeta = nbttagcompound.getInteger("EngineFuelMeta"); + burnTime = nbttagcompound.getInteger("EngineBurnTime"); + totalBurnTime = nbttagcompound.getInteger("EngineTotalTime"); + if (nbttagcompound.hasKey("AshProduction")) + ashProduction = nbttagcompound.getInteger("AshProduction"); + + // Fuel + inventory.readFromNBT(nbttagcompound); + } + + /** + * Writes data to save + */ + @Override + public void writeToNBT(NBTTagCompound nbttagcompound) { + super.writeToNBT(nbttagcompound); + + if (fuelItem != null) { + nbttagcompound.setString("EngineFuelItem", GameData.itemRegistry.getNameForObject(fuelItem)); + } + + nbttagcompound.setInteger("EngineFuelMeta", fuelItemMeta); + nbttagcompound.setInteger("EngineBurnTime", burnTime); + nbttagcompound.setInteger("EngineTotalTime", totalBurnTime); + nbttagcompound.setInteger("AshProduction", ashProduction); + + inventory.writeToNBT(nbttagcompound); + } + + // / SMP GUI + @Override + public void getGUINetworkData(int i, int j) { + + switch (i) { + case 0: + burnTime = j; + break; + case 1: + totalBurnTime = j; + break; + case 2: + currentOutput = j; + break; + case 3: + storedEnergy = j; + break; + case 4: + heat = j; + break; + } + } + + @Override + public void sendGUINetworkData(Container containerEngine, ICrafting iCrafting) { + iCrafting.sendProgressBarUpdate(containerEngine, 0, burnTime); + iCrafting.sendProgressBarUpdate(containerEngine, 1, totalBurnTime); + iCrafting.sendProgressBarUpdate(containerEngine, 2, currentOutput); + iCrafting.sendProgressBarUpdate(containerEngine, 3, (int)storedEnergy); + iCrafting.sendProgressBarUpdate(containerEngine, 4, heat); + } + + // / IINVENTORY + @Override + public int getSizeInventory() { + return inventory.getSizeInventory(); + } + + @Override + public ItemStack getStackInSlot(int i) { + return inventory.getStackInSlot(i); + } + + @Override + public void setInventorySlotContents(int i, ItemStack itemstack) { + inventory.setInventorySlotContents(i, itemstack); + } + + @Override + public ItemStack decrStackSize(int i, int j) { + return inventory.decrStackSize(i, j); + } + + @Override + public ItemStack getStackInSlotOnClosing(int slot) { + return inventory.getStackInSlotOnClosing(slot); + } + + @Override + public int getInventoryStackLimit() { + return inventory.getInventoryStackLimit(); + } + + @Override + public void openInventory() { + } + + @Override + public void closeInventory() { + } + + /** + * TODO: just a specialsource workaround + */ + @Override + public boolean isUseableByPlayer(EntityPlayer player) { + return super.isUseableByPlayer(player); + } + + /** + * TODO: just a specialsource workaround + */ + @Override + public String getInventoryName() { + return super.getInventoryName(); + } + + /** + * TODO: just a specialsource workaround + */ + @Override + public boolean hasCustomInventoryName() { + return super.hasCustomInventoryName(); + } + + /** + * TODO: just a specialsource workaround + */ + @Override + public boolean isItemValidForSlot(int slotIndex, ItemStack itemstack) { + return super.isItemValidForSlot(slotIndex, itemstack); + } + + /** + * TODO: just a specialsource workaround + */ + @Override + public boolean canInsertItem(int i, ItemStack itemstack, int j) { + return super.canInsertItem(i, itemstack, j); + } + + /** + * TODO: just a specialsource workaround + */ + @Override + public boolean canExtractItem(int i, ItemStack itemstack, int j) { + return super.canExtractItem(i, itemstack, j); + } + + /** + * TODO: just a specialsource workaround + */ + @Override + public int[] getAccessibleSlotsFromSide(int side) { + return super.getAccessibleSlotsFromSide(side); + } + + /* ISIDEDINVENTORY */ + @Override + public InventoryAdapter getInternalInventory() { + return inventory; + } + + @Override + protected boolean canTakeStackFromSide(int slotIndex, ItemStack itemstack, int side) { + if(!super.canTakeStackFromSide(slotIndex, itemstack, side)) + return false; + + if(slotIndex >= SLOT_WASTE_1 && slotIndex < SLOT_WASTE_1 + SLOT_WASTE_COUNT) + return true; + + return false; + } + + @Override + protected boolean canPutStackFromSide(int slotIndex, ItemStack itemstack, int side) { + if(!super.canPutStackFromSide(slotIndex, itemstack, side)) + return false; + + if(slotIndex == SLOT_FUEL && FuelManager.copperEngineFuel.containsKey(itemstack)) + return true; + + return false; + + } + + /* ISPECIALINVENTORY */ + @Override + public int addItem(ItemStack stack, boolean doAdd, ForgeDirection from) { + // Peat + if (FuelManager.copperEngineFuel.containsKey(stack)) + return inventory.addStack(stack, SLOT_FUEL, 1, false, doAdd); + + return 0; + } + + @Override + public ItemStack[] extractItem(boolean doRemove, ForgeDirection from, int maxItemCount) { + for (int i = SLOT_WASTE_1; i < SLOT_WASTE_1 + SLOT_WASTE_COUNT; i++) { + if (inventory.getStackInSlot(i) == null) + continue; + + // Only ash can be extracted + if (!ForestryItem.ash.isItemEqual(inventory.getStackInSlot(i))) + continue; + + ItemStack product = ForestryItem.ash.getItemStack(); + if (doRemove) + decrStackSize(i, 1); + return new ItemStack[] { product }; + } + + return new ItemStack[0]; + } + + /* ITRIGGERPROVIDER */ + @Override + public LinkedList getCustomTriggers() { + LinkedList res = new LinkedList(); + res.add(ForestryTrigger.lowFuel25); + return res; + } + +} diff --git a/forestry_common/energy/forestry/energy/gadgets/EngineDefinition.java b/forestry_common/energy/forestry/energy/gadgets/EngineDefinition.java new file mode 100755 index 000000000..8ab0948e5 --- /dev/null +++ b/forestry_common/energy/forestry/energy/gadgets/EngineDefinition.java @@ -0,0 +1,60 @@ +/******************************************************************************* + * Copyright 2011-2014 by SirSengir + * + * This work is licensed under a Creative Commons Attribution-NonCommercial-NoDerivs 3.0 Unported License. + * + * To view a copy of this license, visit http://creativecommons.org/licenses/by-nc-nd/3.0/. + ******************************************************************************/ +package forestry.energy.gadgets; + +import net.minecraft.entity.player.EntityPlayer; +import net.minecraft.item.crafting.IRecipe; +import net.minecraft.tileentity.TileEntity; +import net.minecraft.world.IBlockAccess; +import net.minecraft.world.World; + +import net.minecraftforge.common.util.ForgeDirection; + +import forestry.core.gadgets.Engine; +import forestry.core.gadgets.MachineDefinition; +import forestry.core.interfaces.IBlockRenderer; +import forestry.core.utils.Utils; + +public class EngineDefinition extends MachineDefinition { + + public EngineDefinition(int meta, String teIdent, Class teClass, IBlockRenderer renderer, IRecipe... recipes) { + super(meta, teIdent, teClass, renderer, recipes); + } + + @Override + public boolean isSolidOnSide(IBlockAccess world, int x, int y, int z, int side) { + TileEntity tile = world.getTileEntity(x, y, z); + if (tile instanceof Engine) + return ((Engine) tile).getOrientation().getOpposite().ordinal() == side; + return false; + } + + @Override + public boolean onBlockActivated(World world, int x, int y, int z, EntityPlayer player, int side, float fXplayerClick, float fY, float fZ) { + + if (player.isSneaking()) + return false; + + Engine tile = (Engine) world.getTileEntity(x, y, z); + if (player.getCurrentEquippedItem() != null && Utils.canWrench(player, x, y, z)) { + tile.rotateEngine(); + Utils.useWrench(player, x, y, z); + return true; + } + + return false; + } + + @Override + public boolean rotateBlock(World world, int x, int y, int z, ForgeDirection axis) { + Engine tile = (Engine) world.getTileEntity(x, y, z); + tile.rotateEngine(); + return true; + } + +} diff --git a/forestry_common/energy/forestry/energy/gadgets/EngineTin.java b/forestry_common/energy/forestry/energy/gadgets/EngineTin.java new file mode 100755 index 000000000..5f65facd1 --- /dev/null +++ b/forestry_common/energy/forestry/energy/gadgets/EngineTin.java @@ -0,0 +1,366 @@ +/******************************************************************************* + * Copyright 2011-2014 by SirSengir + * + * This work is licensed under a Creative Commons Attribution-NonCommercial-NoDerivs 3.0 Unported License. + * + * To view a copy of this license, visit http://creativecommons.org/licenses/by-nc-nd/3.0/. + ******************************************************************************/ +package forestry.energy.gadgets; + +import net.minecraft.entity.player.EntityPlayer; +import net.minecraft.inventory.Container; +import net.minecraft.inventory.ICrafting; +import net.minecraft.inventory.IInventory; +import net.minecraft.item.ItemStack; +import net.minecraft.nbt.NBTTagCompound; + +import ic2.api.energy.prefab.BasicSink; + +import forestry.api.circuits.ChipsetManager; +import forestry.api.circuits.ICircuitBoard; +import forestry.api.core.ForestryAPI; +import forestry.core.EnumErrorCode; +import forestry.core.TemperatureState; +import forestry.core.config.Config; +import forestry.core.config.Defaults; +import forestry.core.gadgets.Engine; +import forestry.core.gadgets.TileBase; +import forestry.core.interfaces.ISocketable; +import forestry.core.network.GuiId; +import forestry.core.utils.DelayTimer; +import forestry.core.utils.EnumTankLevel; +import forestry.core.utils.InventoryAdapter; +import forestry.plugins.PluginIC2; + +public class EngineTin extends Engine implements ISocketable, IInventory { + + protected static class EuConfig { + public int euForCycle; + public int mjPerCycle; + public int euStorage; + public int euMaxAccept = 512; + + public EuConfig(int euForCycle, int mjPerCycle, int euStorage) { + this.euForCycle = euForCycle; + this.mjPerCycle = mjPerCycle; + this.euStorage = euStorage; + } + } + + private final short batterySlot = 0; + private final InventoryAdapter inventory = new InventoryAdapter(1, "electrical"); + private final InventoryAdapter sockets = new InventoryAdapter(1, "sockets"); + private final EuConfig euConfig = new EuConfig(Defaults.ENGINE_TIN_EU_FOR_CYCLE, Defaults.ENGINE_TIN_ENERGY_PER_CYCLE, Defaults.ENGINE_TIN_MAX_EU_STORED); + + protected BasicSink ic2EnergySink = new BasicSink(this, euConfig.euStorage, 3); + + private final DelayTimer delayUpdateTimer = new DelayTimer(); + + public EngineTin() { + super(Defaults.ENGINE_TIN_HEAT_MAX, 10000, 400); + setHints(Config.hints.get("engine.tin")); + } + + @Override + public void openGui(EntityPlayer player, TileBase tile) { + player.openGui(ForestryAPI.instance, GuiId.EngineTinGUI.ordinal(), player.worldObj, xCoord, yCoord, zCoord); + } + + // / SAVING / LOADING + @Override + public void readFromNBT(NBTTagCompound nbttagcompound) { + super.readFromNBT(nbttagcompound); + + ic2EnergySink.readFromNBT(nbttagcompound); + inventory.readFromNBT(nbttagcompound); + sockets.readFromNBT(nbttagcompound); + + ItemStack chip = sockets.getStackInSlot(0); + if (chip != null) { + ICircuitBoard chipset = ChipsetManager.circuitRegistry.getCircuitboard(chip); + if (chipset != null) + chipset.onLoad(this); + } + } + + @Override + public void writeToNBT(NBTTagCompound nbttagcompound) { + super.writeToNBT(nbttagcompound); + + ic2EnergySink.writeToNBT(nbttagcompound); + inventory.writeToNBT(nbttagcompound); + sockets.writeToNBT(nbttagcompound); + } + + @Override + public void onChunkUnload() { + ic2EnergySink.onChunkUnload(); + + super.onChunkUnload(); + } + + @Override + public void invalidate() { + ic2EnergySink.invalidate(); + + super.invalidate(); + } + + // / HEAT MANAGMENT + @Override + public int dissipateHeat() { + if (heat <= 0) + return 0; + + int loss = 0; + + if (!isBurning() || !isActivated()) + loss += 1; + + TemperatureState tempState = getTemperatureState(); + if (tempState == TemperatureState.OVERHEATING || tempState == TemperatureState.OPERATING_TEMPERATURE) + loss += 1; + + heat -= loss; + return loss; + } + + @Override + public int generateHeat() { + + int gain = 0; + if (isActivated() && isBurning()) { + gain++; + if (((double) storedEnergy / (double) maxEnergy) > 0.5) + gain++; + } + + addHeat(gain); + return gain; + } + + // / WORK + @Override + public void updateServerSide() { + // No work to be done if IC2 is unavailable. + if (!PluginIC2.instance.isAvailable()) { + setErrorState(EnumErrorCode.NOENERGYNET); + return; + } + + ic2EnergySink.updateEntity(); + + super.updateServerSide(); + + if (forceCooldown) { + setErrorState(EnumErrorCode.FORCEDCOOLDOWN); + return; + } + + if (inventory.getStackInSlot(batterySlot) != null) + replenishFromBattery(batterySlot); + + // Updating of gui delayed to prevent it from going crazy + if (!delayUpdateTimer.delayPassed(worldObj, 80)) + return; + + if (currentOutput <= 0 && getErrorState() == EnumErrorCode.OK) + setErrorState(EnumErrorCode.NOFUEL); + else + setErrorState(EnumErrorCode.OK); + } + + @Override + public void burn() { + + currentOutput = 0; + + if (!isActivated()) + return; + + if (ic2EnergySink.useEnergy(euConfig.euForCycle)) { + currentOutput = euConfig.mjPerCycle; + addEnergy(euConfig.mjPerCycle); + } + + } + + private void replenishFromBattery(int slot) { + if (!isActivated()) + return; + + ic2EnergySink.discharge(inventory.getStackInSlot(slot), euConfig.euForCycle * 3); + } + + // / STATE INFORMATION + @Override + public boolean isBurning() { + return mayBurn() && ic2EnergySink.canUseEnergy(euConfig.euForCycle); + } + + public int getStorageScaled(int i) { + return Math.min(i, (int) (ic2EnergySink.getEnergyStored() * i) / ic2EnergySink.getCapacity()); + } + + public EnumTankLevel rateLevel(int scaled) { + + if (scaled < 5) + return EnumTankLevel.EMPTY; + else if (scaled < 30) + return EnumTankLevel.LOW; + else if (scaled < 60) + return EnumTankLevel.MEDIUM; + else if (scaled < 90) + return EnumTankLevel.HIGH; + else + return EnumTankLevel.MAXIMUM; + } + + // / SMP GUI + @Override + public void getGUINetworkData(int i, int j) { + + switch (i) { + + case 0: + currentOutput = j; + break; + case 1: + storedEnergy = j; + break; + case 2: + heat = j; + break; + case 3: + ic2EnergySink.setEnergyStored(j); + break; + } + + } + + @Override + public void sendGUINetworkData(Container containerEngine, ICrafting iCrafting) { + iCrafting.sendProgressBarUpdate(containerEngine, 0, currentOutput); + iCrafting.sendProgressBarUpdate(containerEngine, 1, (int)storedEnergy); + iCrafting.sendProgressBarUpdate(containerEngine, 2, heat); + iCrafting.sendProgressBarUpdate(containerEngine, 3, (short) ic2EnergySink.getEnergyStored()); + } + + // / ENERGY CONFIG CHANGE + public void changeEnergyConfig(int euChange, int mjChange, int storageChange) { + euConfig.euForCycle += euChange; + euConfig.mjPerCycle += mjChange; + euConfig.euStorage += storageChange; + + ic2EnergySink.setCapacity(euConfig.euStorage); + } + + /* IINVENTORY */ + @Override + public int getSizeInventory() { + return inventory.getSizeInventory(); + } + + @Override + public ItemStack getStackInSlot(int i) { + return inventory.getStackInSlot(i); + } + + @Override + public ItemStack decrStackSize(int i, int j) { + return inventory.decrStackSize(i, j); + } + + @Override + public void setInventorySlotContents(int i, ItemStack itemstack) { + inventory.setInventorySlotContents(i, itemstack); + } + + @Override + public int getInventoryStackLimit() { + return inventory.getInventoryStackLimit(); + } + + @Override + public ItemStack getStackInSlotOnClosing(int slot) { + return inventory.getStackInSlotOnClosing(slot); + } + + @Override + public void openInventory() { + } + + @Override + public void closeInventory() { + } + + /** + * TODO: just a specialsource workaround + */ + @Override + public boolean isUseableByPlayer(EntityPlayer player) { + return super.isUseableByPlayer(player); + } + + /** + * TODO: just a specialsource workaround + */ + @Override + public String getInventoryName() { + return super.getInventoryName(); + } + + /** + * TODO: just a specialsource workaround + */ + @Override + public boolean hasCustomInventoryName() { + return super.hasCustomInventoryName(); + } + + /** + * TODO: just a specialsource workaround + */ + @Override + public boolean isItemValidForSlot(int slotIndex, ItemStack itemstack) { + return super.isItemValidForSlot(slotIndex, itemstack); + } + + /* ISOCKETABLE */ + @Override + public int getSocketCount() { + return sockets.getSizeInventory(); + } + + @Override + public ItemStack getSocket(int slot) { + return sockets.getStackInSlot(slot); + } + + @Override + public void setSocket(int slot, ItemStack stack) { + + if (stack != null && !ChipsetManager.circuitRegistry.isChipset(stack)) + return; + + // Dispose correctly of old chipsets + if (sockets.getStackInSlot(slot) != null) + if (ChipsetManager.circuitRegistry.isChipset(sockets.getStackInSlot(slot))) { + ICircuitBoard chipset = ChipsetManager.circuitRegistry.getCircuitboard(sockets.getStackInSlot(slot)); + if (chipset != null) + chipset.onRemoval(this); + } + + if (stack == null) { + sockets.setInventorySlotContents(slot, stack); + return; + } + + sockets.setInventorySlotContents(slot, stack); + + ICircuitBoard chipset = ChipsetManager.circuitRegistry.getCircuitboard(stack); + if (chipset != null) + chipset.onInsertion(this); + } + +} diff --git a/forestry_common/energy/forestry/energy/gadgets/MachineGenerator.java b/forestry_common/energy/forestry/energy/gadgets/MachineGenerator.java new file mode 100755 index 000000000..df7b27567 --- /dev/null +++ b/forestry_common/energy/forestry/energy/gadgets/MachineGenerator.java @@ -0,0 +1,281 @@ +/******************************************************************************* + * Copyright 2011-2014 by SirSengir + * + * This work is licensed under a Creative Commons Attribution-NonCommercial-NoDerivs 3.0 Unported License. + * + * To view a copy of this license, visit http://creativecommons.org/licenses/by-nc-nd/3.0/. + ******************************************************************************/ +package forestry.energy.gadgets; + +import net.minecraft.entity.player.EntityPlayer; +import net.minecraft.inventory.Container; +import net.minecraft.inventory.ICrafting; +import net.minecraft.item.ItemStack; +import net.minecraft.nbt.NBTTagCompound; + +import net.minecraftforge.common.util.ForgeDirection; +import net.minecraftforge.fluids.FluidContainerRegistry.FluidContainerData; +import net.minecraftforge.fluids.FluidStack; + +import buildcraft.api.inventory.ISpecialInventory; +import ic2.api.energy.prefab.BasicSource; + +import forestry.api.core.ForestryAPI; +import forestry.api.fuels.GeneratorFuel; +import forestry.core.EnumErrorCode; +import forestry.core.config.Config; +import forestry.core.config.Defaults; +import forestry.core.gadgets.TileBase; +import forestry.core.interfaces.ILiquidTankContainer; +import forestry.core.interfaces.IRenderableMachine; +import forestry.core.network.EntityNetData; +import forestry.core.network.GuiId; +import forestry.core.utils.EnumTankLevel; +import forestry.core.utils.ForestryTank; +import forestry.core.utils.InventoryAdapter; +import forestry.core.utils.LiquidHelper; +import forestry.core.utils.StackUtils; +import forestry.core.utils.StringUtil; +import forestry.core.utils.Utils; +import forestry.plugins.PluginIC2; + +public class MachineGenerator extends TileBase implements ISpecialInventory, ILiquidTankContainer, IRenderableMachine { + + // / CONSTANTS + public static final short SLOT_CAN = 0; + public static final int maxEnergy = 30000; + + @EntityNetData + public ForestryTank resourceTank = new ForestryTank(Defaults.PROCESSOR_TANK_CAPACITY); + private int tickCount = 0; + + InventoryAdapter inventory = new InventoryAdapter(1, "Items"); + protected BasicSource ic2EnergySource = new BasicSource(this, maxEnergy, 1); + + public MachineGenerator() { + setHints(Config.hints.get("generator")); + } + + @Override + public String getInventoryName() { + return StringUtil.localize("engine.3"); + } + + @Override + public void openGui(EntityPlayer player, TileBase tile) { + player.openGui(ForestryAPI.instance, GuiId.GeneratorGUI.ordinal(), player.worldObj, xCoord, yCoord, zCoord); + } + + @Override + public void writeToNBT(NBTTagCompound nbttagcompound) { + super.writeToNBT(nbttagcompound); + + ic2EnergySource.writeToNBT(nbttagcompound); + + NBTTagCompound NBTresourceSlot = new NBTTagCompound(); + resourceTank.writeToNBT(NBTresourceSlot); + nbttagcompound.setTag("ResourceTank", NBTresourceSlot); + + inventory.writeToNBT(nbttagcompound); + } + + @Override + public void readFromNBT(NBTTagCompound nbttagcompound) { + super.readFromNBT(nbttagcompound); + + ic2EnergySource.readFromNBT(nbttagcompound); + + resourceTank = new ForestryTank(Defaults.PROCESSOR_TANK_CAPACITY); + if (nbttagcompound.hasKey("ResourceTank")) + resourceTank.readFromNBT(nbttagcompound.getCompoundTag("ResourceTank")); + + inventory.readFromNBT(nbttagcompound); + } + + @Override + public void onChunkUnload() { + ic2EnergySource.onChunkUnload(); + + super.onChunkUnload(); + } + + @Override + public void invalidate() { + ic2EnergySource.invalidate(); + + super.invalidate(); + } + @Override + public void updateServerSide() { + + // Check inventory slots for fuel + // Check if we have suitable items waiting in the item slot + if (inventory.getStackInSlot(SLOT_CAN) != null) { + FluidContainerData container = LiquidHelper.getLiquidContainer(inventory.getStackInSlot(SLOT_CAN)); + if (container != null) + if (GeneratorFuel.fuels.containsKey(container.fluid.fluidID)) { + inventory.setInventorySlotContents(SLOT_CAN, StackUtils.replenishByContainer(this, inventory.getStackInSlot(SLOT_CAN), container, resourceTank)); + if (inventory.getStackInSlot(SLOT_CAN).stackSize <= 0) + inventory.setInventorySlotContents(SLOT_CAN, null); + } + } + + // No work to be done if IC2 is unavailable. + if (!PluginIC2.instance.isAvailable()) { + setErrorState(EnumErrorCode.NOENERGYNET); + return; + } + + ic2EnergySource.updateEntity(); + + if (resourceTank.getFluidAmount() > 0 && + GeneratorFuel.fuels.containsKey(resourceTank.getFluid().fluidID)) { + GeneratorFuel fuel = GeneratorFuel.fuels.get(resourceTank.getFluid().fluidID); + + if (resourceTank.getFluidAmount() >= fuel.fuelConsumed.amount && + ic2EnergySource.getFreeCapacity() >= fuel.eu) { + ic2EnergySource.addEnergy(fuel.eu); + this.tickCount++; + + if (tickCount >= fuel.rate) { + tickCount = 0; + resourceTank.drain(fuel.fuelConsumed.amount, true); + } + } + + } + + if (resourceTank.getFluidAmount() <= 0) + setErrorState(EnumErrorCode.NOFUEL); + else + setErrorState(EnumErrorCode.OK); + } + + public boolean isWorking() { + return resourceTank.getFluidAmount() > 0; + } + + public int getResourceScaled(int i) { + return (resourceTank.getFluidAmount() * i) / Defaults.PROCESSOR_TANK_CAPACITY; + } + + public int getStoredScaled(int i) { + return (int) (ic2EnergySource.getEnergyStored() * i) / maxEnergy; + } + + @Override + public EnumTankLevel getPrimaryLevel() { + return Utils.rateTankLevel(getResourceScaled(100)); + } + + @Override + public EnumTankLevel getSecondaryLevel() { + return EnumTankLevel.EMPTY; + } + + /* SMP GUI */ + public void getGUINetworkData(int i, int j) { + + switch (i) { + case 0: + ic2EnergySource.setEnergyStored(j); + break; + } + } + + public void sendGUINetworkData(Container container, ICrafting iCrafting) { + iCrafting.sendProgressBarUpdate(container, 0, (short) ic2EnergySource.getEnergyStored()); + } + + /* IINVENTORY */ + @Override public ItemStack getStackInSlot(int i) { return inventory.getStackInSlot(i); } + @Override public void setInventorySlotContents(int i, ItemStack itemstack) { inventory.setInventorySlotContents(i, itemstack); } + @Override public int getSizeInventory() { return inventory.getSizeInventory(); } + @Override public ItemStack decrStackSize(int i, int j) { return inventory.decrStackSize(i, j); } + @Override public ItemStack getStackInSlotOnClosing(int slot) { return inventory.getStackInSlotOnClosing(slot); } + @Override public int getInventoryStackLimit() { return inventory.getInventoryStackLimit(); } + @Override public void openInventory() {} + @Override public void closeInventory() {} + + /** + * TODO: just a specialsource workaround + */ + @Override + public boolean isUseableByPlayer(EntityPlayer player) { + return super.isUseableByPlayer(player); + } + + /** + * TODO: just a specialsource workaround + */ + @Override + public boolean hasCustomInventoryName() { + return super.hasCustomInventoryName(); + } + + /** + * TODO: just a specialsource workaround + */ + @Override + public boolean isItemValidForSlot(int slotIndex, ItemStack itemstack) { + return super.isItemValidForSlot(slotIndex, itemstack); + } + + /* ISPECIALINVENTORY */ + @Override + public int addItem(ItemStack stack, boolean doAdd, ForgeDirection from) { + + FluidContainerData container = LiquidHelper.getLiquidContainer(stack); + if (container == null) + return 0; + + if (!GeneratorFuel.fuels.containsKey(container.fluid.fluidID)) + return 0; + + if (inventory.getStackInSlot(SLOT_CAN) == null) { + if (doAdd) + inventory.setInventorySlotContents(SLOT_CAN, stack.copy()); + + return stack.stackSize; + } + + if (!inventory.getStackInSlot(SLOT_CAN).isItemEqual(stack)) + return 0; + + int space = inventory.getStackInSlot(SLOT_CAN).getMaxStackSize() - inventory.getStackInSlot(SLOT_CAN).stackSize; + if (space <= 0) + return 0; + + if (doAdd) + inventory.getStackInSlot(SLOT_CAN).stackSize += stack.stackSize; + + return Math.min(space, stack.stackSize); + + } + + @Override + public ItemStack[] extractItem(boolean doRemove, ForgeDirection from, int maxItemCount) { + return null; + } + + /* ILIQUIDCONTAINER IMPLEMENTATION */ + @Override + public int fill(ForgeDirection from, FluidStack resource, boolean doFill) { + // We only accept water + if (!GeneratorFuel.fuels.containsKey(resource.fluidID)) + return 0; + + int used = resourceTank.fill(resource, doFill); + + if (doFill && used > 0) + // TODO: Slow down updates + sendNetworkUpdate(); + + return used; + } + + @Override + public ForestryTank[] getTanks() { + return new ForestryTank[] { resourceTank }; + } +} diff --git a/forestry_common/energy/forestry/energy/gui/ContainerEngineBronze.java b/forestry_common/energy/forestry/energy/gui/ContainerEngineBronze.java new file mode 100755 index 000000000..56a51ce92 --- /dev/null +++ b/forestry_common/energy/forestry/energy/gui/ContainerEngineBronze.java @@ -0,0 +1,56 @@ +/******************************************************************************* + * Copyright 2011-2014 by SirSengir + * + * This work is licensed under a Creative Commons Attribution-NonCommercial-NoDerivs 3.0 Unported License. + * + * To view a copy of this license, visit http://creativecommons.org/licenses/by-nc-nd/3.0/. + ******************************************************************************/ +package forestry.energy.gui; + +import net.minecraft.entity.player.EntityPlayer; +import net.minecraft.entity.player.InventoryPlayer; +import net.minecraft.inventory.ICrafting; +import net.minecraft.inventory.Slot; + +import forestry.core.gui.ContainerLiquidTanks; +import forestry.core.gui.slots.SlotLiquidContainer; +import forestry.energy.gadgets.EngineBronze; + +public class ContainerEngineBronze extends ContainerLiquidTanks { + protected EngineBronze engine; + + public ContainerEngineBronze(InventoryPlayer player, EngineBronze engine) { + super(engine, engine); + + this.engine = engine; + this.addSlot(new SlotLiquidContainer(engine, EngineBronze.SLOT_CAN, 143, 40)); + + int i; + for (i = 0; i < 3; ++i) + for (int var4 = 0; var4 < 9; ++var4) + this.addSlot(new Slot(player, var4 + i * 9 + 9, 8 + var4 * 18, 84 + i * 18)); + + for (i = 0; i < 9; ++i) + this.addSlot(new Slot(player, i, 8 + i * 18, 142)); + + } + + @Override + public boolean canInteractWith(EntityPlayer entityplayer) { + return engine.isUseableByPlayer(entityplayer); + } + + @Override + public void updateProgressBar(int i, int j) { + engine.getGUINetworkData(i, j); + } + + @Override + public void detectAndSendChanges() { + super.detectAndSendChanges(); + + for (int i = 0; i < crafters.size(); i++) + engine.sendGUINetworkData(this, (ICrafting) crafters.get(i)); + } + +} diff --git a/forestry_common/energy/forestry/energy/gui/ContainerEngineCopper.java b/forestry_common/energy/forestry/energy/gui/ContainerEngineCopper.java new file mode 100755 index 000000000..f740abbca --- /dev/null +++ b/forestry_common/energy/forestry/energy/gui/ContainerEngineCopper.java @@ -0,0 +1,60 @@ +/******************************************************************************* + * Copyright 2011-2014 by SirSengir + * + * This work is licensed under a Creative Commons Attribution-NonCommercial-NoDerivs 3.0 Unported License. + * + * To view a copy of this license, visit http://creativecommons.org/licenses/by-nc-nd/3.0/. + ******************************************************************************/ +package forestry.energy.gui; + +import net.minecraft.entity.player.EntityPlayer; +import net.minecraft.entity.player.InventoryPlayer; +import net.minecraft.inventory.ICrafting; +import net.minecraft.inventory.Slot; + +import forestry.core.gui.ContainerForestry; +import forestry.core.gui.slots.SlotClosed; +import forestry.energy.gadgets.EngineCopper; + +public class ContainerEngineCopper extends ContainerForestry { + protected EngineCopper engine; + + public ContainerEngineCopper(InventoryPlayer player, EngineCopper tile) { + super(tile); + + this.engine = tile; + this.addSlot(new Slot(tile, 0, 44, 46)); + + this.addSlot(new SlotClosed(tile, 1, 98, 35)); + this.addSlot(new SlotClosed(tile, 2, 98, 53)); + this.addSlot(new SlotClosed(tile, 3, 116, 35)); + this.addSlot(new SlotClosed(tile, 4, 116, 53)); + + for (int i = 0; i < 3; ++i) + for (int j = 0; j < 9; ++j) + this.addSlot(new Slot(player, j + i * 9 + 9, 8 + j * 18, 84 + i * 18)); + + for (int i = 0; i < 9; ++i) + this.addSlot(new Slot(player, i, 8 + i * 18, 142)); + + } + + @Override + public void updateProgressBar(int i, int j) { + if (engine != null) + engine.getGUINetworkData(i, j); + } + + @Override + public void detectAndSendChanges() { + super.detectAndSendChanges(); + + for (int i = 0; i < crafters.size(); i++) + engine.sendGUINetworkData(this, (ICrafting) crafters.get(i)); + } + + @Override + public boolean canInteractWith(EntityPlayer entityplayer) { + return engine.isUseableByPlayer(entityplayer); + } +} diff --git a/forestry_common/energy/forestry/energy/gui/ContainerEngineTin.java b/forestry_common/energy/forestry/energy/gui/ContainerEngineTin.java new file mode 100755 index 000000000..9d1b0a807 --- /dev/null +++ b/forestry_common/energy/forestry/energy/gui/ContainerEngineTin.java @@ -0,0 +1,53 @@ +/******************************************************************************* + * Copyright 2011-2014 by SirSengir + * + * This work is licensed under a Creative Commons Attribution-NonCommercial-NoDerivs 3.0 Unported License. + * + * To view a copy of this license, visit http://creativecommons.org/licenses/by-nc-nd/3.0/. + ******************************************************************************/ +package forestry.energy.gui; + +import net.minecraft.entity.player.InventoryPlayer; +import net.minecraft.inventory.ICrafting; +import net.minecraft.inventory.Slot; + +import forestry.core.gui.ContainerSocketed; +import forestry.energy.gadgets.EngineTin; + +public class ContainerEngineTin extends ContainerSocketed { + + protected EngineTin tile; + + public ContainerEngineTin(InventoryPlayer player, EngineTin tile) { + super(tile, tile); + + this.tile = tile; + this.addSlot(new Slot(tile, 0, 84, 53)); + + int i; + for (i = 0; i < 3; ++i) + for (int j = 0; j < 9; ++j) + this.addSlot(new Slot(player, j + i * 9 + 9, 8 + j * 18, 84 + i * 18)); + + for (i = 0; i < 9; ++i) + this.addSlot(new Slot(player, i, 8 + i * 18, 142)); + } + + @Override + public void updateProgressBar(int i, int j) { + if (tile != null) + tile.getGUINetworkData(i, j); + } + + @Override + public void detectAndSendChanges() { + super.detectAndSendChanges(); + + if (tile == null) + return; + + for (int i = 0; i < crafters.size(); i++) + tile.sendGUINetworkData(this, (ICrafting) crafters.get(i)); + } + +} diff --git a/forestry_common/energy/forestry/energy/gui/ContainerGenerator.java b/forestry_common/energy/forestry/energy/gui/ContainerGenerator.java new file mode 100755 index 000000000..c7f032291 --- /dev/null +++ b/forestry_common/energy/forestry/energy/gui/ContainerGenerator.java @@ -0,0 +1,55 @@ +/******************************************************************************* + * Copyright 2011-2014 by SirSengir + * + * This work is licensed under a Creative Commons Attribution-NonCommercial-NoDerivs 3.0 Unported License. + * + * To view a copy of this license, visit http://creativecommons.org/licenses/by-nc-nd/3.0/. + ******************************************************************************/ +package forestry.energy.gui; + +import net.minecraft.entity.player.EntityPlayer; +import net.minecraft.entity.player.InventoryPlayer; +import net.minecraft.inventory.ICrafting; +import net.minecraft.inventory.Slot; + +import forestry.core.gui.ContainerLiquidTanks; +import forestry.core.gui.slots.SlotLiquidContainer; +import forestry.energy.gadgets.MachineGenerator; + +public class ContainerGenerator extends ContainerLiquidTanks { + + protected MachineGenerator tile; + + public ContainerGenerator(InventoryPlayer player, MachineGenerator tile) { + super(tile, tile); + + this.tile = tile; + this.addSlot(new SlotLiquidContainer(tile, MachineGenerator.SLOT_CAN, 22, 38)); + + for (int i = 0; i < 3; ++i) + for (int var4 = 0; var4 < 9; ++var4) + this.addSlot(new Slot(player, var4 + i * 9 + 9, 8 + var4 * 18, 84 + i * 18)); + + for (int i = 0; i < 9; ++i) + this.addSlot(new Slot(player, i, 8 + i * 18, 142)); + } + + @Override + public void updateProgressBar(int i, int j) { + tile.getGUINetworkData(i, j); + } + + @Override + public void detectAndSendChanges() { + super.detectAndSendChanges(); + + for (int i = 0; i < crafters.size(); i++) + tile.sendGUINetworkData(this, (ICrafting) crafters.get(i)); + } + + @Override + public boolean canInteractWith(EntityPlayer entityplayer) { + return tile.isUseableByPlayer(entityplayer); + } + +} diff --git a/forestry_common/energy/forestry/energy/gui/GuiEngine.java b/forestry_common/energy/forestry/energy/gui/GuiEngine.java new file mode 100755 index 000000000..66ca7234e --- /dev/null +++ b/forestry_common/energy/forestry/energy/gui/GuiEngine.java @@ -0,0 +1,63 @@ +/** + * + */ +package forestry.energy.gui; + +import forestry.core.gadgets.Engine; +import forestry.core.gui.ContainerForestry; +import forestry.core.gui.GuiForestry; +import forestry.core.gui.Ledger; +import forestry.core.render.TextureManager; +import forestry.core.utils.StringUtil; + +public abstract class GuiEngine extends GuiForestry { + + protected class EngineLedger extends Ledger { + + private final Engine engine; + + public EngineLedger(Engine engine) { + super(ledgerManager); + this.engine = engine; + maxHeight = 94; + overlayColor = fontColor.get("ledger.power.background"); + } + + @Override + public void draw(int x, int y) { + + // Draw background + drawBackground(x, y); + + // Draw icon + drawIcon(TextureManager.getInstance().getDefault("misc/energy"), x + 3, y + 4); + + if (!isFullyOpened()) + return; + + fontRendererObj.drawStringWithShadow(StringUtil.localize("gui.energy"), x + 22, y + 8, fontColor.get("ledger.power.header")); + fontRendererObj.drawStringWithShadow(StringUtil.localize("gui.currentOutput") + ":", x + 22, y + 20, fontColor.get("ledger.power.subheader")); + fontRendererObj.drawString(engine.getCurrentOutput() + " MJ/t", x + 22, y + 32, fontColor.get("ledger.power.text")); + fontRendererObj.drawStringWithShadow(StringUtil.localize("gui.stored") + ":", x + 22, y + 44, fontColor.get("ledger.power.subheader")); + fontRendererObj.drawString(engine.getEnergyStored() + " MJ", x + 22, y + 56, fontColor.get("ledger.power.text")); + fontRendererObj.drawStringWithShadow(StringUtil.localize("gui.heat") + ":", x + 22, y + 68, fontColor.get("ledger.power.subheader")); + fontRendererObj.drawString((((double) engine.getHeat() / (double) 10) + 20.0) + " C", x + 22, y + 80, fontColor.get("ledger.power.text")); + + } + + @Override + public String getTooltip() { + return engine.getCurrentOutput() + " MJ/t"; + } + } + + public GuiEngine(String texture, ContainerForestry container, Engine tile) { + super(texture, container, tile); + } + + @Override + protected void initLedgers(Object inventory) { + super.initLedgers(inventory); + ledgerManager.insert(new EngineLedger(tile)); + } +} diff --git a/forestry_common/energy/forestry/energy/gui/GuiEngineBronze.java b/forestry_common/energy/forestry/energy/gui/GuiEngineBronze.java new file mode 100755 index 000000000..aad2171ca --- /dev/null +++ b/forestry_common/energy/forestry/energy/gui/GuiEngineBronze.java @@ -0,0 +1,121 @@ +/******************************************************************************* + * Copyright 2011-2014 by SirSengir + * + * This work is licensed under a Creative Commons Attribution-NonCommercial-NoDerivs 3.0 Unported License. + * + * To view a copy of this license, visit http://creativecommons.org/licenses/by-nc-nd/3.0/. + ******************************************************************************/ +package forestry.energy.gui; + +import net.minecraft.entity.player.EntityPlayer; +import net.minecraft.entity.player.InventoryPlayer; +import net.minecraft.util.IIcon; + +import net.minecraftforge.fluids.Fluid; +import net.minecraftforge.fluids.FluidRegistry; + +import org.lwjgl.opengl.GL11; + +import forestry.core.config.Defaults; +import forestry.core.gui.WidgetManager; +import forestry.core.gui.widgets.TankWidget; +import forestry.core.gui.widgets.Widget; +import forestry.core.proxy.Proxies; +import forestry.core.render.SpriteSheet; +import forestry.core.utils.StringUtil; +import forestry.energy.gadgets.EngineBronze; + +public class GuiEngineBronze extends GuiEngine { + + protected class BiogasSlot extends Widget { + + EngineBronze engine; + + public BiogasSlot(WidgetManager manager, int xPos, int yPos, EngineBronze engine) { + super(manager, xPos, yPos); + this.engine = engine; + this.height = 16; + } + + @Override + public void draw(int startX, int startY) { + + if (engine == null || engine.totalTime <= 0) + return; + + Fluid fluid = FluidRegistry.getFluid(engine.currentFluidId); + if (fluid == null) + return; + IIcon liquidIcon = fluid.getIcon(); + if (liquidIcon == null) + return; + + int squaled = (engine.burnTime * height) / engine.totalTime; + if (squaled > height) + squaled = height; + + Proxies.common.bindTexture(SpriteSheet.BLOCKS); + int start = 0; + + GL11.glColor4f(1.0f, 1.0f, 1.0f, 1.0F); + while (true) { + int x = 0; + + if (squaled > 16) { + x = 16; + squaled -= 16; + } else { + x = squaled; + squaled = 0; + } + + // drawTexturedModalRect(startX + xPos, startY + yPos + height - x - start, imgColumn * 16, imgLine * 16, 16, 16 - (16 - x)); + manager.gui.drawTexturedModelRectFromIcon(startX + xPos, startY + yPos + height - x - start, liquidIcon, 16, 16 - (16 - x)); + start = start + 16; + + if (x == 0 || squaled == 0) + break; + } + + Proxies.common.bindTexture(textureFile); + } + + @Override + public String getLegacyTooltip(EntityPlayer player) { + Fluid fluid = FluidRegistry.getFluid(engine.currentFluidId); + if (fluid == null) + return StringUtil.localize("gui.empty"); + + String tooltip = fluid.getLocalizedName(); + return tooltip; + } + } + + public GuiEngineBronze(InventoryPlayer inventory, EngineBronze tile) { + super(Defaults.TEXTURE_PATH_GUI + "/bioengine.png", new ContainerEngineBronze(inventory, tile), tile); + widgetManager.add(new TankWidget(this.widgetManager, 89, 19, 0)); + widgetManager.add(new TankWidget(this.widgetManager, 107, 19, 1)); + + widgetManager.add(new BiogasSlot(this.widgetManager, 30, 47, tile)); + } + + @Override + protected void drawGuiContainerForegroundLayer(int mouseX, int mouseY) { + super.drawGuiContainerForegroundLayer(mouseX, mouseY); + String name = StringUtil.localize("tile.for.engine.2"); + this.fontRendererObj.drawString(name, getCenteredOffset(name), 6, fontColor.get("gui.title")); + } + + @Override + protected void drawGuiContainerBackgroundLayer(float var1, int mouseX, int mouseY) { + super.drawGuiContainerBackgroundLayer(var1, mouseX, mouseY); + EngineBronze engine = (EngineBronze) tile; + + int temp = engine.getOperatingTemperatureScaled(16); + if (temp > 16) + temp = 16; + if (temp > 0) + drawTexturedModalRect(guiLeft + 53, guiTop + 47 + 16 - temp, 176, 60 + 16 - temp, 4, temp); + + } +} diff --git a/forestry_common/energy/forestry/energy/gui/GuiEngineCopper.java b/forestry_common/energy/forestry/energy/gui/GuiEngineCopper.java new file mode 100755 index 000000000..923a8fb93 --- /dev/null +++ b/forestry_common/energy/forestry/energy/gui/GuiEngineCopper.java @@ -0,0 +1,41 @@ +/******************************************************************************* + * Copyright 2011-2014 by SirSengir + * + * This work is licensed under a Creative Commons Attribution-NonCommercial-NoDerivs 3.0 Unported License. + * + * To view a copy of this license, visit http://creativecommons.org/licenses/by-nc-nd/3.0/. + ******************************************************************************/ +package forestry.energy.gui; + +import net.minecraft.entity.player.InventoryPlayer; + +import forestry.core.config.Defaults; +import forestry.core.utils.StringUtil; +import forestry.energy.gadgets.EngineCopper; + +public class GuiEngineCopper extends GuiEngine { + + public GuiEngineCopper(InventoryPlayer inventory, EngineCopper tile) { + super(Defaults.TEXTURE_PATH_GUI + "/peatengine.png", new ContainerEngineCopper(inventory, tile), tile); + } + + @Override + protected void drawGuiContainerForegroundLayer(int mouseX, int mouseY) { + super.drawGuiContainerForegroundLayer(mouseX, mouseY); + String name = StringUtil.localize("tile.for.engine.1"); + this.fontRendererObj.drawString(name, getCenteredOffset(name), 6, fontColor.get("gui.title")); + this.fontRendererObj.drawString("Inventory", 8, this.ySize - 96 + 2, fontColor.get("gui.title")); + } + + @Override + protected void drawGuiContainerBackgroundLayer(float var1, int mouseX, int mouseY) { + super.drawGuiContainerBackgroundLayer(var1, mouseX, mouseY); + EngineCopper engine = (EngineCopper) tile; + + int progress; + if (engine.isBurning()) { + progress = engine.getBurnTimeRemainingScaled(12); + this.drawTexturedModalRect(guiLeft + 45, guiTop + 27 + 12 - progress, 176, 0 + 12 - progress, 14, progress + 2); + } + } +} diff --git a/forestry_common/energy/forestry/energy/gui/GuiEngineTin.java b/forestry_common/energy/forestry/energy/gui/GuiEngineTin.java new file mode 100755 index 000000000..c9f028e78 --- /dev/null +++ b/forestry_common/energy/forestry/energy/gui/GuiEngineTin.java @@ -0,0 +1,63 @@ +/******************************************************************************* + * Copyright 2011-2014 by SirSengir + * + * This work is licensed under a Creative Commons Attribution-NonCommercial-NoDerivs 3.0 Unported License. + * + * To view a copy of this license, visit http://creativecommons.org/licenses/by-nc-nd/3.0/. + ******************************************************************************/ +package forestry.energy.gui; + +import net.minecraft.entity.player.InventoryPlayer; + +import forestry.core.config.Defaults; +import forestry.core.gui.widgets.SocketWidget; +import forestry.core.utils.EnumTankLevel; +import forestry.core.utils.StringUtil; +import forestry.energy.gadgets.EngineTin; + +public class GuiEngineTin extends GuiEngine { + + public GuiEngineTin(InventoryPlayer inventory, EngineTin tile) { + super(Defaults.TEXTURE_PATH_GUI + "/electricalengine.png", new ContainerEngineTin(inventory, tile), tile); + widgetManager.add(new SocketWidget(this.widgetManager, 30, 40, tile, 0)); + } + + @Override + protected void drawGuiContainerForegroundLayer(int mouseX, int mouseY) { + super.drawGuiContainerForegroundLayer(mouseX, mouseY); + String name = StringUtil.localize("tile.for.engine.0"); + this.fontRendererObj.drawString(name, getCenteredOffset(name), 6, fontColor.get("gui.title")); + } + + @Override + protected void drawGuiContainerBackgroundLayer(float var1, int mouseX, int mouseY) { + super.drawGuiContainerBackgroundLayer(var1, mouseX, mouseY); + EngineTin engine = (EngineTin) tile; + drawHealthMeter(guiLeft + 74, guiTop + 25, engine.getStorageScaled(46), engine.rateLevel(engine.getStorageScaled(100))); + + } + + private void drawHealthMeter(int x, int y, int height, EnumTankLevel rated) { + int i = 176; + int k = 0; + switch (rated) { + case EMPTY: + break; + case LOW: + i += 4; + break; + case MEDIUM: + i += 8; + break; + case HIGH: + i += 12; + break; + case MAXIMUM: + i += 16; + break; + } + + this.drawTexturedModalRect(x, y + 46 - height, i, k + 46 - height, 4, height); + } + +} diff --git a/forestry_common/energy/forestry/energy/gui/GuiGenerator.java b/forestry_common/energy/forestry/energy/gui/GuiGenerator.java new file mode 100755 index 000000000..5b5e4108f --- /dev/null +++ b/forestry_common/energy/forestry/energy/gui/GuiGenerator.java @@ -0,0 +1,42 @@ +/******************************************************************************* + * Copyright 2011-2014 by SirSengir + * + * This work is licensed under a Creative Commons Attribution-NonCommercial-NoDerivs 3.0 Unported License. + * + * To view a copy of this license, visit http://creativecommons.org/licenses/by-nc-nd/3.0/. + ******************************************************************************/ +package forestry.energy.gui; + +import net.minecraft.entity.player.InventoryPlayer; + +import forestry.core.config.Defaults; +import forestry.core.gui.GuiForestry; +import forestry.core.gui.widgets.TankWidget; +import forestry.core.utils.StringUtil; +import forestry.energy.gadgets.MachineGenerator; + +public class GuiGenerator extends GuiForestry { + + public GuiGenerator(InventoryPlayer inventory, MachineGenerator tile) { + super(Defaults.TEXTURE_PATH_GUI + "/generator.png", new ContainerGenerator(inventory, tile), tile); + widgetManager.add(new TankWidget(this.widgetManager, 49, 17, 0)); + } + + @Override + protected void drawGuiContainerForegroundLayer(int mouseX, int mouseY) { + super.drawGuiContainerForegroundLayer(mouseX, mouseY); + String title = StringUtil.localize("tile.for." + tile.getInventoryName()); + this.fontRendererObj.drawString(title, getCenteredOffset(title), 6, fontColor.get("gui.title")); + } + + @Override + protected void drawGuiContainerBackgroundLayer(float var1, int mouseX, int mouseY) { + super.drawGuiContainerBackgroundLayer(var1, mouseX, mouseY); + MachineGenerator boiler = tile; + + int progress = boiler.getStoredScaled(49); + if (progress > 0) + drawTexturedModalRect(guiLeft + 108, guiTop + 38, 176, 91, progress, 18); + } + +} diff --git a/forestry_common/energy/forestry/energy/proxy/ClientProxyEnergy.java b/forestry_common/energy/forestry/energy/proxy/ClientProxyEnergy.java new file mode 100755 index 000000000..6f478ce0f --- /dev/null +++ b/forestry_common/energy/forestry/energy/proxy/ClientProxyEnergy.java @@ -0,0 +1,19 @@ +/******************************************************************************* + * Copyright 2011-2014 by SirSengir + * + * This work is licensed under a Creative Commons Attribution-NonCommercial-NoDerivs 3.0 Unported License. + * + * To view a copy of this license, visit http://creativecommons.org/licenses/by-nc-nd/3.0/. + ******************************************************************************/ +package forestry.energy.proxy; + +import forestry.core.interfaces.IBlockRenderer; +import forestry.energy.render.RenderEngine; + +public class ClientProxyEnergy extends ProxyEnergy { + + public IBlockRenderer getRenderDefaultEngine(String gfxBase) { + return new RenderEngine(gfxBase); + } + +} diff --git a/forestry_common/energy/forestry/energy/proxy/ProxyEnergy.java b/forestry_common/energy/forestry/energy/proxy/ProxyEnergy.java new file mode 100755 index 000000000..a24ca9a69 --- /dev/null +++ b/forestry_common/energy/forestry/energy/proxy/ProxyEnergy.java @@ -0,0 +1,16 @@ +/******************************************************************************* + * Copyright 2011-2014 by SirSengir + * + * This work is licensed under a Creative Commons Attribution-NonCommercial-NoDerivs 3.0 Unported License. + * + * To view a copy of this license, visit http://creativecommons.org/licenses/by-nc-nd/3.0/. + ******************************************************************************/ +package forestry.energy.proxy; + +import forestry.core.interfaces.IBlockRenderer; + +public class ProxyEnergy { + public IBlockRenderer getRenderDefaultEngine(String gfxBase) { + return null; + } +} diff --git a/forestry_common/energy/forestry/energy/render/RenderEngine.java b/forestry_common/energy/forestry/energy/render/RenderEngine.java new file mode 100755 index 000000000..92fce9709 --- /dev/null +++ b/forestry_common/energy/forestry/energy/render/RenderEngine.java @@ -0,0 +1,203 @@ +/******************************************************************************* + * Copyright 2011-2014 by SirSengir + * + * This work is licensed under a Creative Commons Attribution-NonCommercial-NoDerivs 3.0 Unported License. + * + * To view a copy of this license, visit http://creativecommons.org/licenses/by-nc-nd/3.0/. + ******************************************************************************/ +package forestry.energy.render; + +import net.minecraft.client.model.ModelBase; +import net.minecraft.client.model.ModelRenderer; +import net.minecraft.client.renderer.tileentity.TileEntitySpecialRenderer; +import net.minecraft.tileentity.TileEntity; +import net.minecraft.util.ResourceLocation; + +import net.minecraftforge.common.util.ForgeDirection; + +import org.lwjgl.opengl.GL11; + +import forestry.core.TemperatureState; +import forestry.core.config.Defaults; +import forestry.core.gadgets.Engine; +import forestry.core.interfaces.IBlockRenderer; +import forestry.core.proxy.Proxies; +import forestry.core.utils.ForestryResource; + +public class RenderEngine extends TileEntitySpecialRenderer implements IBlockRenderer { + + private final ModelBase model = new ModelBase() { + }; + private final ModelRenderer boiler; + private final ModelRenderer trunk; + private final ModelRenderer piston; + private final ModelRenderer extension; + + private static enum Textures { + + BASE, PISTON, EXTENSION, TRUNK_HIGHEST, TRUNK_HIGHER, TRUNK_HIGH, TRUNK_MEDIUM, TRUNK_LOW + }; + private ResourceLocation[] textures; + private static final float[] angleMap = new float[6]; + + static { + angleMap[ForgeDirection.EAST.ordinal()] = (float) -Math.PI / 2; + angleMap[ForgeDirection.WEST.ordinal()] = (float) Math.PI / 2; + angleMap[ForgeDirection.UP.ordinal()] = 0; + angleMap[ForgeDirection.DOWN.ordinal()] = (float) Math.PI; + angleMap[ForgeDirection.SOUTH.ordinal()] = (float) Math.PI / 2; + angleMap[ForgeDirection.NORTH.ordinal()] = (float) -Math.PI / 2; + } + + public RenderEngine() { + boiler = new ModelRenderer(model, 0, 0); + boiler.addBox(-8F, -8F, -8F, 16, 6, 16); + boiler.rotationPointX = 8; + boiler.rotationPointY = 8; + boiler.rotationPointZ = 8; + + trunk = new ModelRenderer(model, 0, 0); + trunk.addBox(-4F, -4F, -4F, 8, 12, 8); + trunk.rotationPointX = 8F; + trunk.rotationPointY = 8F; + trunk.rotationPointZ = 8F; + + piston = new ModelRenderer(model, 0, 0); + piston.addBox(-6F, -2, -6F, 12, 4, 12); + piston.rotationPointX = 8F; + piston.rotationPointY = 8F; + piston.rotationPointZ = 8F; + + extension = new ModelRenderer(model, 0, 0); + extension.addBox(-5F, -3, -5F, 10, 2, 10); + extension.rotationPointX = 8F; + extension.rotationPointY = 8F; + extension.rotationPointZ = 8F; + } + + public RenderEngine(String baseTexture) { + this(); + + textures = new ResourceLocation[] { + new ForestryResource(baseTexture + "base.png"), + new ForestryResource(baseTexture + "piston.png"), + new ForestryResource(baseTexture + "extension.png"), + new ForestryResource(Defaults.TEXTURE_PATH_BLOCKS + "/engine_trunk_highest.png"), + new ForestryResource(Defaults.TEXTURE_PATH_BLOCKS + "/engine_trunk_higher.png"), + new ForestryResource(Defaults.TEXTURE_PATH_BLOCKS + "/engine_trunk_high.png"), + new ForestryResource(Defaults.TEXTURE_PATH_BLOCKS + "/engine_trunk_medium.png"), + new ForestryResource(Defaults.TEXTURE_PATH_BLOCKS + "/engine_trunk_low.png"), }; + } + + @Override + public void inventoryRender(double x, double y, double z, float f, float f1) { + render(TemperatureState.COOL, 0.25F, ForgeDirection.UP, x, y, z); + } + + @Override + public void renderTileEntityAt(TileEntity tile, double d, double d1, double d2, float f) { + + Engine engine = (Engine) tile; + + if (engine != null) + render(engine.getTemperatureState(), engine.progress, engine.getOrientation(), d, d1, d2); + } + + private void render(TemperatureState state, float progress, ForgeDirection orientation, double x, double y, double z) { + + GL11.glPushMatrix(); + GL11.glPushAttrib(GL11.GL_ENABLE_BIT); + GL11.glEnable(GL11.GL_LIGHTING); + GL11.glDisable(GL11.GL_BLEND); + GL11.glEnable(GL11.GL_CULL_FACE); + GL11.glColor3f(1, 1, 1); + + GL11.glTranslatef((float) x, (float) y, (float) z); + + float step; + + if (progress > 0.5) + step = 5.99F - (progress - 0.5F) * 2F * 5.99F; + else + step = progress * 2F * 5.99F; + + float tfactor = step / 16; + + float[] angle = { 0, 0, 0 }; + float[] translate = { orientation.offsetX, orientation.offsetY, orientation.offsetZ }; + + switch (orientation) { + case EAST: + case WEST: + case DOWN: + angle[2] = angleMap[orientation.ordinal()]; + break; + case SOUTH: + case NORTH: + default: + angle[0] = angleMap[orientation.ordinal()]; + break; + } + + boiler.rotateAngleX = angle[0]; + boiler.rotateAngleY = angle[1]; + boiler.rotateAngleZ = angle[2]; + + trunk.rotateAngleX = angle[0]; + trunk.rotateAngleY = angle[1]; + trunk.rotateAngleZ = angle[2]; + + piston.rotateAngleX = angle[0]; + piston.rotateAngleY = angle[1]; + piston.rotateAngleZ = angle[2]; + + extension.rotateAngleX = angle[0]; + extension.rotateAngleY = angle[1]; + extension.rotateAngleZ = angle[2]; + + float factor = (float) (1.0 / 16.0); + + Proxies.common.bindTexture(textures[Textures.BASE.ordinal()]); + boiler.render(factor); + + Proxies.common.bindTexture(textures[Textures.PISTON.ordinal()]); + GL11.glTranslatef(translate[0] * tfactor, translate[1] * tfactor, translate[2] * tfactor); + piston.render(factor); + GL11.glTranslatef(-translate[0] * tfactor, -translate[1] * tfactor, -translate[2] * tfactor); + + ResourceLocation texture; + + switch (state) { + case OVERHEATING: + texture = textures[Textures.TRUNK_HIGHEST.ordinal()]; + break; + case RUNNING_HOT: + texture = textures[Textures.TRUNK_HIGHER.ordinal()]; + break; + case OPERATING_TEMPERATURE: + texture = textures[Textures.TRUNK_HIGH.ordinal()]; + break; + case WARMED_UP: + texture = textures[Textures.TRUNK_MEDIUM.ordinal()]; + break; + case COOL: + default: + texture = textures[Textures.TRUNK_LOW.ordinal()]; + break; + + } + Proxies.common.bindTexture(texture); + trunk.render(factor); + + Proxies.common.bindTexture(textures[Textures.EXTENSION.ordinal()]); + float chamberf = 2F / 16F; + + for (int i = 0; i <= step + 2; i += 2) { + extension.render(factor); + GL11.glTranslatef(translate[0] * chamberf, translate[1] * chamberf, translate[2] * chamberf); + } + + GL11.glPopAttrib(); + GL11.glPopMatrix(); + } +} diff --git a/forestry_common/energy/forestry/plugins/PluginEnergy.java b/forestry_common/energy/forestry/plugins/PluginEnergy.java new file mode 100755 index 000000000..0a150d5d5 --- /dev/null +++ b/forestry_common/energy/forestry/plugins/PluginEnergy.java @@ -0,0 +1,200 @@ +/******************************************************************************* + * Copyright 2011-2014 by SirSengir + * + * This work is licensed under a Creative Commons Attribution-NonCommercial-NoDerivs 3.0 Unported License. + * + * To view a copy of this license, visit http://creativecommons.org/licenses/by-nc-nd/3.0/. + ******************************************************************************/ +package forestry.plugins; + +import net.minecraft.block.material.Material; +import net.minecraft.init.Blocks; +import net.minecraft.init.Items; +import net.minecraft.item.ItemStack; + +import cpw.mods.fml.common.SidedProxy; +import cpw.mods.fml.common.network.IGuiHandler; + +import forestry.api.circuits.ChipsetManager; +import forestry.api.circuits.ICircuitLayout; +import forestry.api.core.PluginInfo; +import forestry.api.fuels.GeneratorFuel; +import forestry.core.GameMode; +import forestry.core.circuits.Circuit; +import forestry.core.circuits.CircuitId; +import forestry.core.config.Config; +import forestry.core.config.Defaults; +import forestry.core.config.ForestryBlock; +import forestry.core.config.ForestryItem; +import forestry.core.gadgets.BlockBase; +import forestry.core.gadgets.MachineDefinition; +import forestry.core.interfaces.IOreDictionaryHandler; +import forestry.core.interfaces.ISaveEventHandler; +import forestry.core.items.ItemForestryBlock; +import forestry.core.proxy.Proxies; +import forestry.core.utils.LiquidHelper; +import forestry.core.utils.ShapedRecipeCustom; +import forestry.energy.GuiHandlerEnergy; +import forestry.energy.circuits.CircuitElectricBoost; +import forestry.energy.circuits.CircuitElectricChoke; +import forestry.energy.circuits.CircuitElectricEfficiency; +import forestry.energy.circuits.CircuitFireDampener; +import forestry.energy.gadgets.EngineBronze; +import forestry.energy.gadgets.EngineClockwork; +import forestry.energy.gadgets.EngineCopper; +import forestry.energy.gadgets.EngineDefinition; +import forestry.energy.gadgets.EngineTin; +import forestry.energy.gadgets.MachineGenerator; +import forestry.energy.proxy.ProxyEnergy; + +@PluginInfo(pluginID = "Energy", name = "Energy", author = "SirSengir", url = Defaults.URL, description = "Adds several engines compatible with BuildCraft 3 as well as a generator for IC2.") +public class PluginEnergy extends NativePlugin { + + @SidedProxy(clientSide = "forestry.energy.proxy.ClientProxyEnergy", serverSide = "forestry.energy.proxy.ProxyEnergy") + public static ProxyEnergy proxy; + public static MachineDefinition definitionEngineTin; + public static MachineDefinition definitionEngineCopper; + public static MachineDefinition definitionEngineBronze; + public static MachineDefinition definitionEngineClockwork; + public static MachineDefinition definitionGenerator; + + @Override + public boolean isAvailable() { + return !Config.disableEnergy; + } + + @Override + public void preInit() { + super.preInit(); + + ForestryBlock.engine = new BlockBase(Material.iron, true); + ForestryBlock.engine.setBlockName("for.engine"); + Proxies.common.registerBlock(ForestryBlock.engine, ItemForestryBlock.class); + + definitionEngineTin = ForestryBlock.engine.addDefinition(new EngineDefinition(Defaults.DEFINITION_ENGINETIN_META, "forestry.EngineTin", EngineTin.class, + PluginEnergy.proxy.getRenderDefaultEngine(Defaults.TEXTURE_PATH_BLOCKS + "/engine_tin_"), ShapedRecipeCustom.createShapedRecipe( + new ItemStack(ForestryBlock.engine, 1, Defaults.DEFINITION_ENGINETIN_META), + "###", + " X ", + "YVY", + '#', "ingotTin", + 'X', Blocks.glass, + 'Y', "gearTin", + 'V', Blocks.piston))); + definitionEngineCopper = ForestryBlock.engine.addDefinition(new EngineDefinition(Defaults.DEFINITION_ENGINECOPPER_META, "forestry.EngineCopper", EngineCopper.class, + PluginEnergy.proxy.getRenderDefaultEngine(Defaults.TEXTURE_PATH_BLOCKS + "/engine_copper_"), ShapedRecipeCustom.createShapedRecipe( + new ItemStack(ForestryBlock.engine, 1, Defaults.DEFINITION_ENGINECOPPER_META), + "###", + " X ", + "YVY", + '#', "ingotCopper", + 'X', Blocks.glass, + 'Y', "gearCopper", + 'V', Blocks.piston))); + definitionEngineBronze = ForestryBlock.engine.addDefinition(new EngineDefinition(Defaults.DEFINITION_ENGINEBRONZE_META, "forestry.EngineBronze", EngineBronze.class, + PluginEnergy.proxy.getRenderDefaultEngine(Defaults.TEXTURE_PATH_BLOCKS + "/engine_bronze_"), ShapedRecipeCustom.createShapedRecipe( + new ItemStack(ForestryBlock.engine, 1, Defaults.DEFINITION_ENGINEBRONZE_META), + "###", + " X ", + "YVY", + '#', "ingotBronze", + 'X', Blocks.glass, + 'Y', "gearBronze", + 'V', Blocks.piston))); + + definitionGenerator = ForestryBlock.engine.addDefinition(new MachineDefinition(Defaults.DEFINITION_GENERATOR_META, "forestry.Generator", MachineGenerator.class, + Proxies.render.getRenderDefaultMachine(Defaults.TEXTURE_PATH_BLOCKS + "/generator_"), ShapedRecipeCustom.createShapedRecipe(new ItemStack(ForestryBlock.engine, 1, Defaults.DEFINITION_GENERATOR_META), + "X#X", + "XYX", + "X#X", + '#', Blocks.glass, + 'X', Items.gold_ingot, + 'Y', ForestryItem.sturdyCasing))); + + ShapedRecipeCustom clockworkRecipe = null; + if (GameMode.getGameMode().getBooleanSetting("energy.engine.clockwork")) { + clockworkRecipe = ShapedRecipeCustom.createShapedRecipe( + new ItemStack(ForestryBlock.engine, 1, Defaults.DEFINITION_ENGINECLOCKWORK_META), + "###", + " X ", + "ZVY", + '#', "plankWood", + 'X', Blocks.glass, + 'Y', Items.clock, + 'Z', ForestryItem.gearCopper, + 'V', Blocks.piston); + } + + definitionEngineClockwork = ForestryBlock.engine.addDefinition(new EngineDefinition(Defaults.DEFINITION_ENGINECLOCKWORK_META, "forestry.EngineClockwork", EngineClockwork.class, + PluginEnergy.proxy.getRenderDefaultEngine(Defaults.TEXTURE_PATH_BLOCKS + "/engine_clock_"), clockworkRecipe)); + + ChipsetManager.circuitRegistry.registerLegacyMapping(CircuitId.ELECTRIC_CHOKE_I, "forestry.energyChoke1"); + ChipsetManager.circuitRegistry.registerLegacyMapping(CircuitId.FIRE_DAMPENER_I, "forestry.energyDampener1"); + ChipsetManager.circuitRegistry.registerLegacyMapping(CircuitId.ELECTRIC_EFFICIENCY_I, "forestry.energyEfficiency1"); + ChipsetManager.circuitRegistry.registerLegacyMapping(CircuitId.ELECTRIC_BOOST_I, "forestry.energyBoost1"); + ChipsetManager.circuitRegistry.registerLegacyMapping(CircuitId.ELECTRIC_BOOST_II, "forestry.energyBoost2"); + } + + @Override + public void doInit() { + super.doInit(); + + definitionEngineTin.register(); + definitionEngineCopper.register(); + definitionEngineBronze.register(); + definitionGenerator.register(); + definitionEngineClockwork.register(); + + GeneratorFuel.fuels.put(LiquidHelper.getLiquid(Defaults.LIQUID_ETHANOL, 1).getFluid().getID(), new GeneratorFuel(LiquidHelper.getLiquid(Defaults.LIQUID_ETHANOL, 1), + (int) (32 * GameMode.getGameMode().getFloatSetting("fuel.ethanol.generator")), 4)); + GeneratorFuel.fuels.put(LiquidHelper.getLiquid(Defaults.LIQUID_BIOMASS, 1).getFluid().getID(), new GeneratorFuel(LiquidHelper.getLiquid(Defaults.LIQUID_BIOMASS, 1), + (int) (8 * GameMode.getGameMode().getFloatSetting("fuel.biomass.generator")), 1)); + + Circuit.energyElectricChoke1 = new CircuitElectricChoke("energyChoke1"); + Circuit.energyFireDampener1 = new CircuitFireDampener("energyDampener1"); + Circuit.energyElectricEfficiency1 = new CircuitElectricEfficiency("energyEfficiency1"); + Circuit.energyElectricBoost1 = new CircuitElectricBoost("energyBoost1", 2, 7, 2, "electric.boost.1", new String[] { "Increases output by 2 MJ/t", + "Increases intake by 7 EU/t" }); + Circuit.energyElectricBoost2 = new CircuitElectricBoost("energyBoost2", 2, 15, 4, "electric.boost.2", new String[] { "Increases output by 4 MJ/t", + "Increases intake by 15 EU/t" }); + } + + @Override + protected void registerItems() { + } + + @Override + protected void registerBackpackItems() { + } + + @Override + protected void registerRecipes() { + + ICircuitLayout layout = ChipsetManager.circuitRegistry.getLayout("forestry.engine.tin"); + + // / Solder Manager + ChipsetManager.solderManager.addRecipe(layout, ForestryItem.tubes.getItemStack(1, 0), Circuit.energyElectricChoke1); + ChipsetManager.solderManager.addRecipe(layout, ForestryItem.tubes.getItemStack(1, 1), Circuit.energyElectricBoost1); + ChipsetManager.solderManager.addRecipe(layout, ForestryItem.tubes.getItemStack(1, 2), Circuit.energyElectricBoost2); + ChipsetManager.solderManager.addRecipe(layout, ForestryItem.tubes.getItemStack(1, 3), Circuit.energyElectricEfficiency1); + } + + @Override + protected void registerCrates() { + } + + @Override + public IGuiHandler getGuiHandler() { + return new GuiHandlerEnergy(); + } + + @Override + public ISaveEventHandler getSaveEventHandler() { + return null; + } + + @Override + public IOreDictionaryHandler getDictionaryHandler() { + return null; + } +} diff --git a/forestry_common/factory/forestry/factory/GuiHandlerFactory.java b/forestry_common/factory/forestry/factory/GuiHandlerFactory.java new file mode 100755 index 000000000..d6aaa9cc3 --- /dev/null +++ b/forestry_common/factory/forestry/factory/GuiHandlerFactory.java @@ -0,0 +1,136 @@ +/******************************************************************************* + * Copyright 2011-2014 by SirSengir + * + * This work is licensed under a Creative Commons Attribution-NonCommercial-NoDerivs 3.0 Unported License. + * + * To view a copy of this license, visit http://creativecommons.org/licenses/by-nc-nd/3.0/. + ******************************************************************************/ +package forestry.factory; + +import net.minecraft.entity.player.EntityPlayer; +import net.minecraft.world.World; + +import forestry.core.GuiHandlerBase; +import forestry.core.network.GuiId; +import forestry.factory.gadgets.MachineBottler; +import forestry.factory.gadgets.MachineCarpenter; +import forestry.factory.gadgets.MachineCentrifuge; +import forestry.factory.gadgets.MachineFabricator; +import forestry.factory.gadgets.MachineFermenter; +import forestry.factory.gadgets.MachineMoistener; +import forestry.factory.gadgets.MachineRaintank; +import forestry.factory.gadgets.MachineSqueezer; +import forestry.factory.gadgets.MachineStill; +import forestry.factory.gadgets.TileWorktable; +import forestry.factory.gui.ContainerBottler; +import forestry.factory.gui.ContainerCarpenter; +import forestry.factory.gui.ContainerCentrifuge; +import forestry.factory.gui.ContainerFabricator; +import forestry.factory.gui.ContainerFermenter; +import forestry.factory.gui.ContainerMoistener; +import forestry.factory.gui.ContainerRaintank; +import forestry.factory.gui.ContainerSqueezer; +import forestry.factory.gui.ContainerStill; +import forestry.factory.gui.ContainerWorktable; +import forestry.factory.gui.GuiBottler; +import forestry.factory.gui.GuiCarpenter; +import forestry.factory.gui.GuiCentrifuge; +import forestry.factory.gui.GuiFabricator; +import forestry.factory.gui.GuiFermenter; +import forestry.factory.gui.GuiMoistener; +import forestry.factory.gui.GuiRaintank; +import forestry.factory.gui.GuiSqueezer; +import forestry.factory.gui.GuiStill; +import forestry.factory.gui.GuiWorktable; + +public class GuiHandlerFactory extends GuiHandlerBase { + + @Override + public Object getClientGuiElement(int id, EntityPlayer player, World world, int x, int y, int z) { + + if (id >= GuiId.values().length) + return null; + + switch (GuiId.values()[id]) { + + case BottlerGUI: + return new GuiBottler(player.inventory, (MachineBottler) getTileForestry(world, x, y, z)); + + case CarpenterGUI: + return new GuiCarpenter(player.inventory, (MachineCarpenter) getTileForestry(world, x, y, z)); + + case CentrifugeGUI: + return new GuiCentrifuge(player.inventory, (MachineCentrifuge) getTileForestry(world, x, y, z)); + + case FabricatorGUI: + return new GuiFabricator(player.inventory, (MachineFabricator) getTileForestry(world, x, y, z)); + + case FermenterGUI: + return new GuiFermenter(player.inventory, (MachineFermenter) getTileForestry(world, x, y, z)); + + case MoistenerGUI: + return new GuiMoistener(player.inventory, (MachineMoistener) getTileForestry(world, x, y, z)); + + case RaintankGUI: + return new GuiRaintank(player.inventory, (MachineRaintank) getTileForestry(world, x, y, z)); + + case SqueezerGUI: + return new GuiSqueezer(player.inventory, (MachineSqueezer) getTileForestry(world, x, y, z)); + + case StillGUI: + return new GuiStill(player.inventory, (MachineStill) getTileForestry(world, x, y, z)); + + case WorktableGUI: + return new GuiWorktable(player, (TileWorktable)getTileForestry(world, x, y, z)); + + default: + return null; + + } + } + + @Override + public Object getServerGuiElement(int id, EntityPlayer player, World world, int x, int y, int z) { + + if (id >= GuiId.values().length) + return null; + + switch (GuiId.values()[id]) { + + case BottlerGUI: + return new ContainerBottler(player.inventory, (MachineBottler) getTileForestry(world, x, y, z)); + + case CarpenterGUI: + return new ContainerCarpenter(player.inventory, (MachineCarpenter) getTileForestry(world, x, y, z)); + + case CentrifugeGUI: + return new ContainerCentrifuge(player.inventory, (MachineCentrifuge) getTileForestry(world, x, y, z)); + + case FabricatorGUI: + return new ContainerFabricator(player.inventory, (MachineFabricator) getTileForestry(world, x, y, z)); + + case FermenterGUI: + return new ContainerFermenter(player.inventory, (MachineFermenter) getTileForestry(world, x, y, z)); + + case MoistenerGUI: + return new ContainerMoistener(player.inventory, (MachineMoistener) getTileForestry(world, x, y, z)); + + case RaintankGUI: + return new ContainerRaintank(player.inventory, (MachineRaintank) getTileForestry(world, x, y, z)); + + case SqueezerGUI: + return new ContainerSqueezer(player.inventory, (MachineSqueezer) getTileForestry(world, x, y, z)); + + case StillGUI: + return new ContainerStill(player.inventory, (MachineStill) getTileForestry(world, x, y, z)); + + case WorktableGUI: + return new ContainerWorktable(player, (TileWorktable) getTileForestry(world, x, y, z)); + + default: + return null; + + } + } + +} diff --git a/forestry_common/factory/forestry/factory/gadgets/MachineBottler.java b/forestry_common/factory/forestry/factory/gadgets/MachineBottler.java new file mode 100755 index 000000000..e07fc0fe7 --- /dev/null +++ b/forestry_common/factory/forestry/factory/gadgets/MachineBottler.java @@ -0,0 +1,508 @@ +/******************************************************************************* + * Copyright 2011-2014 by SirSengir + * + * This work is licensed under a Creative Commons Attribution-NonCommercial-NoDerivs 3.0 Unported License. + * + * To view a copy of this license, visit http://creativecommons.org/licenses/by-nc-nd/3.0/. + ******************************************************************************/ +package forestry.factory.gadgets; + +import java.util.ArrayList; +import java.util.HashMap; +import java.util.LinkedList; +import java.util.Map; +import java.util.Stack; + +import net.minecraft.entity.player.EntityPlayer; +import net.minecraft.inventory.Container; +import net.minecraft.inventory.ICrafting; +import net.minecraft.inventory.ISidedInventory; +import net.minecraft.item.ItemStack; +import net.minecraft.nbt.NBTTagCompound; +import net.minecraft.nbt.NBTTagList; + +import net.minecraftforge.common.util.ForgeDirection; +import net.minecraftforge.fluids.FluidContainerRegistry; +import net.minecraftforge.fluids.FluidContainerRegistry.FluidContainerData; +import net.minecraftforge.fluids.FluidRegistry; +import net.minecraftforge.fluids.FluidStack; + +import buildcraft.api.gates.ITrigger; +import buildcraft.api.power.PowerHandler; + +import forestry.api.core.ForestryAPI; +import forestry.api.recipes.IBottlerManager; +import forestry.api.recipes.RecipeManagers; +import forestry.core.EnumErrorCode; +import forestry.core.config.Config; +import forestry.core.config.Defaults; +import forestry.core.gadgets.TileBase; +import forestry.core.gadgets.TilePowered; +import forestry.core.interfaces.ILiquidTankContainer; +import forestry.core.network.EntityNetData; +import forestry.core.network.GuiId; +import forestry.core.triggers.ForestryTrigger; +import forestry.core.utils.EnumTankLevel; +import forestry.core.utils.ForestryTank; +import forestry.core.utils.InventoryAdapter; +import forestry.core.utils.LiquidHelper; +import forestry.core.utils.StackUtils; +import forestry.core.utils.Utils; + +public class MachineBottler extends TilePowered implements ISidedInventory, ILiquidTankContainer { + + /* CONSTANTS */ + public static final short SLOT_RESOURCE = 0; + public static final short SLOT_PRODUCT = 1; + public static final short SLOT_CAN = 2; + + public static final short CYCLES_FILLING_DEFAULT = 5; + + /* RECIPE MANAGMENT */ + public static class Recipe { + public final int cyclesPerUnit; + public final FluidStack input; + public final ItemStack can; + public final ItemStack bottled; + + public Recipe(int cyclesPerUnit, FluidStack input, ItemStack can, ItemStack bottled) { + this.cyclesPerUnit = cyclesPerUnit; + this.input = input; + this.can = can; + this.bottled = bottled; + } + + public boolean matches(FluidStack res, ItemStack empty) { + return input.isFluidEqual(res) && res.amount >= input.amount && can.isItemEqual(empty); + } + + public boolean hasInput(FluidStack res) { + return input.isFluidEqual(res); + } + } + + public static class RecipeManager implements IBottlerManager { + public static ArrayList recipes = new ArrayList(); + + @Override + public void addRecipe(int cyclesPerUnit, FluidStack input, ItemStack can, ItemStack bottled) { + recipes.add(new MachineBottler.Recipe(cyclesPerUnit, input, can, bottled)); + } + + /** + * + * @param res + * @param empty + * @return Recipe matching both res and empty, null if none + */ + public static Recipe findMatchingRecipe(FluidStack res, ItemStack empty) { + // We need both ingredients + if (res == null || empty == null) + return null; + + for (int i = 0; i < recipes.size(); i++) { + Recipe recipe = recipes.get(i); + if (recipe.matches(res, empty)) + return recipe; + } + + // No custom recipe matched. See if the liquid dictionary has anything. + if(FluidContainerRegistry.isEmptyContainer(empty)) { + ItemStack filled = FluidContainerRegistry.fillFluidContainer(res, empty); + if(filled != null) { + RecipeManagers.bottlerManager.addRecipe(CYCLES_FILLING_DEFAULT, FluidContainerRegistry.getFluidForFilledItem(filled), empty, filled); + return findMatchingRecipe(res, empty); + } + } + + return null; + } + + /** + * + * @param res + * @return true if any recipe has a matching input + */ + public static boolean isInput(FluidStack res) { + for (int i = 0; i < recipes.size(); i++) { + Recipe recipe = recipes.get(i); + if (recipe.hasInput(res)) + return true; + } + + return FluidRegistry.isFluidRegistered(res.getFluid()); + + } + + @Override + public Map getRecipes() { + HashMap recipeList = new HashMap(); + + for (Recipe recipe : recipes) + recipeList.put(new Object[] { recipe.input, recipe.can }, new Object[] { recipe.bottled }); + + return recipeList; + } + } + + @EntityNetData + public ForestryTank resourceTank = new ForestryTank(Defaults.PROCESSOR_TANK_CAPACITY); + + private final InventoryAdapter inventory = new InventoryAdapter(3, "Items"); + + private boolean productPending = false; + + private Recipe currentRecipe; + private final Stack pendingProducts = new Stack(); + private int fillingTime; + private int fillingTotalTime; + + public MachineBottler() { + setHints(Config.hints.get("bottler")); + } + + @Override + public String getInventoryName() { + return "factory.0"; + } + + @Override + public void openGui(EntityPlayer player, TileBase tile) { + player.openGui(ForestryAPI.instance, GuiId.BottlerGUI.ordinal(), player.worldObj, xCoord, yCoord, zCoord); + } + + + @Override + protected void configurePowerProvider(PowerHandler provider) { + provider.configure(50, 110, 5, 400); + } + + /* SAVING & LOADING */ + @Override + public void writeToNBT(NBTTagCompound nbttagcompound) { + super.writeToNBT(nbttagcompound); + + nbttagcompound.setInteger("FillingTime", fillingTime); + nbttagcompound.setInteger("FillingTotalTime", fillingTotalTime); + nbttagcompound.setBoolean("ProductPending", productPending); + + NBTTagCompound NBTresourceSlot = new NBTTagCompound(); + resourceTank.writeToNBT(NBTresourceSlot); + nbttagcompound.setTag("ResourceTank", NBTresourceSlot); + + inventory.writeToNBT(nbttagcompound); + + NBTTagList nbttaglist = new NBTTagList(); + ItemStack[] offspring = pendingProducts.toArray(new ItemStack[pendingProducts.size()]); + for (int i = 0; i < offspring.length; i++) + if (offspring[i] != null) { + NBTTagCompound nbttagcompound1 = new NBTTagCompound(); + nbttagcompound1.setByte("Slot", (byte) i); + offspring[i].writeToNBT(nbttagcompound1); + nbttaglist.appendTag(nbttagcompound1); + } + nbttagcompound.setTag("PendingProducts", nbttaglist); + } + + @Override + public void readFromNBT(NBTTagCompound nbttagcompound) { + super.readFromNBT(nbttagcompound); + + fillingTime = nbttagcompound.getInteger("FillingTime"); + fillingTotalTime = nbttagcompound.getInteger("FillingTotalTime"); + productPending = nbttagcompound.getBoolean("ProductPending"); + + resourceTank = new ForestryTank(Defaults.PROCESSOR_TANK_CAPACITY); + if (nbttagcompound.hasKey("ResourceTank")) + resourceTank.readFromNBT(nbttagcompound.getCompoundTag("ResourceTank")); + + inventory.readFromNBT(nbttagcompound); + + NBTTagList nbttaglist = nbttagcompound.getTagList("PendingProducts", 10); + for (int i = 0; i < nbttaglist.tagCount(); i++) { + NBTTagCompound nbttagcompound1 = nbttaglist.getCompoundTagAt(i); + pendingProducts.add(ItemStack.loadItemStackFromNBT(nbttagcompound1)); + } + + checkRecipe(); + } + + @Override + public void updateServerSide() { + if (worldObj.getTotalWorldTime() % 20 * 10 != 0) + return; + + // Check if we have suitable items waiting in the item slot + if (inventory.getStackInSlot(SLOT_CAN) != null) { + FluidContainerData container = LiquidHelper.getLiquidContainer(inventory.getStackInSlot(SLOT_CAN)); + if (container != null && RecipeManager.isInput(container.fluid)) { + + inventory.setInventorySlotContents(SLOT_CAN, StackUtils.replenishByContainer(this, inventory.getStackInSlot(SLOT_CAN), container, resourceTank)); + if (inventory.getStackInSlot(SLOT_CAN).stackSize <= 0) + inventory.setInventorySlotContents(SLOT_CAN, null); + } + } + + checkRecipe(); + if (getErrorState() == EnumErrorCode.NORECIPE && currentRecipe != null) + setErrorState(EnumErrorCode.OK); + } + + @Override + public boolean workCycle() { + + checkRecipe(); + + // If we add pending products, we skip to the next work cycle. + if (tryAddPending()) + return false; + + if (!pendingProducts.isEmpty()) + return false; + + // Continue work if nothing needs to be added + if (fillingTime <= 0) + return false; + + if (currentRecipe == null) { + setErrorState(EnumErrorCode.NORECIPE); + return false; + } + + fillingTime--; + // Still not done, return + if (fillingTime > 0) { + setErrorState(EnumErrorCode.OK); + return true; + } + + // We are done, add products to queue and remove resources + pendingProducts.push(currentRecipe.bottled.copy()); + + inventory.decrStackSize(SLOT_RESOURCE, 1); + resourceTank.drain(currentRecipe.input.amount, true); + checkRecipe(); + resetRecipe(); + + while (tryAddPending()) + ; + return true; + } + + public void checkRecipe() { + Recipe sameRec = RecipeManager.findMatchingRecipe(resourceTank.getFluid(), inventory.getStackInSlot(SLOT_RESOURCE)); + + if (sameRec == null) + setErrorState(EnumErrorCode.NORECIPE); + + if (currentRecipe != sameRec) { + currentRecipe = sameRec; + resetRecipe(); + } + } + + private void resetRecipe() { + if (currentRecipe == null) { + fillingTime = 0; + fillingTotalTime = 0; + return; + } + + fillingTime = currentRecipe.cyclesPerUnit; + fillingTotalTime = currentRecipe.cyclesPerUnit; + } + + private boolean tryAddPending() { + if (pendingProducts.isEmpty()) + return false; + + ItemStack next = pendingProducts.peek(); + if (addProduct(next, true)) { + pendingProducts.pop(); + return true; + } + + setErrorState(EnumErrorCode.NOSPACE); + return false; + } + + private boolean addProduct(ItemStack product, boolean all) { + return inventory.tryAddStack(product, SLOT_PRODUCT, 1, all); + } + + // / STATE INFORMATION + @Override + public boolean isWorking() { + return fillingTime > 0; + } + + @Override + public boolean hasResourcesMin(float percentage) { + if (inventory.getStackInSlot(SLOT_RESOURCE) == null) + return false; + + return ((float) inventory.getStackInSlot(SLOT_RESOURCE).stackSize / (float) inventory.getStackInSlot(SLOT_RESOURCE).getMaxStackSize()) > percentage; + } + + @Override + public boolean hasWork() { + return currentRecipe != null; + } + + public int getFillProgressScaled(int i) { + if (fillingTotalTime == 0) + return 0; + + return (fillingTime * i) / fillingTotalTime; + + } + + public int getResourceScaled(int i) { + return (resourceTank.getFluidAmount() * i) / Defaults.PROCESSOR_TANK_CAPACITY; + } + + @Override + public EnumTankLevel getPrimaryLevel() { + return Utils.rateTankLevel(getResourceScaled(100)); + } + + /* SMP GUI */ + public void getGUINetworkData(int i, int j) { + + switch (i) { + case 0: + fillingTime = j; + break; + case 1: + fillingTotalTime = j; + break; + } + } + + public void sendGUINetworkData(Container container, ICrafting iCrafting) { + iCrafting.sendProgressBarUpdate(container, 0, fillingTime); + iCrafting.sendProgressBarUpdate(container, 1, fillingTotalTime); + } + + /* IINVENTORY */ + @Override public int getSizeInventory() { return inventory.getSizeInventory(); } + @Override public ItemStack getStackInSlot(int i) { return inventory.getStackInSlot(i); } + @Override public ItemStack decrStackSize(int i, int j) { return inventory.decrStackSize(i, j); } + @Override public void setInventorySlotContents(int i, ItemStack itemstack) { inventory.setInventorySlotContents(i, itemstack); } + @Override public ItemStack getStackInSlotOnClosing(int slot) { return inventory.getStackInSlotOnClosing(slot); } + @Override public int getInventoryStackLimit() { return inventory.getInventoryStackLimit(); } + @Override public void openInventory() {} + @Override public void closeInventory() {} + + /** + * TODO: just a specialsource workaround + */ + @Override + public boolean isUseableByPlayer(EntityPlayer player) { + return super.isUseableByPlayer(player); + } + + /** + * TODO: just a specialsource workaround + */ + @Override + public boolean hasCustomInventoryName() { + return super.hasCustomInventoryName(); + } + + /** + * TODO: just a specialsource workaround + */ + @Override + public boolean isItemValidForSlot(int slotIndex, ItemStack itemstack) { + return super.isItemValidForSlot(slotIndex, itemstack); + } + + /** + * TODO: just a specialsource workaround + */ + @Override + public boolean canInsertItem(int i, ItemStack itemstack, int j) { + return super.canInsertItem(i, itemstack, j); + } + + /** + * TODO: just a specialsource workaround + */ + @Override + public boolean canExtractItem(int i, ItemStack itemstack, int j) { + return super.canExtractItem(i, itemstack, j); + } + + /** + * TODO: just a specialsource workaround + */ + @Override + public int[] getAccessibleSlotsFromSide(int side) { + return super.getAccessibleSlotsFromSide(side); + } + + /* ISIDEDINVENTORY */ + @Override + public InventoryAdapter getInternalInventory() { + return inventory; + } + + @Override + protected boolean canTakeStackFromSide(int slotIndex, ItemStack itemstack, int side) { + + if(!super.canTakeStackFromSide(slotIndex, itemstack, side)) + return false; + + return slotIndex == SLOT_PRODUCT; + } + + @Override + protected boolean canPutStackFromSide(int slotIndex, ItemStack itemstack, int side) { + + if(!super.canPutStackFromSide(slotIndex, itemstack, side)) + return false; + + if(slotIndex == SLOT_RESOURCE) + return FluidContainerRegistry.isEmptyContainer(itemstack); + + if(slotIndex == SLOT_CAN) { + FluidContainerData container = LiquidHelper.getLiquidContainer(itemstack); + return container != null && RecipeManager.isInput(container.fluid); + } + + return false; + } + + /* ILIQUIDCONTAINER */ + @Override + public int fill(ForgeDirection from, FluidStack resource, boolean doFill) { + + if (!RecipeManager.isInput(resource)) + return 0; + + int used = resourceTank.fill(resource, doFill); + + if (doFill && used > 0) + // TODO: Slow down updates + sendNetworkUpdate(); + + return used; + } + + @Override + public ForestryTank[] getTanks() { + return new ForestryTank[] { resourceTank }; + } + + // ITRIGGERPROVIDER + @Override + public LinkedList getCustomTriggers() { + LinkedList res = new LinkedList(); + res.add(ForestryTrigger.lowResource25); + res.add(ForestryTrigger.lowResource10); + res.add(ForestryTrigger.hasWork); + return res; + } + +} diff --git a/forestry_common/factory/forestry/factory/gadgets/MachineCarpenter.java b/forestry_common/factory/forestry/factory/gadgets/MachineCarpenter.java new file mode 100755 index 000000000..d0ed4c27a --- /dev/null +++ b/forestry_common/factory/forestry/factory/gadgets/MachineCarpenter.java @@ -0,0 +1,698 @@ +/******************************************************************************* + * Copyright 2011-2014 by SirSengir + * + * This work is licensed under a Creative Commons Attribution-NonCommercial-NoDerivs 3.0 Unported License. + * + * To view a copy of this license, visit http://creativecommons.org/licenses/by-nc-nd/3.0/. + ******************************************************************************/ +package forestry.factory.gadgets; + +import java.util.ArrayList; +import java.util.HashMap; +import java.util.LinkedList; +import java.util.Map; + +import net.minecraft.entity.player.EntityPlayer; +import net.minecraft.inventory.Container; +import net.minecraft.inventory.ICrafting; +import net.minecraft.inventory.ISidedInventory; +import net.minecraft.inventory.InventoryCrafting; +import net.minecraft.item.ItemStack; +import net.minecraft.item.crafting.IRecipe; +import net.minecraft.nbt.NBTTagCompound; +import net.minecraft.nbt.NBTTagList; +import net.minecraft.world.World; + +import net.minecraftforge.common.util.ForgeDirection; +import net.minecraftforge.fluids.FluidContainerRegistry; +import net.minecraftforge.fluids.FluidContainerRegistry.FluidContainerData; +import net.minecraftforge.fluids.FluidStack; + +import buildcraft.api.gates.ITrigger; +import buildcraft.api.power.PowerHandler; + +import forestry.api.core.ForestryAPI; +import forestry.api.recipes.ICarpenterManager; +import forestry.core.EnumErrorCode; +import forestry.core.config.Config; +import forestry.core.config.Defaults; +import forestry.core.config.ForestryItem; +import forestry.core.gadgets.TileBase; +import forestry.core.gadgets.TilePowered; +import forestry.core.interfaces.ILiquidTankContainer; +import forestry.core.network.EntityNetData; +import forestry.core.network.GuiId; +import forestry.core.triggers.ForestryTrigger; +import forestry.core.utils.EnumTankLevel; +import forestry.core.utils.ForestryTank; +import forestry.core.utils.InventoryAdapter; +import forestry.core.utils.LiquidHelper; +import forestry.core.utils.ShapedRecipeCustom; +import forestry.core.utils.StackUtils; +import forestry.core.utils.TileInventoryAdapter; +import forestry.core.utils.Utils; +import forestry.factory.gui.ContainerCarpenter; + +public class MachineCarpenter extends TilePowered implements ISidedInventory, ILiquidTankContainer { + + /* CONSTANTS */ + public final static int SLOT_CRAFTING_1 = 0; + public final static int SLOT_BOX = 9; + public final static int SLOT_PRODUCT = 10; + public final static int SLOT_CAN_INPUT = 11; + public final static short SLOT_INVENTORY_1 = 12; + public final static short SLOT_INVENTORY_COUNT = 18; + + /* RECIPE MANAGMENT */ + public static class Recipe { + + private final int packagingTime; + private final FluidStack liquid; + private final ItemStack box; + private final ShapedRecipeCustom internal; + + public Recipe(int packagingTime, FluidStack liquid, ItemStack box, ShapedRecipeCustom internal) { + this.packagingTime = packagingTime; + this.liquid = liquid; + this.box = box; + this.internal = internal; + } + + public ItemStack getCraftingResult() { + return internal.getRecipeOutput(); + } + + public boolean matches(FluidStack resource, ItemStack item, InventoryCrafting inventorycrafting, World world) { + + // Check liquid + if (liquid != null && resource == null) + return false; + if (liquid != null && !liquid.isFluidEqual(resource)) + return false; + + // Check box + if (box != null && item == null) + return false; + if (box != null && !box.isItemEqual(item)) + return false; + + return internal.matches(inventorycrafting, world); + } + + public boolean hasLiquid(FluidStack resource) { + if (liquid != null && resource != null) + return liquid.isFluidEqual(resource); + else + return false; + } + + public boolean hasBox(ItemStack resource) { + if (box == null && resource == null) + return true; + else if (box == null) + return true; + + if (box.getItemDamage() > 0) + return box.isItemEqual(resource); + else + return box.getItem() == resource.getItem(); + } + + public boolean isIngredient(ItemStack resource) { + return internal.isIngredient(resource); + } + + public ItemStack getBox() { + return box; + } + + public FluidStack getLiquid() { + return liquid; + } + + public IRecipe asIRecipe() { + return internal; + } + } + + public static class RecipeManager implements ICarpenterManager { + + public static ArrayList recipes = new ArrayList(); + + @Override + public void addCrating(ItemStack itemStack) { + ItemStack uncrated = ((forestry.core.items.ItemCrated) itemStack.getItem()).getContained(itemStack); + addRecipe(Defaults.CARPENTER_CRATING_CYCLES, LiquidHelper.getLiquid(Defaults.LIQUID_WATER, Defaults.CARPENTER_CRATING_LIQUID_QUANTITY), + ForestryItem.crate.getItemStack(), itemStack, new Object[] { "###", "###", "###", '#', uncrated }); + addRecipe(null, new ItemStack(uncrated.getItem(), 9, uncrated.getItemDamage()), new Object[] { "#", Character.valueOf('#'), itemStack }); + } + + @Override + public void addCrating(String toCrate, ItemStack unpack, ItemStack crated) { + addRecipe(Defaults.CARPENTER_CRATING_CYCLES, LiquidHelper.getLiquid(Defaults.LIQUID_WATER, Defaults.CARPENTER_CRATING_LIQUID_QUANTITY), + ForestryItem.crate.getItemStack(), crated, new Object[] { "###", "###", "###", '#', toCrate }); + addRecipe(null, new ItemStack(unpack.getItem(), 9, unpack.getItemDamage()), new Object[] { "#", '#', crated }); + } + + @Override + public void addRecipe(ItemStack box, ItemStack product, Object materials[]) { + addRecipe(5, null, box, product, materials); + } + + @Override + public void addRecipe(int packagingTime, ItemStack box, ItemStack product, Object materials[]) { + addRecipe(packagingTime, null, box, product, materials); + } + + @Override + public void addRecipe(int packagingTime, FluidStack liquid, ItemStack box, ItemStack product, Object materials[]) { + recipes.add(new Recipe(packagingTime, liquid, box, ShapedRecipeCustom.createShapedRecipe(product, materials))); + } + + public static Recipe findMatchingRecipe(FluidStack liquid, ItemStack item, InventoryCrafting inventorycrafting, World world) { + for (int i = 0; i < recipes.size(); i++) { + Recipe recipe = recipes.get(i); + if (recipe.matches(liquid, item, inventorycrafting, world)) + return recipe; + } + return null; + } + + public static boolean isResourceLiquid(FluidStack liquid) { + for (Recipe recipe : recipes) { + if (recipe.hasLiquid(liquid)) + return true; + } + + return false; + } + + public static boolean isBox(ItemStack resource) { + for (Recipe recipe : recipes) { + if (StackUtils.isIdenticalItem(recipe.getBox(), resource)) + return true; + } + + return false; + } + + @Override + public Map getRecipes() { + + HashMap recipeList = new HashMap(); + + for (Recipe recipe : recipes) { + recipeList.put(recipe.internal.getIngredients(), new Object[] { recipe.getCraftingResult() }); + } + + return recipeList; + } + } + + /* MEMBER */ + @EntityNetData + public ForestryTank resourceTank = new ForestryTank(Defaults.PROCESSOR_TANK_CAPACITY); + private final TileInventoryAdapter craftingInventory; + private final TileInventoryAdapter accessibleInventory; + public MachineCarpenter.Recipe currentRecipe; + public MachineCarpenter.Recipe lastRecipe; + public ContainerCarpenter activeContainer; + private int packageTime; + private int totalTime; + private ItemStack currentProduct; + private ItemStack pendingProduct; + + public ItemStack getBoxStack() { + return accessibleInventory.getStackInSlot(SLOT_BOX); + } + + public MachineCarpenter() { + setHints(Config.hints.get("carpenter")); + craftingInventory = new TileInventoryAdapter(this, 10, "CraftItems"); + accessibleInventory = (TileInventoryAdapter) new TileInventoryAdapter(this, 30, "Items").configureSided(Defaults.FACINGS, SLOT_BOX, 20); + } + + @Override + public String getInventoryName() { + return "factory.1"; + } + + @Override + public void openGui(EntityPlayer player, TileBase tile) { + player.openGui(ForestryAPI.instance, GuiId.CarpenterGUI.ordinal(), player.worldObj, xCoord, yCoord, zCoord); + } + + @Override + protected void configurePowerProvider(PowerHandler provider) { + provider.configure(50, 110, 5, 400); + } + + /* LOADING & SAVING */ + @Override + public void writeToNBT(NBTTagCompound nbttagcompound) { + super.writeToNBT(nbttagcompound); + + nbttagcompound.setInteger("PackageTime", packageTime); + nbttagcompound.setInteger("PackageTotalTime", totalTime); + + NBTTagCompound NBTresourceSlot = new NBTTagCompound(); + + resourceTank.writeToNBT(NBTresourceSlot); + nbttagcompound.setTag("ResourceTank", NBTresourceSlot); + + craftingInventory.writeToNBT(nbttagcompound); + accessibleInventory.writeToNBT(nbttagcompound); + + // Write pending product + if (pendingProduct != null) { + NBTTagCompound nbttagcompoundP = new NBTTagCompound(); + pendingProduct.writeToNBT(nbttagcompoundP); + nbttagcompound.setTag("PendingProduct", nbttagcompoundP); + } + // Write current product + if (currentProduct != null) { + NBTTagCompound nbttagcompoundC = new NBTTagCompound(); + currentProduct.writeToNBT(nbttagcompoundC); + nbttagcompound.setTag("CurrentProduct", nbttagcompoundC); + } + } + + @Override + public void readFromNBT(NBTTagCompound nbttagcompound) { + super.readFromNBT(nbttagcompound); + + packageTime = nbttagcompound.getInteger("PackageTime"); + totalTime = nbttagcompound.getInteger("PackageTotalTime"); + + resourceTank = new ForestryTank(Defaults.PROCESSOR_TANK_CAPACITY); + if (nbttagcompound.hasKey("ResourceTank")) + resourceTank.readFromNBT(nbttagcompound.getCompoundTag("ResourceTank")); + + if (nbttagcompound.hasKey("CraftItems")) + craftingInventory.readFromNBT(nbttagcompound); + else { + // FIXME: Legacy conversion for carpenters <= 2.2.2.2 + NBTTagList nbttaglist = nbttagcompound.getTagList("Items", 10); + + for (int j = 0; j < nbttaglist.tagCount(); ++j) { + NBTTagCompound nbttagcompound2 = nbttaglist.getCompoundTagAt(j); + int index = nbttagcompound2.getByte("Slot"); + if (index < 9) + craftingInventory.setInventorySlotContents(index, ItemStack.loadItemStackFromNBT(nbttagcompound2)); + } + + } + accessibleInventory.readFromNBT(nbttagcompound); + + // Load pending product + if (nbttagcompound.hasKey("PendingProduct")) { + NBTTagCompound nbttagcompoundP = nbttagcompound.getCompoundTag("PendingProduct"); + pendingProduct = ItemStack.loadItemStackFromNBT(nbttagcompoundP); + } + // Load current product + if (nbttagcompound.hasKey("CurrentProduct")) { + NBTTagCompound nbttagcompoundP = nbttagcompound.getCompoundTag("CurrentProduct"); + currentProduct = ItemStack.loadItemStackFromNBT(nbttagcompoundP); + } + + // Reset recipe according to contents + ContainerCarpenter container = new ContainerCarpenter(this); + setCurrentRecipe(RecipeManager.findMatchingRecipe(resourceTank.getFluid(), getBoxStack(), container.craftMatrix, worldObj)); + } + + public void setCurrentRecipe(MachineCarpenter.Recipe currentRecipe) { + this.currentRecipe = currentRecipe; + if(currentRecipe != null) + lastRecipe = currentRecipe; + } + + @Override + public void updateServerSide() { + + if (worldObj.getTotalWorldTime() % 20 * 10 != 0) + return; + + // Check if we have suitable items waiting in the item slot + if (accessibleInventory.getStackInSlot(SLOT_CAN_INPUT) != null) { + FluidContainerData container = LiquidHelper.getLiquidContainer(accessibleInventory.getStackInSlot(SLOT_CAN_INPUT)); + if (container != null && RecipeManager.isResourceLiquid(container.fluid)) { + + accessibleInventory.setInventorySlotContents(SLOT_CAN_INPUT, + StackUtils.replenishByContainer(this, accessibleInventory.getStackInSlot(SLOT_CAN_INPUT), container, resourceTank)); + if (accessibleInventory.getStackInSlot(SLOT_CAN_INPUT).stackSize <= 0) + accessibleInventory.setInventorySlotContents(SLOT_CAN_INPUT, null); + } + } + + if (worldObj.getTotalWorldTime() % 40 * 10 != 0) + return; + + if (currentRecipe == null) { + ContainerCarpenter container = new ContainerCarpenter(this); + setCurrentRecipe(MachineCarpenter.RecipeManager.findMatchingRecipe(resourceTank.getFluid(), getBoxStack(), container.craftMatrix, worldObj)); + } + + if (currentRecipe == null) + setErrorState(EnumErrorCode.NORECIPE); + else if (!validateResources()) + setErrorState(EnumErrorCode.NORESOURCE); + else + setErrorState(EnumErrorCode.OK); + + } + + @Override + public boolean workCycle() { + + if (packageTime > 0) { + packageTime--; + + // Check whether we have become invalid and need to abort production + if (currentRecipe == null || !currentProduct.isItemEqual(currentRecipe.getCraftingResult()) || !validateResources()) { + currentProduct = null; + packageTime = totalTime = 0; + return false; + } + + if (packageTime <= 0) { + + pendingProduct = currentProduct; + currentProduct = null; + totalTime = 0; + + // Remove resources + removeResources(currentRecipe); + + // Update product display + if (activeContainer != null) + activeContainer.updateProductDisplay(); + + return tryAddPending(); + } + return true; + } else if (pendingProduct != null) + return tryAddPending(); + else { + + if (currentRecipe != null) { + + if (!validateResources()) + return false; + + // Enough items available, start the process + packageTime = totalTime = currentRecipe.packagingTime; + currentProduct = currentRecipe.getCraftingResult(); + + // Update product display + if (activeContainer != null) + activeContainer.updateProductDisplay(); + + return true; + } + + return false; + } + } + + private boolean validateResources() { + // Check whether liquid is needed and if there is enough available + if (currentRecipe.liquid != null) + if (resourceTank.getFluidAmount() < currentRecipe.liquid.amount) + return false; + + // Check whether boxes are available + if (currentRecipe.box != null) + if (accessibleInventory.getStackInSlot(SLOT_BOX) == null) + return false; + + // Need at least one matched set + return StackUtils.containsSets(craftingInventory.getStacks(SLOT_CRAFTING_1, 9), accessibleInventory.getStacks(SLOT_INVENTORY_1, SLOT_INVENTORY_COUNT), null, true, false) > 0; + } + + private void removeResources(Recipe recipe) { + + // Remove resources + if (recipe.liquid != null) + resourceTank.drain(recipe.liquid.amount, true); + // Remove boxes + if (recipe.box != null) + accessibleInventory.decrStackSize(SLOT_BOX, 1); + + removeSets(1, craftingInventory.getStacks(SLOT_CRAFTING_1, 9)); + + } + + private void removeSets(int count, ItemStack[] set) { + + for (int i = 0; i < count; i++) { + ItemStack[] condensedSet = StackUtils.condenseStacks(set); + for (ItemStack req : condensedSet) { + for (int j = SLOT_INVENTORY_1; j < SLOT_INVENTORY_1 + SLOT_INVENTORY_COUNT; j++) { + ItemStack pol = accessibleInventory.getStackInSlot(j); + if (pol == null) + continue; + if (!StackUtils.isCraftingEquivalent(pol, req, true, false)) + continue; + + ItemStack removed = accessibleInventory.decrStackSize(j, req.stackSize); + req.stackSize -= removed.stackSize; + } + } + } + + } + + private boolean tryAddPending() { + if (accessibleInventory.getStackInSlot(SLOT_PRODUCT) == null) { + accessibleInventory.setInventorySlotContents(SLOT_PRODUCT, pendingProduct.copy()); + pendingProduct = null; + return true; + } + + if (accessibleInventory.getStackInSlot(SLOT_PRODUCT).isItemEqual(pendingProduct) + && accessibleInventory.getStackInSlot(SLOT_PRODUCT).stackSize <= accessibleInventory.getStackInSlot(SLOT_PRODUCT).getMaxStackSize() - pendingProduct.stackSize) { + accessibleInventory.getStackInSlot(SLOT_PRODUCT).stackSize += pendingProduct.stackSize; + pendingProduct = null; + return true; + } + + setErrorState(EnumErrorCode.NOSPACE); + return false; + } + + /* STATE INFORMATION */ + @Override + public boolean isWorking() { + return packageTime > 0 || pendingProduct != null || currentRecipe != null && validateResources(); + } + + @Override + public boolean hasWork() { + if (currentRecipe == null) + return false; + + // Stop working if the output slot cannot take more + if (accessibleInventory.getStackInSlot(SLOT_PRODUCT) != null + && accessibleInventory.getStackInSlot(SLOT_PRODUCT).getMaxStackSize() - accessibleInventory.getStackInSlot(SLOT_PRODUCT).stackSize < currentRecipe + .getCraftingResult().stackSize) + return false; + + return validateResources(); + } + + public int getCraftingProgressScaled(int i) { + if (totalTime == 0) + return 0; + + return (packageTime * i) / totalTime; + + } + + public int getResourceScaled(int i) { + return (resourceTank.getFluidAmount() * i) / Defaults.PROCESSOR_TANK_CAPACITY; + } + + @Override + public EnumTankLevel getPrimaryLevel() { + return Utils.rateTankLevel(getResourceScaled(100)); + } + + /* IINVENTORY */ + @Override + public int getSizeInventory() { + return accessibleInventory.getSizeInventory(); + } + + @Override + public ItemStack getStackInSlot(int i) { + return accessibleInventory.getStackInSlot(i); + } + + @Override + public void setInventorySlotContents(int i, ItemStack itemstack) { + accessibleInventory.setInventorySlotContents(i, itemstack); + } + + @Override + public ItemStack decrStackSize(int i, int j) { + return accessibleInventory.decrStackSize(i, j); + } + + @Override + public ItemStack getStackInSlotOnClosing(int slot) { + return accessibleInventory.getStackInSlotOnClosing(slot); + } + + @Override + public int getInventoryStackLimit() { + return accessibleInventory.getInventoryStackLimit(); + } + + @Override + public void openInventory() { + } + + @Override + public void closeInventory() { + } + + /** + * TODO: just a specialsource workaround + */ + @Override + public boolean isUseableByPlayer(EntityPlayer player) { + return super.isUseableByPlayer(player); + } + + /** + * TODO: just a specialsource workaround + */ + @Override + public boolean hasCustomInventoryName() { + return super.hasCustomInventoryName(); + } + + /** + * TODO: just a specialsource workaround + */ + @Override + public boolean isItemValidForSlot(int slotIndex, ItemStack itemstack) { + return super.isItemValidForSlot(slotIndex, itemstack); + } + + /** + * TODO: just a specialsource workaround + */ + @Override + public boolean canInsertItem(int i, ItemStack itemstack, int j) { + return super.canInsertItem(i, itemstack, j); + } + + /** + * TODO: just a specialsource workaround + */ + @Override + public boolean canExtractItem(int i, ItemStack itemstack, int j) { + return super.canExtractItem(i, itemstack, j); + } + + /** + * TODO: just a specialsource workaround + */ + @Override + public int[] getAccessibleSlotsFromSide(int side) { + return super.getAccessibleSlotsFromSide(side); + } + + /* SMP GUI */ + public void getGUINetworkData(int i, int j) { + + switch (i) { + case 0: + packageTime = j; + break; + case 1: + totalTime = j; + break; + } + } + + public void sendGUINetworkData(Container container, ICrafting iCrafting) { + iCrafting.sendProgressBarUpdate(container, 0, packageTime); + iCrafting.sendProgressBarUpdate(container, 1, totalTime); + } + + /* ISIDEDINVENTORY */ + @Override + public InventoryAdapter getInternalInventory() { + return accessibleInventory; + } + + /** + * @return Inaccessible crafting inventory for the craft grid. + */ + public InventoryAdapter getCraftingInventory() { + return craftingInventory; + } + + @Override + protected boolean canTakeStackFromSide(int slotIndex, ItemStack itemstack, int side) { + + if (!super.canTakeStackFromSide(slotIndex, itemstack, side)) + return false; + + if (slotIndex == SLOT_PRODUCT) + return true; + + return false; + } + + @Override + protected boolean canPutStackFromSide(int slotIndex, ItemStack itemstack, int side) { + + if (!super.canPutStackFromSide(slotIndex, itemstack, side)) + return false; + + if (slotIndex == SLOT_PRODUCT) + return false; + + if (slotIndex == SLOT_BOX) + return RecipeManager.isBox(itemstack); + + if (slotIndex == SLOT_CAN_INPUT) + return FluidContainerRegistry.isContainer(itemstack); + + if (slotIndex >= SLOT_INVENTORY_1 && slotIndex < SLOT_INVENTORY_1 + SLOT_INVENTORY_COUNT) { + if (lastRecipe == null) + return true; + return lastRecipe.isIngredient(itemstack); + } + + return false; + } + + // ILIQUIDCONTAINER IMPLEMENTATION + @Override + public int fill(ForgeDirection direction, FluidStack resource, boolean doFill) { + int used = resourceTank.fill(resource, doFill); + + if (doFill && used > 0) + // TODO: Slow down updates + sendNetworkUpdate(); + + return used; + } + + @Override + public ForestryTank[] getTanks() { + return new ForestryTank[] { resourceTank }; + } + + // ITRIGGERPROVIDER + @Override + public LinkedList getCustomTriggers() { + LinkedList res = new LinkedList(); + res.add(ForestryTrigger.hasWork); + return res; + } +} diff --git a/forestry_common/factory/forestry/factory/gadgets/MachineCentrifuge.java b/forestry_common/factory/forestry/factory/gadgets/MachineCentrifuge.java new file mode 100755 index 000000000..4c87a7e0f --- /dev/null +++ b/forestry_common/factory/forestry/factory/gadgets/MachineCentrifuge.java @@ -0,0 +1,475 @@ +/******************************************************************************* + * Copyright 2011-2014 by SirSengir + * + * This work is licensed under a Creative Commons Attribution-NonCommercial-NoDerivs 3.0 Unported License. + * + * To view a copy of this license, visit http://creativecommons.org/licenses/by-nc-nd/3.0/. + ******************************************************************************/ +package forestry.factory.gadgets; + +import java.util.ArrayList; +import java.util.HashMap; +import java.util.LinkedList; +import java.util.Map; +import java.util.Stack; + +import net.minecraft.entity.player.EntityPlayer; +import net.minecraft.inventory.Container; +import net.minecraft.inventory.ICrafting; +import net.minecraft.inventory.ISidedInventory; +import net.minecraft.item.ItemStack; +import net.minecraft.nbt.NBTTagCompound; +import net.minecraft.nbt.NBTTagList; + +import net.minecraftforge.common.util.ForgeDirection; + +import buildcraft.api.gates.ITrigger; +import buildcraft.api.inventory.ISpecialInventory; +import buildcraft.api.power.PowerHandler; + +import forestry.api.core.ForestryAPI; +import forestry.api.recipes.ICentrifugeManager; +import forestry.core.EnumErrorCode; +import forestry.core.config.Config; +import forestry.core.config.Defaults; +import forestry.core.gadgets.TileBase; +import forestry.core.gadgets.TilePowered; +import forestry.core.network.GuiId; +import forestry.core.triggers.ForestryTrigger; +import forestry.core.utils.InventoryAdapter; +import forestry.core.utils.StackUtils; + +public class MachineCentrifuge extends TilePowered implements ISidedInventory, ISpecialInventory { + + /* CONSTANTS */ + public static final int SLOT_RESOURCE = 0; + public static final int SLOT_PRODUCT_1 = 1; + + /* RECIPE MANAGMENT */ + public static class Recipe { + public final int timePerItem; + public final ItemStack resource; + public final HashMap products; + + public Recipe(int timePerItem, ItemStack resource, HashMap products) { + this.timePerItem = timePerItem; + this.resource = resource; + this.products = products; + } + + public boolean matches(ItemStack res) { + if (res == null && resource == null) + return true; + else if (res == null && resource != null) + return false; + else if (res != null && resource == null) + return false; + else + return resource.isItemEqual(res); + } + } + + public static class RecipeManager implements ICentrifugeManager { + public static ArrayList recipes = new ArrayList(); + + @Override + public void addRecipe(int timePerItem, ItemStack resource, HashMap products) { + recipes.add(new Recipe(timePerItem, resource, products)); + } + + @Override + public void addRecipe(int timePerItem, ItemStack resource, ItemStack[] produce, int[] chances) { + HashMap products = new HashMap(); + + int i = 0; + for (ItemStack prod : produce) { + products.put(prod, chances[i]); + i++; + } + + addRecipe(timePerItem, resource, products); + } + + @Override + public void addRecipe(int timePerItem, ItemStack resource, ItemStack primary, ItemStack secondary, int chance) { + HashMap products = new HashMap(); + products.put(primary, 100); + if (secondary != null) + products.put(secondary, chance); + addRecipe(timePerItem, resource, products); + } + + @Override + public void addRecipe(int timePerItem, ItemStack resource, ItemStack primary) { + HashMap products = new HashMap(); + products.put(primary, 100); + addRecipe(timePerItem, resource, products); + } + + public static Recipe findMatchingRecipe(ItemStack item) { + for (int i = 0; i < recipes.size(); i++) { + Recipe recipe = recipes.get(i); + if (recipe.matches(item)) + return recipe; + } + return null; + } + + @Override + public Map getRecipes() { + HashMap recipeList = new HashMap(); + + for (Recipe recipe : recipes) + recipeList.put(new Object[] { recipe.resource }, recipe.products.keySet().toArray(StackUtils.EMPTY_STACK_ARRAY)); + + return recipeList; + } + } + + /* MEMBER */ + private final InventoryAdapter inventory = new InventoryAdapter(10, "Items"); + public MachineCentrifuge.Recipe currentRecipe; + + private final Stack pendingProducts = new Stack(); + private int productionTime; + private int timePerItem; + + public MachineCentrifuge() { + setHints(Config.hints.get("centrifuge")); + } + + @Override + public String getInventoryName() { + return "factory.2"; + } + + @Override + public void openGui(EntityPlayer player, TileBase tile) { + player.openGui(ForestryAPI.instance, GuiId.CentrifugeGUI.ordinal(), player.worldObj, xCoord, yCoord, zCoord); + } + + @Override + protected void configurePowerProvider(PowerHandler provider) { + provider.configure(40, 80, 4, Defaults.MACHINE_MAX_ENERGY); + } + + /* LOADING & SAVING */ + @Override + public void writeToNBT(NBTTagCompound nbttagcompound) { + super.writeToNBT(nbttagcompound); + + nbttagcompound.setInteger("ProductionTime", productionTime); + nbttagcompound.setInteger("TimePerItem", timePerItem); + + inventory.writeToNBT(nbttagcompound); + + NBTTagList nbttaglist = new NBTTagList(); + ItemStack[] offspring = pendingProducts.toArray(new ItemStack[pendingProducts.size()]); + for (int i = 0; i < offspring.length; i++) + if (offspring[i] != null) { + NBTTagCompound nbttagcompound1 = new NBTTagCompound(); + nbttagcompound1.setByte("Slot", (byte) i); + offspring[i].writeToNBT(nbttagcompound1); + nbttaglist.appendTag(nbttagcompound1); + } + nbttagcompound.setTag("PendingProducts", nbttaglist); + } + + @Override + public void readFromNBT(NBTTagCompound nbttagcompound) { + super.readFromNBT(nbttagcompound); + + productionTime = nbttagcompound.getInteger("ProductionTime"); + timePerItem = nbttagcompound.getInteger("TimePerItem"); + + inventory.readFromNBT(nbttagcompound); + + NBTTagList nbttaglist = nbttagcompound.getTagList("PendingProducts", 10); + for (int i = 0; i < nbttaglist.tagCount(); i++) { + NBTTagCompound nbttagcompound1 = nbttaglist.getCompoundTagAt(i); + pendingProducts.add(ItemStack.loadItemStackFromNBT(nbttagcompound1)); + } + + checkRecipe(); + } + + @Override + public void updateServerSide() { + + if (worldObj.getTotalWorldTime() % 20 * 10 != 0) + return; + + // Check and reset recipe if necessary + checkRecipe(); + if (getErrorState() == EnumErrorCode.NORECIPE && currentRecipe != null) + setErrorState(EnumErrorCode.OK); + } + + @Override + public boolean workCycle() { + + checkRecipe(); + + // If we add pending products, we skip to the next work cycle. + if (tryAddPending()) + return false; + + if (!pendingProducts.isEmpty()) + return false; + + // Continue work if nothing needs to be added + if (productionTime <= 0) + return false; + + if (currentRecipe == null) + return false; + + productionTime--; + // Still not done, return + if (productionTime > 0) { + setErrorState(EnumErrorCode.OK); + return true; + } + + // We are done, add products to queue + for (Map.Entry entry : currentRecipe.products.entrySet()) + if (entry.getValue() >= 100) + pendingProducts.push(entry.getKey().copy()); + else if (worldObj.rand.nextInt(100) < entry.getValue()) + pendingProducts.push(entry.getKey().copy()); + + inventory.decrStackSize(SLOT_RESOURCE, 1); + checkRecipe(); + resetRecipe(); + + tryAddPending(); + return true; + } + + public void checkRecipe() { + Recipe sameRec = RecipeManager.findMatchingRecipe(inventory.getStackInSlot(SLOT_RESOURCE)); + + if (sameRec == null) + setErrorState(EnumErrorCode.NORECIPE); + + if (currentRecipe != sameRec) { + currentRecipe = sameRec; + resetRecipe(); + } + } + + private void resetRecipe() { + if (currentRecipe == null) { + productionTime = 0; + timePerItem = 0; + return; + } + + productionTime = currentRecipe.timePerItem; + timePerItem = currentRecipe.timePerItem; + } + + private boolean tryAddPending() { + if (pendingProducts.isEmpty()) + return false; + + ItemStack next = pendingProducts.peek(); + if (addProduct(next, true)) { + pendingProducts.pop(); + return true; + } + + setErrorState(EnumErrorCode.NOSPACE); + return false; + } + + private boolean addProduct(ItemStack product, boolean all) { + return inventory.tryAddStack(product, 1, getSizeInventory() - 1, all); + } + + @Override + public boolean isWorking() { + return currentRecipe != null; + } + + @Override + public boolean hasResourcesMin(float percentage) { + if (inventory.getStackInSlot(SLOT_RESOURCE) == null) + return false; + + return ((float) inventory.getStackInSlot(SLOT_RESOURCE).stackSize / (float) inventory.getStackInSlot(SLOT_RESOURCE).getMaxStackSize()) > percentage; + } + + @Override + public boolean hasWork() { + return currentRecipe != null; + } + + public int getProgressScaled(int i) { + if (timePerItem == 0) + return i; + + return (productionTime * i) / timePerItem; + } + + /* GUI */ + public void getGUINetworkData(int i, int j) { + switch (i) { + case 0: + productionTime = j; + break; + case 1: + timePerItem = j; + break; + } + } + + public void sendGUINetworkData(Container container, ICrafting iCrafting) { + iCrafting.sendProgressBarUpdate(container, 0, productionTime); + iCrafting.sendProgressBarUpdate(container, 1, timePerItem); + } + + /* IINVENTORY */ + @Override + public InventoryAdapter getInternalInventory() { + return inventory; + } + + @Override + protected boolean canTakeStackFromSide(int slotIndex, ItemStack itemstack, int side) { + + if(!super.canTakeStackFromSide(slotIndex, itemstack, side)) + return false; + + if(slotIndex >= SLOT_PRODUCT_1 && slotIndex < SLOT_PRODUCT_1 + 9) + return true; + + return false; + } + + @Override + protected boolean canPutStackFromSide(int slotIndex, ItemStack itemstack, int side) { + + if(!super.canPutStackFromSide(slotIndex, itemstack, side)) + return false; + + if (slotIndex == SLOT_RESOURCE && RecipeManager.findMatchingRecipe(itemstack) != null) + return true; + + return false; + } + + @Override public int getSizeInventory() { return inventory.getSizeInventory(); } + @Override public ItemStack getStackInSlot(int i) { return inventory.getStackInSlot(i); } + @Override public ItemStack decrStackSize(int i, int j) { return inventory.decrStackSize(i, j); } + @Override public void setInventorySlotContents(int i, ItemStack itemstack) { inventory.setInventorySlotContents(i, itemstack); } + @Override public ItemStack getStackInSlotOnClosing(int slot) { return inventory.getStackInSlotOnClosing(slot); } + @Override public int getInventoryStackLimit() { return inventory.getInventoryStackLimit(); } + @Override public void openInventory() {} + @Override public void closeInventory() {} + + /** + * TODO: just a specialsource workaround + */ + @Override + public boolean isUseableByPlayer(EntityPlayer player) { + return super.isUseableByPlayer(player); + } + + /** + * TODO: just a specialsource workaround + */ + @Override + public boolean hasCustomInventoryName() { + return super.hasCustomInventoryName(); + } + + /** + * TODO: just a specialsource workaround + */ + @Override + public boolean isItemValidForSlot(int slotIndex, ItemStack itemstack) { + return super.isItemValidForSlot(slotIndex, itemstack); + } + + /** + * TODO: just a specialsource workaround + */ + @Override + public boolean canInsertItem(int i, ItemStack itemstack, int j) { + return super.canInsertItem(i, itemstack, j); + } + + /** + * TODO: just a specialsource workaround + */ + @Override + public boolean canExtractItem(int i, ItemStack itemstack, int j) { + return super.canExtractItem(i, itemstack, j); + } + + /** + * TODO: just a specialsource workaround + */ + @Override + public int[] getAccessibleSlotsFromSide(int side) { + return super.getAccessibleSlotsFromSide(side); + } + + /* ISPECIALINVENTORY */ + @Override + public ItemStack[] extractItem(boolean doRemove, ForgeDirection from, int maxItemCount) { + + ItemStack product = null; + + for (int i = SLOT_PRODUCT_1; i < inventory.getSizeInventory(); i++) { + if (inventory.getStackInSlot(i) == null) + continue; + + product = new ItemStack(inventory.getStackInSlot(i).getItem(), 1, inventory.getStackInSlot(i).getItemDamage()); + if (doRemove) + decrStackSize(i, 1); + + break; + } + + if (product != null) + return new ItemStack[] { product }; + else + return new ItemStack[0]; + } + + @Override + public int addItem(ItemStack stack, boolean doAdd, ForgeDirection from) { + if (inventory.getStackInSlot(SLOT_RESOURCE) == null) { + if (doAdd) + inventory.setInventorySlotContents(SLOT_RESOURCE, stack.copy()); + return stack.stackSize; + } + + if (!inventory.getStackInSlot(SLOT_RESOURCE).isItemEqual(stack)) + return 0; + + int space = inventory.getStackInSlot(SLOT_RESOURCE).getMaxStackSize() - inventory.getStackInSlot(SLOT_RESOURCE).stackSize; + if (space <= 0) + return 0; + + if (doAdd) + if (stack.stackSize <= space) + inventory.getStackInSlot(SLOT_RESOURCE).stackSize += stack.stackSize; + else + inventory.getStackInSlot(SLOT_RESOURCE).stackSize += space; + + return Math.min(stack.stackSize, space); + } + + /* ITRIGGERPROVIDER */ + @Override + public LinkedList getCustomTriggers() { + LinkedList res = new LinkedList(); + res.add(ForestryTrigger.lowResource25); + res.add(ForestryTrigger.lowResource10); + res.add(ForestryTrigger.hasWork); + return res; + } +} diff --git a/forestry_common/factory/forestry/factory/gadgets/MachineFabricator.java b/forestry_common/factory/forestry/factory/gadgets/MachineFabricator.java new file mode 100755 index 000000000..719ee89d7 --- /dev/null +++ b/forestry_common/factory/forestry/factory/gadgets/MachineFabricator.java @@ -0,0 +1,606 @@ +/******************************************************************************* + * Copyright 2011-2014 by SirSengir + * + * This work is licensed under a Creative Commons Attribution-NonCommercial-NoDerivs 3.0 Unported License. + * + * To view a copy of this license, visit http://creativecommons.org/licenses/by-nc-nd/3.0/. + ******************************************************************************/ +package forestry.factory.gadgets; + +import java.util.ArrayList; +import java.util.HashMap; +import java.util.Map; + +import net.minecraft.entity.player.EntityPlayer; +import net.minecraft.inventory.Container; +import net.minecraft.inventory.ICrafting; +import net.minecraft.item.Item; +import net.minecraft.item.ItemStack; +import net.minecraft.item.crafting.IRecipe; +import net.minecraft.nbt.NBTTagCompound; + +import net.minecraftforge.common.util.ForgeDirection; +import net.minecraftforge.fluids.FluidStack; + +import buildcraft.api.inventory.ISpecialInventory; +import buildcraft.api.power.PowerHandler; + +import forestry.api.core.ForestryAPI; +import forestry.api.recipes.IFabricatorManager; +import forestry.core.config.Defaults; +import forestry.core.gadgets.TileBase; +import forestry.core.gadgets.TilePowered; +import forestry.core.interfaces.ICrafter; +import forestry.core.interfaces.ICraftingPlan; +import forestry.core.interfaces.ILiquidTankContainer; +import forestry.core.network.GuiId; +import forestry.core.utils.ForestryTank; +import forestry.core.utils.InventoryAdapter; +import forestry.core.utils.ShapedRecipeCustom; +import forestry.core.utils.StackUtils; + +public class MachineFabricator extends TilePowered implements ICrafter, ISpecialInventory, ILiquidTankContainer { + + /* RECIPE MANAGMENT */ + public static class Recipe { + ItemStack plan; + + FluidStack molten; + ShapedRecipeCustom internal; + + public Recipe(ItemStack plan, FluidStack molten, ShapedRecipeCustom internal) { + this.plan = plan; + this.molten = molten; + this.internal = internal; + } + + public boolean matches(ItemStack plan) { + if (this.plan == null) + return true; + + if (plan == null && this.plan == null) + return true; + else if (plan == null && this.plan != null) + return false; + + if (this.plan.getItemDamage() == Defaults.WILDCARD) + return plan.getItem() == this.plan.getItem(); + else + return plan.isItemEqual(this.plan); + } + + public boolean matches(ItemStack plan, ItemStack[][] resources) { + if (!this.matches(plan)) + return false; + + return internal.matches(resources); + } + + public boolean hasLiquid(FluidStack resource) { + if(resource == null) + return molten == null; + + if (!resource.isFluidEqual(molten)) + return false; + + return molten.amount <= resource.amount; + } + + public ItemStack getPlan() { + return plan; + } + + public FluidStack getLiquid() { + return molten; + } + + public IRecipe asIRecipe() { + return internal; + } + + } + + public static class Smelting { + ItemStack resource; + FluidStack product; + int meltingPoint; + + public Smelting(ItemStack resource, FluidStack molten, int meltingPoint) { + if(resource == null) + throw new IllegalArgumentException("Resource cannot be null"); + if(molten == null) + throw new IllegalArgumentException("Molten cannot be null"); + + this.resource = resource; + this.product = molten; + this.meltingPoint = meltingPoint; + } + + public boolean matches(ItemStack resource) { + return this.resource.isItemEqual(resource); + } + + public boolean matches(FluidStack product) { + return this.product.isFluidEqual(product); + } + + public ItemStack getResource() { + return resource; + } + + public FluidStack getProduct() { + return product; + } + + public int getMeltingPoint() { + return meltingPoint; + } + } + + public static class RecipeManager implements IFabricatorManager { + public static ArrayList recipes = new ArrayList(); + public static ArrayList smeltings = new ArrayList(); + + @Override + public void addRecipe(ItemStack plan, FluidStack molten, ItemStack result, Object[] pattern) { + recipes.add(new Recipe(plan, molten, ShapedRecipeCustom.createShapedRecipe(result, pattern))); + } + + @Override + public void addSmelting(ItemStack resource, FluidStack molten, int meltingPoint) { + smeltings.add(new Smelting(resource, molten, meltingPoint)); + } + + public static Recipe findMatchingRecipe(ItemStack plan) { + for (Recipe recipe : recipes) + if (recipe.matches(plan)) + return recipe; + + return null; + } + + public static Recipe findMatchingRecipe(ItemStack plan, FluidStack liquid, ItemStack[] resources) { + ItemStack[][] gridResources = new ItemStack[3][3]; + for (int i = 0; i < 3; i++) + for (int j = 0; j < 3; j++) + gridResources[j][i] = resources[i * 3 + j]; + + for (Recipe recipe : recipes) + if (recipe.matches(plan, gridResources)) + if (recipe.hasLiquid(liquid)) + return recipe; + + return null; + } + + public static boolean isResourceLiquid(FluidStack liquid) { + for (Recipe recipe : recipes) + if (recipe.hasLiquid(liquid)) + return true; + + return false; + } + + public static Smelting findMatchingSmelting(ItemStack resource) { + if (resource == null) + return null; + + for (Smelting smelting : smeltings) + if (smelting.matches(resource)) + return smelting; + + return null; + } + + public static Smelting findMatchingSmelting(FluidStack product) { + if (product == null) + return null; + + for (Smelting smelting : smeltings) + if (smelting.matches(product)) + return smelting; + + return null; + } + + @Override + public Map getRecipes() { + HashMap recipeList = new HashMap(); + + for (Recipe recipe : recipes) + recipeList.put(recipe.internal.getIngredients(), new Object[] { recipe.internal.getRecipeOutput() }); + + return recipeList; + } + + } + + /* CONSTANTS */ + private static final int MAX_HEAT = 5000; + + public static final short SLOT_METAL = 0; + public static final short SLOT_PLAN = 1; + public static final short SLOT_RESULT = 2; + public static final short SLOT_CRAFTING_1 = 3; + public static final short SLOT_INVENTORY_1 = 12; + public static final short SLOT_INVENTORY_COUNT = 18; + + /* MEMBER */ + private final InventoryAdapter inventory = new InventoryAdapter(30, "Items"); + private ForestryTank moltenTank = new ForestryTank(2 * Defaults.BUCKET_VOLUME); + private int heat = 0; + private int guiMeltingPoint = 0; + + private FluidStack pendingSmelt; + + public MachineFabricator() { + } + + @Override + protected void configurePowerProvider(PowerHandler provider) { + provider.configure(50, 110, 5, 330); + } + + @Override + public String getInventoryName() { + return "factory2.0"; + } + + @Override + public void openGui(EntityPlayer player, TileBase tile) { + player.openGui(ForestryAPI.instance, GuiId.FabricatorGUI.ordinal(), player.worldObj, xCoord, yCoord, zCoord); + } + + /* SAVING & LOADING */ + @Override + public void writeToNBT(NBTTagCompound nbttagcompound) { + super.writeToNBT(nbttagcompound); + + nbttagcompound.setInteger("Heat", heat); + + // Tank + NBTTagCompound nbtMoltenTank = new NBTTagCompound(); + moltenTank.writeToNBT(nbtMoltenTank); + nbttagcompound.setTag("MoltenTank", nbtMoltenTank); + + // Pending Smelt + if (pendingSmelt != null) { + NBTTagCompound smelt = new NBTTagCompound(); + pendingSmelt.writeToNBT(smelt); + nbttagcompound.setTag("PendingSmelt", smelt); + } + + // / Inventory + inventory.writeToNBT(nbttagcompound); + } + + @Override + public void readFromNBT(NBTTagCompound nbttagcompound) { + super.readFromNBT(nbttagcompound); + + heat = nbttagcompound.getInteger("Heat"); + + // Tank + moltenTank = new ForestryTank(Defaults.BUCKET_VOLUME * 2); + if (nbttagcompound.hasKey("MoltenTank")) + moltenTank.readFromNBT(nbttagcompound.getCompoundTag("MoltenTank")); + + // Pending Smelt + if (nbttagcompound.hasKey("PendingSmelt")) { + NBTTagCompound smelt = nbttagcompound.getCompoundTag("PendingSmelt"); + pendingSmelt = FluidStack.loadFluidStackFromNBT(smelt); + } + + // / Inventory + inventory.readFromNBT(nbttagcompound); + + } + + /* UPDATING */ + @Override + public void updateServerSide() { + + // Remove smelt if we have gone below metling point + if (moltenTank.getFluidAmount() > 0) { + Smelting smelt = RecipeManager.findMatchingSmelting(moltenTank.getFluid()); + if (smelt != null && heat < smelt.meltingPoint) + moltenTank.drain(5, true); + } + + // Add pending smelt + if (pendingSmelt != null) { + + int filled = moltenTank.fill(pendingSmelt, true); + pendingSmelt.amount -= filled; + + if (pendingSmelt.amount <= 0) + pendingSmelt = null; + // Smelt if necessary and possible + } else if (moltenTank.getFluidAmount() < moltenTank.getCapacity()) + if (inventory.getStackInSlot(SLOT_METAL) != null) { + + Smelting smelt = RecipeManager.findMatchingSmelting(inventory.getStackInSlot(SLOT_METAL)); + if (smelt != null && smelt.meltingPoint <= heat) { + + this.decrStackSize(SLOT_METAL, 1); + pendingSmelt = smelt.product.copy(); + } + } + + this.dissipateHeat(); + } + + @Override + public boolean workCycle() { + return addHeat(25); + } + + private boolean addHeat(int addition) { + if (this.heat >= MAX_HEAT) + return false; + + this.heat += addition; + if (this.heat > MAX_HEAT) + this.heat = MAX_HEAT; + + return true; + } + + private void dissipateHeat() { + if (heat > 2500) + this.heat -= 2; + else if (heat > 0) + this.heat--; + } + + public Object[] getPlan() { + if (inventory.getStackInSlot(SLOT_PLAN) == null) + return null; + + Recipe myRecipe = RecipeManager.findMatchingRecipe(inventory.getStackInSlot(SLOT_PLAN)); + if (myRecipe == null) + return null; + + return myRecipe.internal.getIngredients(); + } + + /* ICRAFTER */ + @Override + public boolean canTakeStack(int slotIndex) { + return true; + } + + @Override + public ItemStack getResult() { + Recipe myRecipe = RecipeManager.findMatchingRecipe(inventory.getStackInSlot(SLOT_PLAN), moltenTank.getFluid(), + inventory.getStacks(SLOT_CRAFTING_1, 9)); + + if (myRecipe == null) + return null; + + return myRecipe.internal.getRecipeOutput().copy(); + } + + @Override + public ItemStack takenFromSlot(int slotIndex, boolean consumeRecipe, EntityPlayer player) { + if(slotIndex != SLOT_RESULT) + return null; + + Recipe myRecipe = RecipeManager.findMatchingRecipe(inventory.getStackInSlot(SLOT_PLAN), moltenTank.getFluid(), + inventory.getStacks(SLOT_CRAFTING_1, 9)); + if (myRecipe == null) + return null; + + FluidStack liquid = myRecipe.molten; + + // Remove resources + if (removeFromInventory(1, inventory.getStacks(SLOT_CRAFTING_1, 9), false)) { + removeFromInventory(1, inventory.getStacks(SLOT_CRAFTING_1, 9), true); + moltenTank.drain(liquid.amount, true); + } else if (consumeRecipe) { + removeFromCraftMatrix(myRecipe); + moltenTank.drain(liquid.amount, true); + } else + return null; + + ItemStack result = myRecipe.internal.getRecipeOutput().copy(); + // Damage plan + if (inventory.getStackInSlot(SLOT_PLAN) != null) { + Item planItem = inventory.getStackInSlot(SLOT_PLAN).getItem(); + if (planItem instanceof ICraftingPlan) + inventory.setInventorySlotContents(SLOT_PLAN, ((ICraftingPlan) planItem).planUsed(inventory.getStackInSlot(SLOT_PLAN), result)); + } + + // Return result + return result; + } + + private void removeFromCraftMatrix(Recipe recipe) { + + for (int i = 0; i < 9; i++) { + if (inventory.getStackInSlot(SLOT_CRAFTING_1 + i) == null) + continue; + inventory.decrStackSize(SLOT_CRAFTING_1 + i, 1); + } + + } + + private boolean removeFromInventory(int count, ItemStack[] set, boolean doRemove) { + + boolean hasRemoved = true; + for (int i = 0; i < count; i++) { + ItemStack[] condensedSet = StackUtils.condenseStacks(set, 1, true); + for (ItemStack req : condensedSet) + for (int j = SLOT_INVENTORY_1; j < SLOT_INVENTORY_1 + SLOT_INVENTORY_COUNT; j++) { + ItemStack pol = inventory.getStackInSlot(j); + if (pol == null) + continue; + if (!StackUtils.isCraftingEquivalent(pol, req, true, false)) + continue; + + int available = pol.stackSize; + if (doRemove) { + inventory.decrStackSize(j, req.stackSize); + } + req.stackSize -= available; + + if(req.stackSize <= 0) + break; + } + + boolean hasLeft = false; + for (ItemStack req : condensedSet) + if (req != null && req.stackSize > 0) + hasLeft = true; + if (hasLeft) + hasRemoved = false; + + } + + return hasRemoved; + } + + @Override + public boolean isWorking() { + return this.heat <= MAX_HEAT; + } + + public int getHeatScaled(int i) { + return (heat * i) / MAX_HEAT; + } + + public int getMeltingPoint() { + if (moltenTank.getFluidAmount() > 0) { + Smelting smelt = RecipeManager.findMatchingSmelting(moltenTank.getFluid()); + if (smelt != null) + return smelt.meltingPoint; + } else if (this.getStackInSlot(SLOT_METAL) != null) { + Smelting smelt = RecipeManager.findMatchingSmelting(this.getStackInSlot(SLOT_METAL)); + if (smelt != null) + return smelt.meltingPoint; + } + + return 0; + } + + public int getMeltingPointScaled(int i) { + // / For SMP clients + if (guiMeltingPoint > 0) + return (guiMeltingPoint * i) / MAX_HEAT; + + int meltingPoint = getMeltingPoint(); + + if (meltingPoint <= 0) + return 0; + else + return (meltingPoint * i) / MAX_HEAT; + } + + /* SMP */ + public void getGUINetworkData(int i, int j) { + switch (i) { + case 0: + heat = j; + break; + case 1: + guiMeltingPoint = j; + break; + } + } + + public void sendGUINetworkData(Container container, ICrafting iCrafting) { + iCrafting.sendProgressBarUpdate(container, 0, heat); + iCrafting.sendProgressBarUpdate(container, 1, getMeltingPoint()); + } + + // / ISPECIALINVENTORY + @Override + public int addItem(ItemStack stack, boolean doAdd, ForgeDirection from) { + if (from == ForgeDirection.UP && RecipeManager.findMatchingSmelting(stack) != null) + return inventory.addStack(stack, SLOT_METAL, 1, false, doAdd); + return inventory.addStack(stack, SLOT_INVENTORY_1, SLOT_INVENTORY_COUNT, false, doAdd); + } + + @Override + public ItemStack[] extractItem(boolean doRemove, ForgeDirection from, int maxItemCount) { + ItemStack taken; + if (doRemove) + taken = this.takenFromSlot(SLOT_RESULT, false, null); + else + taken = this.getResult(); + + if (taken != null) + return new ItemStack[] { taken }; + else + return new ItemStack[0]; + } + + // / IINVENTORY + @Override + public int getSizeInventory() { + return inventory.getSizeInventory(); + } + + @Override + public ItemStack getStackInSlot(int i) { + return inventory.getStackInSlot(i); + } + + @Override + public ItemStack decrStackSize(int i, int j) { + return inventory.decrStackSize(i, j); + } + + @Override + public void setInventorySlotContents(int i, ItemStack itemstack) { + inventory.setInventorySlotContents(i, itemstack); + } + + @Override + public int getInventoryStackLimit() { + return inventory.getInventoryStackLimit(); + } + + @Override + public ItemStack getStackInSlotOnClosing(int slot) { + return inventory.getStackInSlotOnClosing(slot); + } + + @Override + public void openInventory() { + } + + @Override + public void closeInventory() { + } + + /** + * TODO: just a specialsource workaround + */ + @Override + public boolean isUseableByPlayer(EntityPlayer player) { + return super.isUseableByPlayer(player); + } + + /** + * TODO: just a specialsource workaround + */ + @Override + public boolean hasCustomInventoryName() { + return super.hasCustomInventoryName(); + } + + /** + * TODO: just a specialsource workaround + */ + @Override + public boolean isItemValidForSlot(int slotIndex, ItemStack itemstack) { + return super.isItemValidForSlot(slotIndex, itemstack); + } + + /* ILIQUIDCONTAINER */ + @Override + public ForestryTank[] getTanks() { + return new ForestryTank[] { moltenTank }; + } +} diff --git a/forestry_common/factory/forestry/factory/gadgets/MachineFermenter.java b/forestry_common/factory/forestry/factory/gadgets/MachineFermenter.java new file mode 100755 index 000000000..cdb93fa29 --- /dev/null +++ b/forestry_common/factory/forestry/factory/gadgets/MachineFermenter.java @@ -0,0 +1,700 @@ +/******************************************************************************* + * Copyright 2011-2014 by SirSengir + * + * This work is licensed under a Creative Commons Attribution-NonCommercial-NoDerivs 3.0 Unported License. + * + * To view a copy of this license, visit http://creativecommons.org/licenses/by-nc-nd/3.0/. + ******************************************************************************/ +package forestry.factory.gadgets; + +import java.util.ArrayList; +import java.util.HashMap; +import java.util.LinkedList; +import java.util.Map; + +import net.minecraft.entity.player.EntityPlayer; +import net.minecraft.inventory.Container; +import net.minecraft.inventory.ICrafting; +import net.minecraft.inventory.ISidedInventory; +import net.minecraft.item.ItemStack; +import net.minecraft.nbt.NBTTagCompound; + +import net.minecraftforge.common.util.ForgeDirection; +import net.minecraftforge.fluids.FluidContainerRegistry.FluidContainerData; +import net.minecraftforge.fluids.FluidStack; + +import buildcraft.api.gates.ITrigger; +import buildcraft.api.power.PowerHandler; + +import forestry.api.core.ForestryAPI; +import forestry.api.fuels.FuelManager; +import forestry.api.recipes.IFermenterManager; +import forestry.api.recipes.IVariableFermentable; +import forestry.core.EnumErrorCode; +import forestry.core.config.Config; +import forestry.core.config.Defaults; +import forestry.core.gadgets.TileBase; +import forestry.core.gadgets.TilePowered; +import forestry.core.interfaces.ILiquidTankContainer; +import forestry.core.network.EntityNetData; +import forestry.core.network.GuiId; +import forestry.core.triggers.ForestryTrigger; +import forestry.core.utils.EnumTankLevel; +import forestry.core.utils.ForestryTank; +import forestry.core.utils.InventoryAdapter; +import forestry.core.utils.LiquidHelper; +import forestry.core.utils.StackUtils; +import forestry.core.utils.Utils; + +public class MachineFermenter extends TilePowered implements ISidedInventory, ILiquidTankContainer { + + // / CONSTANTS + public static final short SLOT_RESOURCE = 0; + public static final short SLOT_FUEL = 1; + public static final short SLOT_CAN_OUTPUT = 2; + public static final short SLOT_CAN_INPUT = 3; + public static final short SLOT_INPUT = 4; + + // / RECIPE MANAGMENT + public static class Recipe { + + public final ItemStack resource; + public final int fermentationValue; + public final float modifier; + public final FluidStack output; + public final FluidStack liquid; + + public Recipe(ItemStack resource, int fermentationValue, float modifier, FluidStack output, FluidStack liquid) { + this.resource = resource; + this.fermentationValue = fermentationValue; + this.modifier = modifier; + this.output = output; + this.liquid = liquid; + + if (resource == null) + throw new NullPointerException("Fermenter Resource cannot be null!"); + + if (output == null) + throw new NullPointerException("Fermenter Output cannot be null!"); + + if (liquid == null) + throw new NullPointerException("Fermenter Liquid cannot be null!"); + } + + public boolean matches(ItemStack res, FluidStack liqu) { + // No recipe without resource! + if (res == null) + return false; + + if (resource.getItem() != res.getItem()) + return false; + if (resource.getItemDamage() != Defaults.WILDCARD && resource.getItemDamage() != res.getItemDamage()) + return false; + + // No liquid required + if (liquid == null) + return true; + + // Liquid required but none given + if (liquid != null && liqu == null) + return false; + + // Wrong liquid + if (!liquid.isFluidEqual(liqu)) + return false; + + // Enough liquid + if (liquid.amount <= liqu.amount) + return true; + + return false; + } + } + + public static class RecipeManager implements IFermenterManager { + + public static ArrayList recipes = new ArrayList(); + + @Override + public void addRecipe(ItemStack resource, int fermentationValue, float modifier, FluidStack output, FluidStack liquid) { + recipes.add(new Recipe(resource, fermentationValue, modifier, output, liquid)); + } + + @Override + public void addRecipe(ItemStack resource, int fermentationValue, float modifier, FluidStack output) { + addRecipe(resource, fermentationValue, modifier, output, LiquidHelper.getLiquid(Defaults.LIQUID_WATER, 1000)); + } + + public static Recipe findMatchingRecipe(ItemStack res, FluidStack liqu) { + for (int i = 0; i < recipes.size(); i++) { + Recipe recipe = recipes.get(i); + if (recipe.matches(res, liqu)) + return recipe; + } + return null; + } + + public static boolean isResource(ItemStack resource) { + for (int i = 0; i < recipes.size(); i++) { + Recipe recipe = recipes.get(i); + if (recipe.resource.getItemDamage() == Defaults.WILDCARD + && recipe.resource.getItem() == resource.getItem()) { + return true; + } else if (recipe.resource.isItemEqual(resource)) { + return true; + } + } + return false; + } + + public static boolean isLiquidResource(FluidStack liquid) { + for (int i = 0; i < recipes.size(); i++) { + Recipe recipe = recipes.get(i); + if (recipe.liquid.isFluidEqual(liquid)) + return true; + } + return false; + } + + public static boolean isLiquidProduct(FluidStack liquid) { + for (int i = 0; i < recipes.size(); i++) { + Recipe recipe = recipes.get(i); + if (recipe.output.isFluidEqual(liquid)) + return true; + } + return false; + } + + @Override + public Map getRecipes() { + HashMap recipeList = new HashMap(); + + for (Recipe recipe : recipes) { + recipeList.put(new Object[] { recipe.resource, recipe.liquid }, new Object[] { recipe.output }); + } + + return recipeList; + } + } + @EntityNetData + public ForestryTank resourceTank = new ForestryTank(Defaults.PROCESSOR_TANK_CAPACITY); + @EntityNetData + public ForestryTank productTank = new ForestryTank(Defaults.PROCESSOR_TANK_CAPACITY); + private final InventoryAdapter inventory = new InventoryAdapter(5, "Items"); + private Recipe currentRecipe; + private float currentResourceModifier; + public int fermentationTime = 0; + public int fermentationTotalTime = 0; + public int fuelBurnTime = 0; + public int fuelTotalTime = 0; + public int fuelCurrentFerment = 0; + + public MachineFermenter() { + setHints(Config.hints.get("fermenter")); + } + + @Override + public String getInventoryName() { + return "factory.3"; + } + + @Override + public void openGui(EntityPlayer player, TileBase tile) { + player.openGui(ForestryAPI.instance, GuiId.FermenterGUI.ordinal(), player.worldObj, xCoord, yCoord, zCoord); + } + + @Override + protected void configurePowerProvider(PowerHandler provider) { + provider.configure(5, 200, 15, 800); + } + + @Override + public void writeToNBT(NBTTagCompound nbttagcompound) { + super.writeToNBT(nbttagcompound); + + nbttagcompound.setInteger("FermentationTime", fermentationTime); + nbttagcompound.setInteger("FermentationTotalTime", fermentationTotalTime); + nbttagcompound.setInteger("FuelBurnTime", fuelBurnTime); + nbttagcompound.setInteger("FuelTotalTime", fuelTotalTime); + nbttagcompound.setInteger("FuelCurrentFerment", fuelCurrentFerment); + + NBTTagCompound NBTresourceSlot = new NBTTagCompound(); + NBTTagCompound NBTproductSlot = new NBTTagCompound(); + + resourceTank.writeToNBT(NBTresourceSlot); + productTank.writeToNBT(NBTproductSlot); + + nbttagcompound.setTag("ResourceTank", NBTresourceSlot); + nbttagcompound.setTag("ProductTank", NBTproductSlot); + + inventory.writeToNBT(nbttagcompound); + + } + + @Override + public void readFromNBT(NBTTagCompound nbttagcompound) { + super.readFromNBT(nbttagcompound); + + fermentationTime = nbttagcompound.getInteger("FermentationTime"); + fermentationTotalTime = nbttagcompound.getInteger("FermentationTotalTime"); + fuelBurnTime = nbttagcompound.getInteger("FuelBurnTime"); + fuelTotalTime = nbttagcompound.getInteger("FuelTotalTime"); + fuelCurrentFerment = nbttagcompound.getInteger("FuelCurrentFerment"); + + resourceTank = new ForestryTank(Defaults.PROCESSOR_TANK_CAPACITY); + productTank = new ForestryTank(Defaults.PROCESSOR_TANK_CAPACITY); + if (nbttagcompound.hasKey("ResourceTank")) { + resourceTank.readFromNBT(nbttagcompound.getCompoundTag("ResourceTank")); + productTank.readFromNBT(nbttagcompound.getCompoundTag("ProductTank")); + } + + inventory.readFromNBT(nbttagcompound); + } + + @Override + public void updateServerSide() { + + // Check if we have suitable items waiting in the item slot + if (inventory.getStackInSlot(SLOT_INPUT) != null) { + + FluidContainerData container = LiquidHelper.getLiquidContainer(inventory.getStackInSlot(SLOT_INPUT)); + if (container != null && RecipeManager.isLiquidResource(container.fluid)) { + + inventory.setInventorySlotContents(SLOT_INPUT, StackUtils.replenishByContainer(this, inventory.getStackInSlot(SLOT_INPUT), container, resourceTank)); + if (inventory.getStackInSlot(SLOT_INPUT).stackSize <= 0) + inventory.setInventorySlotContents(SLOT_INPUT, null); + + } + } + // Can/capsule input/output needs to be handled here. + if (inventory.getStackInSlot(SLOT_CAN_INPUT) != null) { + FluidContainerData container = LiquidHelper.getEmptyContainer(inventory.getStackInSlot(SLOT_CAN_INPUT), productTank.getFluid()); + + if (container != null) { + inventory.setInventorySlotContents(SLOT_CAN_OUTPUT, bottleIntoContainer(inventory.getStackInSlot(SLOT_CAN_INPUT), inventory.getStackInSlot(SLOT_CAN_OUTPUT), container, + productTank)); + if (inventory.getStackInSlot(SLOT_CAN_INPUT).stackSize <= 0) + inventory.setInventorySlotContents(SLOT_CAN_INPUT, null); + } + } + + if (worldObj.getTotalWorldTime() % 20 * 10 != 0) + return; + + if (RecipeManager.findMatchingRecipe(inventory.getStackInSlot(SLOT_RESOURCE), resourceTank.getFluid()) != null) + setErrorState(EnumErrorCode.OK); + else if (inventory.getStackInSlot(SLOT_FUEL) == null && fuelBurnTime <= 0) + setErrorState(EnumErrorCode.NOFUEL); + else + setErrorState(EnumErrorCode.NORECIPE); + } + + @Override + public boolean workCycle() { + + if (currentRecipe == null) { + checkRecipe(); + resetRecipe(); + + if (currentRecipe != null) { + currentResourceModifier = determineResourceMod(inventory.getStackInSlot(SLOT_RESOURCE)); + decrStackSize(SLOT_RESOURCE, 1); + return true; + } else + return false; + + // If we have burnTime left, just decrease it. + } else if (fuelBurnTime > 0) { + if (currentRecipe == null) { + /* there was a fail-safe check for this before, but it can + never happen due to the 1st if clause unless there's some + thread unsafe accessing going on which has to fixed otherwise. */ + throw new NullPointerException("currentRecipe is null"); + } + + if (resourceTank.getFluidAmount() < fuelCurrentFerment) + return false; + + // Nothing to do, return + if (fermentationTime <= 0) + return false; + + int fermented = Math.min(fermentationTime, this.fuelCurrentFerment); + + // input are checked, add output if possible + if (!addProduct(new FluidStack(currentRecipe.output, + Math.round(fermented * currentRecipe.modifier * currentResourceModifier)))) { + return false; // the output tank is too full, TODO: check/add error code? + } + + fuelBurnTime--; + resourceTank.drain(fuelCurrentFerment, true); + fermentationTime -= this.fuelCurrentFerment; + + // Not done yet + if (fermentationTime > 0) + return true; + + currentRecipe = null; + return true; + + } else { // out of fuel + + // Use only fuel that provides value + fuelBurnTime = fuelTotalTime = determineFuelValue(getFuelStack()); + if (fuelBurnTime > 0) { + this.fuelCurrentFerment = determineFermentPerCycle(getFuelStack()); + decrStackSize(1, 1); + return true; + } else { + this.fuelCurrentFerment = 0; + return false; + } + } + } + + private boolean addProduct(FluidStack output) { + int amount = productTank.fill(output, false); + + if (amount == output.amount) { + productTank.fill(output, true); + + return true; + } else { + return false; + } + } + + private void checkRecipe() { + Recipe sameRec = RecipeManager.findMatchingRecipe(inventory.getStackInSlot(SLOT_RESOURCE), resourceTank.getFluid()); + + if (currentRecipe != sameRec) + currentRecipe = sameRec; + } + + private void resetRecipe() { + if (currentRecipe == null) { + fermentationTime = 0; + fermentationTotalTime = 0; + return; + } + + fermentationTime = currentRecipe.fermentationValue; + fermentationTotalTime = currentRecipe.fermentationValue; + } + + /** + * Returns the burnTime an item of the passed ItemStack provides + * + * @param item + * @return + */ + private int determineFuelValue(ItemStack item) { + if (item == null) + return 0; + + if (FuelManager.fermenterFuel.containsKey(item)) + return FuelManager.fermenterFuel.get(item).burnDuration; + else + return 0; + } + + private int determineFermentPerCycle(ItemStack item) { + if (item == null) + return 0; + + if (FuelManager.fermenterFuel.containsKey(item)) + return FuelManager.fermenterFuel.get(item).fermentPerCycle; + else + return 0; + } + + private float determineResourceMod(ItemStack itemstack) { + if (!(itemstack.getItem() instanceof IVariableFermentable)) + return 1.0f; + + return ((IVariableFermentable) itemstack.getItem()).getFermentationModifier(itemstack); + } + + @Override + public boolean isWorking() { + if (currentRecipe == null + && RecipeManager.findMatchingRecipe(inventory.getStackInSlot(SLOT_RESOURCE), resourceTank.getFluid()) == null) + return false; + if (fuelBurnTime > 0) + return resourceTank.getFluidAmount() > 0 && productTank.getFluidAmount() < Defaults.PROCESSOR_TANK_CAPACITY; + else + return determineFuelValue(getFuelStack()) > 0; + } + + @Override + public boolean hasResourcesMin(float percentage) { + if (this.getFermentationStack() == null) + return false; + + return ((float) getFermentationStack().stackSize / (float) getFermentationStack().getMaxStackSize()) > percentage; + } + + @Override + public boolean hasFuelMin(float percentage) { + if (this.getFuelStack() == null) + return false; + + return ((float) getFuelStack().stackSize / (float) getFuelStack().getMaxStackSize()) > percentage; + } + + @Override + public boolean hasWork() { + if (this.getFuelStack() == null && fuelBurnTime <= 0) + return false; + else if (fuelBurnTime <= 0) + if (RecipeManager.findMatchingRecipe(inventory.getStackInSlot(SLOT_RESOURCE), resourceTank.getFluid()) == null) + return false; + + if (this.getFermentationStack() == null && fermentationTime <= 0) + return false; + else if (fermentationTime <= 0) + if (RecipeManager.findMatchingRecipe(inventory.getStackInSlot(SLOT_RESOURCE), resourceTank.getFluid()) == null) + return false; + + if (resourceTank.getFluidAmount() <= 0) + return false; + + if (productTank.getFluidAmount() >= productTank.getCapacity()) + return false; + + return true; + } + + public int getBurnTimeRemainingScaled(int i) { + if (fuelTotalTime == 0) + return 0; + + return (fuelBurnTime * i) / fuelTotalTime; + } + + public int getFermentationProgressScaled(int i) { + if (fermentationTotalTime == 0) + return 0; + + return (fermentationTime * i) / fermentationTotalTime; + } + + public int getResourceScaled(int i) { + return (resourceTank.getFluidAmount() * i) / Defaults.PROCESSOR_TANK_CAPACITY; + } + + public int getProductScaled(int i) { + return (productTank.getFluidAmount() * i) / Defaults.PROCESSOR_TANK_CAPACITY; + } + + @Override + public EnumTankLevel getPrimaryLevel() { + return Utils.rateTankLevel(getResourceScaled(100)); + } + + @Override + public EnumTankLevel getSecondaryLevel() { + return Utils.rateTankLevel(getProductScaled(100)); + } + + public ItemStack getFermentationStack() { + return inventory.getStackInSlot(SLOT_RESOURCE); + } + + public ItemStack getFuelStack() { + return inventory.getStackInSlot(SLOT_FUEL); + } + + /* SMP GUI */ + public void getGUINetworkData(int i, int j) { + + switch (i) { + case 0: + fuelBurnTime = j; + break; + case 1: + fuelTotalTime = j; + break; + case 2: + fermentationTime = j; + break; + case 3: + fermentationTotalTime = j; + break; + } + } + + public void sendGUINetworkData(Container container, ICrafting iCrafting) { + iCrafting.sendProgressBarUpdate(container, 0, fuelBurnTime); + iCrafting.sendProgressBarUpdate(container, 1, fuelTotalTime); + iCrafting.sendProgressBarUpdate(container, 2, fermentationTime); + iCrafting.sendProgressBarUpdate(container, 3, fermentationTotalTime); + } + + /* INVENTORY */ + @Override + public InventoryAdapter getInternalInventory() { + return inventory; + } + + @Override + protected boolean canTakeStackFromSide(int slotIndex, ItemStack itemstack, int side) { + + if (!super.canTakeStackFromSide(slotIndex, itemstack, side)) + return false; + + if (slotIndex == SLOT_CAN_OUTPUT) + return true; + + return false; + } + + @Override + protected boolean canPutStackFromSide(int slotIndex, ItemStack itemstack, int side) { + + if (!super.canPutStackFromSide(slotIndex, itemstack, side)) + return false; + + if (slotIndex == SLOT_RESOURCE && RecipeManager.isResource(itemstack)) + return true; + + + if (slotIndex == SLOT_INPUT) { + FluidContainerData container = LiquidHelper.getLiquidContainer(itemstack); + return container != null && RecipeManager.isLiquidResource(container.fluid); + } + + if (slotIndex == SLOT_CAN_INPUT && LiquidHelper.isEmptyContainer(itemstack)) { + return true; + } + if (slotIndex == SLOT_FUEL && FuelManager.fermenterFuel.containsKey(itemstack)) + return true; + + return false; + } + + @Override + public int getSizeInventory() { + return inventory.getSizeInventory(); + } + + @Override + public ItemStack getStackInSlot(int i) { + return inventory.getStackInSlot(i); + } + + @Override + public ItemStack decrStackSize(int i, int j) { + return inventory.decrStackSize(i, j); + } + + @Override + public void setInventorySlotContents(int i, ItemStack itemstack) { + inventory.setInventorySlotContents(i, itemstack); + } + + @Override + public ItemStack getStackInSlotOnClosing(int slot) { + return inventory.getStackInSlotOnClosing(slot); + } + + @Override + public int getInventoryStackLimit() { + return inventory.getInventoryStackLimit(); + } + + @Override + public void openInventory() { + } + + @Override + public void closeInventory() { + } + + /** + * TODO: just a specialsource workaround + */ + @Override + public boolean isUseableByPlayer(EntityPlayer player) { + return super.isUseableByPlayer(player); + } + + /** + * TODO: just a specialsource workaround + */ + @Override + public boolean hasCustomInventoryName() { + return super.hasCustomInventoryName(); + } + + /** + * TODO: just a specialsource workaround + */ + @Override + public boolean isItemValidForSlot(int slotIndex, ItemStack itemstack) { + return super.isItemValidForSlot(slotIndex, itemstack); + } + + /** + * TODO: just a specialsource workaround + */ + @Override + public boolean canInsertItem(int i, ItemStack itemstack, int j) { + return super.canInsertItem(i, itemstack, j); + } + + /** + * TODO: just a specialsource workaround + */ + @Override + public boolean canExtractItem(int i, ItemStack itemstack, int j) { + return super.canExtractItem(i, itemstack, j); + } + + /** + * TODO: just a specialsource workaround + */ + @Override + public int[] getAccessibleSlotsFromSide(int side) { + return super.getAccessibleSlotsFromSide(side); + } + + // ILIQUIDCONTAINER IMPLEMENTATION + @Override + public int fill(ForgeDirection from, FluidStack resource, boolean doFill) { + + if (!RecipeManager.isLiquidResource(resource)) + return 0; + + int used = resourceTank.fill(resource, doFill); + + if (doFill && used > 0) + // updateNetworkTime.markTime(worldObj); + sendNetworkUpdate(); + + return used; + } + + @Override + public FluidStack drain(ForgeDirection from, int quantityMax, boolean doEmpty) { + return productTank.drain(quantityMax, doEmpty); + } + + @Override + public ForestryTank[] getTanks() { + return new ForestryTank[] { resourceTank, productTank }; + } + + // ITRIGGERPROVIDER + @Override + public LinkedList getCustomTriggers() { + LinkedList res = new LinkedList(); + res.add(ForestryTrigger.lowFuel25); + res.add(ForestryTrigger.lowFuel10); + res.add(ForestryTrigger.lowResource25); + res.add(ForestryTrigger.lowResource10); + res.add(ForestryTrigger.hasWork); + return res; + } +} diff --git a/forestry_common/factory/forestry/factory/gadgets/MachineMoistener.java b/forestry_common/factory/forestry/factory/gadgets/MachineMoistener.java new file mode 100755 index 000000000..f1341499b --- /dev/null +++ b/forestry_common/factory/forestry/factory/gadgets/MachineMoistener.java @@ -0,0 +1,728 @@ +/******************************************************************************* + * Copyright 2011-2014 by SirSengir + * + * This work is licensed under a Creative Commons Attribution-NonCommercial-NoDerivs 3.0 Unported License. + * + * To view a copy of this license, visit http://creativecommons.org/licenses/by-nc-nd/3.0/. + ******************************************************************************/ +package forestry.factory.gadgets; + +import java.util.ArrayList; +import java.util.HashMap; +import java.util.LinkedList; +import java.util.Map; + +import net.minecraft.entity.player.EntityPlayer; +import net.minecraft.inventory.Container; +import net.minecraft.inventory.ICrafting; +import net.minecraft.inventory.ISidedInventory; +import net.minecraft.item.ItemStack; +import net.minecraft.nbt.NBTTagCompound; + +import net.minecraftforge.common.util.ForgeDirection; +import net.minecraftforge.fluids.FluidContainerRegistry.FluidContainerData; +import net.minecraftforge.fluids.FluidStack; + +import buildcraft.api.gates.ITrigger; +import buildcraft.api.inventory.ISpecialInventory; + +import forestry.api.core.ForestryAPI; +import forestry.api.fuels.FuelManager; +import forestry.api.fuels.MoistenerFuel; +import forestry.api.recipes.IMoistenerManager; +import forestry.core.EnumErrorCode; +import forestry.core.config.Config; +import forestry.core.config.Defaults; +import forestry.core.gadgets.TileBase; +import forestry.core.gadgets.TilePowered; +import forestry.core.interfaces.ILiquidTankContainer; +import forestry.core.network.EntityNetData; +import forestry.core.network.GuiId; +import forestry.core.triggers.ForestryTrigger; +import forestry.core.utils.EnumTankLevel; +import forestry.core.utils.ForestryTank; +import forestry.core.utils.InventoryAdapter; +import forestry.core.utils.LiquidHelper; +import forestry.core.utils.StackUtils; +import forestry.core.utils.Utils; + +public class MachineMoistener extends TilePowered implements ISpecialInventory, ISidedInventory, ILiquidTankContainer { + + /* CONSTANTS */ + private static final short SLOT_STASH_1 = 0; + private static final short SLOT_RESERVOIR_1 = 6; + private static final short SLOT_WORKING = 9; + private static final short SLOT_PRODUCT = 10; + private static final short SLOT_RESOURCE = 11; + private static final short SLOTS_COUNT_RESERVOIR = 3; + private static final short SLOTS_COUNT_STASH = 6; + + private static final FluidStack STACK_WATER = LiquidHelper.getLiquid(Defaults.LIQUID_WATER, 1); + + /* RECIPE MANAGMENT */ + public static class Recipe { + public int timePerItem; + public ItemStack resource; + public ItemStack product; + + public Recipe(ItemStack resource, ItemStack product, int timePerItem) { + this.timePerItem = timePerItem; + this.resource = resource; + this.product = product; + } + + public boolean matches(ItemStack res) { + if (res == null && resource == null) + return true; + else if (res == null && resource != null) + return false; + else if (res != null && resource == null) + return false; + else + return resource.isItemEqual(res); + } + } + + public static class RecipeManager implements IMoistenerManager { + public static ArrayList recipes = new ArrayList(); + + @Override + public void addRecipe(ItemStack resource, ItemStack product, int timePerItem) { + recipes.add(new MachineMoistener.Recipe(resource, product, timePerItem)); + } + + public static boolean isResource(ItemStack resource) { + if(resource == null) + return false; + + for(Recipe rec : recipes) { + if(StackUtils.isIdenticalItem(resource, rec.resource)) + return true; + } + + return false; + } + + public static Recipe findMatchingRecipe(ItemStack item) { + for (int i = 0; i < recipes.size(); i++) { + Recipe recipe = recipes.get(i); + if (recipe.matches(item)) + return recipe; + } + return null; + } + + @Override + public Map getRecipes() { + HashMap recipeList = new HashMap(); + + for (Recipe recipe : recipes) + recipeList.put(new ItemStack[] { recipe.resource }, new ItemStack[] { recipe.product }); + + return recipeList; + } + } + + @EntityNetData + public ForestryTank resourceTank = new ForestryTank(Defaults.PROCESSOR_TANK_CAPACITY); + private final InventoryAdapter inventory = new InventoryAdapter(12, "Items"); + //private ItemStack[] inventoryStacks = new ItemStack[12]; + public MachineMoistener.Recipe currentRecipe; + + public int burnTime = 0; + public int totalTime = 0; + public int productionTime = 0; + private int timePerItem = 0; + private ItemStack currentProduct; + private ItemStack pendingProduct; + + public MachineMoistener() { + setHints(Config.hints.get("moistener")); + } + + @Override + public String getInventoryName() { + return "factory.4"; + } + + @Override + public void openGui(EntityPlayer player, TileBase tile) { + player.openGui(ForestryAPI.instance, GuiId.MoistenerGUI.ordinal(), player.worldObj, xCoord, yCoord, zCoord); + } + + /* LOADING & SAVING */ + @Override + public void writeToNBT(NBTTagCompound nbttagcompound) { + super.writeToNBT(nbttagcompound); + + nbttagcompound.setInteger("BurnTime", burnTime); + nbttagcompound.setInteger("TotalTime", totalTime); + nbttagcompound.setInteger("ProductionTime", productionTime); + + NBTTagCompound NBTresourceSlot = new NBTTagCompound(); + + resourceTank.writeToNBT(NBTresourceSlot); + nbttagcompound.setTag("ResourceTank", NBTresourceSlot); + + inventory.writeToNBT(nbttagcompound); + + // Write pending product + if (pendingProduct != null) { + NBTTagCompound nbttagcompoundP = new NBTTagCompound(); + pendingProduct.writeToNBT(nbttagcompoundP); + nbttagcompound.setTag("PendingProduct", nbttagcompoundP); + } + if (currentProduct != null) { + NBTTagCompound nbttagcompoundP = new NBTTagCompound(); + currentProduct.writeToNBT(nbttagcompoundP); + nbttagcompound.setTag("CurrentProduct", nbttagcompoundP); + } + } + + @Override + public void readFromNBT(NBTTagCompound nbttagcompound) { + super.readFromNBT(nbttagcompound); + + burnTime = nbttagcompound.getInteger("BurnTime"); + totalTime = nbttagcompound.getInteger("TotalTime"); + productionTime = nbttagcompound.getInteger("ProductionTime"); + + resourceTank = new ForestryTank(Defaults.PROCESSOR_TANK_CAPACITY); + if (nbttagcompound.hasKey("ResourceTank")) + resourceTank.readFromNBT(nbttagcompound.getCompoundTag("ResourceTank")); + + inventory.readFromNBT(nbttagcompound); + + // Load pending product + if (nbttagcompound.hasKey("PendingProduct")) { + NBTTagCompound nbttagcompoundP = nbttagcompound.getCompoundTag("PendingProduct"); + pendingProduct = ItemStack.loadItemStackFromNBT(nbttagcompoundP); + } + if (nbttagcompound.hasKey("CurrentProduct")) { + NBTTagCompound nbttagcompoundP = nbttagcompound.getCompoundTag("CurrentProduct"); + currentProduct = ItemStack.loadItemStackFromNBT(nbttagcompoundP); + } + + checkRecipe(); + } + + @Override + public void updateServerSide() { + + // Check if we have suitable water container waiting in the item slot + if (inventory.getStackInSlot(SLOT_PRODUCT) != null) { + FluidContainerData container = LiquidHelper.getLiquidContainer(inventory.getStackInSlot(SLOT_PRODUCT)); + if (container != null && container.fluid.isFluidEqual(STACK_WATER)) { + + inventory.setInventorySlotContents(SLOT_PRODUCT, StackUtils.replenishByContainer(this, inventory.getStackInSlot(SLOT_PRODUCT), container, resourceTank)); + if (inventory.getStackInSlot(SLOT_PRODUCT).stackSize <= 0) + inventory.setInventorySlotContents(SLOT_PRODUCT, null); + } + } + + // Let's get to work + int lightvalue = worldObj.getBlockLightValue(xCoord, yCoord + 1, zCoord); + + // Not working in broad daylight + if (lightvalue > 11) { + setErrorState(EnumErrorCode.NOTGLOOMY); + return; + } + + // The darker, the better + int speed; + if (lightvalue >= 9) + speed = 1; + else if (lightvalue >= 7) + speed = 2; + else if (lightvalue >= 5) + speed = 3; + else + speed = 4; + + // Already running + if (burnTime > 0 && pendingProduct == null) { + // Not working if there is no water available. + if (resourceTank.getFluidAmount() <= 0) + return; + + checkRecipe(); + + if (currentRecipe == null) + return; + + resourceTank.drain(1, true); + burnTime -= speed; + productionTime -= speed; + + if (productionTime <= 0) { + pendingProduct = currentProduct; + decrStackSize(SLOT_RESOURCE, 1); + resetRecipe(); + tryAddPending(); + } + + } else if (pendingProduct != null) + tryAddPending(); + // Try to start process + else // Make sure we have a new item in the working slot. + if (rotateWorkingSlot()) { + checkRecipe(); + + // Let's see if we have a valid resource in the working slot + if (inventory.getStackInSlot(SLOT_WORKING) == null) + return; + + if (FuelManager.moistenerResource.containsKey(inventory.getStackInSlot(SLOT_WORKING))) { + MoistenerFuel res = FuelManager.moistenerResource.get(inventory.getStackInSlot(SLOT_WORKING)); + burnTime = totalTime = res.moistenerValue; + } + } else + rotateReservoir(); + + if (currentRecipe != null) + setErrorState(EnumErrorCode.OK); + else + setErrorState(EnumErrorCode.NORECIPE); + } + + private boolean tryAddPending() { + if (pendingProduct == null) + return false; + + if(inventory.tryAddStack(pendingProduct, SLOT_PRODUCT, 1, true)) { + pendingProduct = null; + return true; + } + + return false; + } + + public void checkRecipe() { + Recipe sameRec = RecipeManager.findMatchingRecipe(inventory.getStackInSlot(SLOT_RESOURCE)); + if (currentRecipe != sameRec) { + currentRecipe = sameRec; + resetRecipe(); + } + } + + private void resetRecipe() { + if (currentRecipe == null) { + currentProduct = null; + productionTime = 0; + timePerItem = 0; + setErrorState(EnumErrorCode.NORECIPE); + return; + } + + currentProduct = currentRecipe.product; + productionTime = currentRecipe.timePerItem; + timePerItem = currentRecipe.timePerItem; + } + + private int getFreeSlot(ItemStack deposit, int startSlot, int endSlot, boolean emptyOnly) { + int slot = -1; + + for (int i = startSlot; i < endSlot; i++) { + ItemStack slotStack = inventory.getStackInSlot(i); + // Empty slots are okay. + if (slotStack == null) { + if (slot < 0) + slot = i; + continue; + } + + if (emptyOnly) + continue; + + // Wrong item or full + if (!slotStack.isItemEqual(deposit) || slotStack.stackSize >= slotStack.getMaxStackSize()) + continue; + + slot = i; + } + + return slot; + } + + private int getFreeStashSlot(ItemStack deposit, boolean emptyOnly) { + return getFreeSlot(deposit, 0, SLOT_RESERVOIR_1, emptyOnly); + } + + private int getFreeReservoirSlot(ItemStack deposit) { + return getFreeSlot(deposit, SLOT_RESERVOIR_1, SLOT_RESERVOIR_1 + SLOTS_COUNT_RESERVOIR, false); + + } + + private int getNextResourceSlot(int startSlot, int endSlot) { + // Let's look for a new resource to put into the working slot. + int stage = -1; + int resourceSlot = -1; + + for (int i = startSlot; i < endSlot; i++) { + ItemStack slotStack = inventory.getStackInSlot(i); + if (slotStack == null) + continue; + + if (!FuelManager.moistenerResource.containsKey(slotStack)) + continue; + + MoistenerFuel res = FuelManager.moistenerResource.get(slotStack); + if (stage < 0 || res.stage < stage) { + stage = res.stage; + resourceSlot = i; + } + } + + return resourceSlot; + } + + private boolean rotateWorkingSlot() { + // Put working slot contents into inventory if space is available + if (inventory.getStackInSlot(SLOT_WORKING) != null) { + // Get the result of the consumed item in the working slot + ItemStack deposit; + if (FuelManager.moistenerResource.containsKey(inventory.getStackInSlot(SLOT_WORKING))) { + MoistenerFuel res = FuelManager.moistenerResource.get(inventory.getStackInSlot(SLOT_WORKING)); + deposit = res.product.copy(); + } else + deposit = inventory.getStackInSlot(SLOT_WORKING).copy(); + + int targetSlot = getFreeReservoirSlot(deposit); + // We stop the whole thing, if we don't have any room anymore. + if (targetSlot < 0) + return false; + + if (inventory.getStackInSlot(targetSlot) == null) + inventory.setInventorySlotContents(targetSlot, deposit); + else + inventory.getStackInSlot(targetSlot).stackSize++; + + decrStackSize(SLOT_WORKING, 1); + } + + if (inventory.getStackInSlot(SLOT_WORKING) != null) + return true; + + // Let's look for a new resource to put into the working slot. + int resourceSlot = getNextResourceSlot(SLOT_RESERVOIR_1, SLOT_RESERVOIR_1 + SLOTS_COUNT_RESERVOIR); + // Nothing found, stop. + if (resourceSlot < 0) + return false; + + inventory.setInventorySlotContents(SLOT_WORKING, inventory.decrStackSize(resourceSlot, 1)); + return true; + } + + private void rotateReservoir() { + ArrayList slotsToShift = new ArrayList(); + + for (int i = SLOT_RESERVOIR_1; i < SLOT_RESERVOIR_1 + SLOTS_COUNT_RESERVOIR; i++) { + if (inventory.getStackInSlot(i) == null) + continue; + + if (!FuelManager.moistenerResource.containsKey(inventory.getStackInSlot(i))) + slotsToShift.add(i); + } + + // Move consumed items back to stash + int shiftedSlots = 0; + for (int slot : slotsToShift) { + ItemStack slotStack = inventory.getStackInSlot(slot); + int targetSlot = getFreeStashSlot(slotStack, true); + if (targetSlot < 0) + continue; + + inventory.setInventorySlotContents(targetSlot, slotStack); + inventory.setInventorySlotContents(slot, null); + shiftedSlots++; + } + + // Grab new items from stash + for (int i = 0; i < (slotsToShift.size() > 0 ? shiftedSlots : 2); i++) { + int resourceSlot = getNextResourceSlot(0, SLOT_RESERVOIR_1); + // Stop if no resources are available + if (resourceSlot < 0) + break; + int targetSlot = getFreeReservoirSlot(inventory.getStackInSlot(resourceSlot)); + // No free target slot, stop + if (targetSlot < 0) + break; + // Else shift + if (inventory.getStackInSlot(targetSlot) == null) { + inventory.setInventorySlotContents(targetSlot, inventory.getStackInSlot(resourceSlot)); + inventory.setInventorySlotContents(resourceSlot, null); + } else { + StackUtils.mergeStacks(inventory.getStackInSlot(resourceSlot), inventory.getStackInSlot(targetSlot)); + if (inventory.getStackInSlot(resourceSlot) != null && inventory.getStackInSlot(resourceSlot).stackSize <= 0) + inventory.setInventorySlotContents(resourceSlot, null); + } + } + } + + @Override + public boolean workCycle() { + return false; + } + + @Override + public boolean isWorking() { + return burnTime > 0 && resourceTank.getFluidAmount() > 0; + } + + @Override + public boolean hasFuelMin(float percentage) { + int max = 0; + int avail = 0; + + for (int i = SLOT_STASH_1; i < SLOT_RESERVOIR_1; i++) { + if (inventory.getStackInSlot(i) == null) { + max += 64; + continue; + } + if (FuelManager.moistenerResource.containsKey(inventory.getStackInSlot(i))) { + MoistenerFuel res = FuelManager.moistenerResource.get(inventory.getStackInSlot(i)); + if (res.item.isItemEqual(inventory.getStackInSlot(i))) { + max += 64; + avail += inventory.getStackInSlot(i).stackSize; + } + } + } + + return ((float) avail / (float) max) > percentage; + } + + @Override + public boolean hasResourcesMin(float percentage) { + if (inventory.getStackInSlot(SLOT_RESOURCE) == null) + return false; + + return ((float) inventory.getStackInSlot(SLOT_RESOURCE).stackSize / (float) inventory.getStackInSlot(SLOT_RESOURCE).getMaxStackSize()) > percentage; + } + + public boolean isProducing() { + return productionTime > 0; + } + + public int getProductionProgressScaled(int i) { + if (timePerItem == 0) + return 0; + + return (productionTime * i) / timePerItem; + + } + + public int getConsumptionProgressScaled(int i) { + if (totalTime == 0) + return 0; + + return (burnTime * i) / totalTime; + + } + + public int getResourceScaled(int i) { + return (resourceTank.getFluidAmount() * i) / Defaults.PROCESSOR_TANK_CAPACITY; + } + + @Override + public EnumTankLevel getPrimaryLevel() { + return Utils.rateTankLevel(getResourceScaled(100)); + } + + /* IINVENTORY */ + @Override public int getSizeInventory() { return inventory.getSizeInventory(); } + @Override public ItemStack getStackInSlot(int i) { return inventory.getStackInSlot(i); } + @Override public ItemStack decrStackSize(int i, int j) { return inventory.decrStackSize(i, j); } + @Override public void setInventorySlotContents(int i, ItemStack itemstack) { inventory.setInventorySlotContents(i, itemstack); } + @Override public ItemStack getStackInSlotOnClosing(int slot) { return inventory.getStackInSlotOnClosing(slot); } + @Override public int getInventoryStackLimit() { return inventory.getInventoryStackLimit(); } + @Override public void openInventory() {} + @Override public void closeInventory() {} + + /** + * TODO: just a specialsource workaround + */ + @Override + public boolean isUseableByPlayer(EntityPlayer player) { + return super.isUseableByPlayer(player); + } + + /** + * TODO: just a specialsource workaround + */ + @Override + public boolean hasCustomInventoryName() { + return super.hasCustomInventoryName(); + } + + /** + * TODO: just a specialsource workaround + */ + @Override + public boolean isItemValidForSlot(int slotIndex, ItemStack itemstack) { + return super.isItemValidForSlot(slotIndex, itemstack); + } + + /** + * TODO: just a specialsource workaround + */ + @Override + public boolean canInsertItem(int i, ItemStack itemstack, int j) { + return super.canInsertItem(i, itemstack, j); + } + + /** + * TODO: just a specialsource workaround + */ + @Override + public boolean canExtractItem(int i, ItemStack itemstack, int j) { + return super.canExtractItem(i, itemstack, j); + } + + /** + * TODO: just a specialsource workaround + */ + @Override + public int[] getAccessibleSlotsFromSide(int side) { + return super.getAccessibleSlotsFromSide(side); + } + + /* ISIDEDINVENTORY */ + @Override + public InventoryAdapter getInternalInventory() { + return inventory; + } + + @Override + protected boolean canTakeStackFromSide(int slotIndex, ItemStack itemstack, int side) { + + if(!super.canTakeStackFromSide(slotIndex, itemstack, side)) + return false; + + if(slotIndex == SLOT_PRODUCT) + return true; + + if(slotIndex >= SLOT_STASH_1 && slotIndex < SLOT_STASH_1 + SLOTS_COUNT_STASH) { + return !FuelManager.moistenerResource.containsKey(itemstack); + } + + return false; + } + + @Override + protected boolean canPutStackFromSide(int slotIndex, ItemStack itemstack, int side) { + + if(!super.canPutStackFromSide(slotIndex, itemstack, side)) + return false; + + if(slotIndex == SLOT_RESOURCE) + return RecipeManager.isResource(itemstack); + + if(slotIndex >= SLOT_STASH_1 && slotIndex < SLOT_STASH_1 + SLOTS_COUNT_STASH - 2) { + return FuelManager.moistenerResource.containsKey(itemstack); + } + + return false; + } + + /* ISPECIALINVENTORY */ + @Override + public int addItem(ItemStack stack, boolean doAdd, ForgeDirection from) { + + FluidContainerData container = LiquidHelper.getLiquidContainer(stack); + if (container != null && container.fluid.isFluidEqual(STACK_WATER)) { + return inventory.addStack(stack, SLOT_PRODUCT, 1, false, doAdd); + } + + // Try to add to resource slot if input is from top or bottom. + if (from == ForgeDirection.UP || from == ForgeDirection.DOWN) { + return inventory.addStack(stack, SLOT_RESOURCE, 1, false, doAdd); + } + + return inventory.addStack(stack, SLOT_STASH_1, SLOTS_COUNT_STASH - 2, false, doAdd); + } + + @Override + public ItemStack[] extractItem(boolean doRemove, ForgeDirection from, int maxItemCount) { + ItemStack product; + + ItemStack slotStack = inventory.getStackInSlot(SLOT_PRODUCT); + if (slotStack != null && slotStack.stackSize > 0) { + + product = new ItemStack(slotStack.getItem(), 1, slotStack.getItemDamage()); + if (doRemove) { + inventory.decrStackSize(SLOT_PRODUCT, 1); + } + return new ItemStack[] { product }; + } else + for (int i = 0; i < SLOT_RESERVOIR_1; i++) { + slotStack = inventory.getStackInSlot(i); + if (slotStack == null) + continue; + + if (!FuelManager.moistenerResource.containsKey(slotStack)) { + product = new ItemStack(slotStack.getItem(), 1, slotStack.getItemDamage()); + if (doRemove) { + inventory.decrStackSize(i, 1); + } + return new ItemStack[] { product }; + } + } + + return StackUtils.EMPTY_STACK_ARRAY; + } + + /* ILIQUIDCONTAINER */ + @Override + public int fill(ForgeDirection from, FluidStack resource, boolean doFill) { + int used = resourceTank.fill(resource, doFill); + + if (doFill && used > 0) + sendNetworkUpdate(); + + return used; + } + + @Override + public ForestryTank[] getTanks() { + return new ForestryTank[] { resourceTank }; + } + + /* SMP GUI */ + public void getGUINetworkData(int i, int j) { + + switch (i) { + case 0: + burnTime = j; + break; + case 1: + totalTime = j; + break; + case 2: + productionTime = j; + break; + case 3: + timePerItem = j; + break; + } + } + + public void sendGUINetworkData(Container container, ICrafting iCrafting) { + iCrafting.sendProgressBarUpdate(container, 0, burnTime); + iCrafting.sendProgressBarUpdate(container, 1, totalTime); + iCrafting.sendProgressBarUpdate(container, 2, productionTime); + iCrafting.sendProgressBarUpdate(container, 3, timePerItem); + } + + // ITRIGGERPROVIDER + @Override + public LinkedList getCustomTriggers() { + LinkedList res = new LinkedList(); + res.add(ForestryTrigger.lowFuel25); + res.add(ForestryTrigger.lowFuel10); + res.add(ForestryTrigger.lowResource25); + res.add(ForestryTrigger.lowResource10); + return res; + } + +} diff --git a/forestry_common/factory/forestry/factory/gadgets/MachineRaintank.java b/forestry_common/factory/forestry/factory/gadgets/MachineRaintank.java new file mode 100755 index 000000000..bf29abc78 --- /dev/null +++ b/forestry_common/factory/forestry/factory/gadgets/MachineRaintank.java @@ -0,0 +1,313 @@ +/******************************************************************************* + * Copyright 2011-2014 by SirSengir + * + * This work is licensed under a Creative Commons Attribution-NonCommercial-NoDerivs 3.0 Unported License. + * + * To view a copy of this license, visit http://creativecommons.org/licenses/by-nc-nd/3.0/. + ******************************************************************************/ +package forestry.factory.gadgets; + +import java.util.LinkedList; + +import net.minecraft.entity.player.EntityPlayer; +import net.minecraft.inventory.Container; +import net.minecraft.inventory.ICrafting; +import net.minecraft.inventory.ISidedInventory; +import net.minecraft.item.ItemStack; +import net.minecraft.nbt.NBTTagCompound; +import net.minecraft.world.biome.BiomeGenBase; + +import net.minecraftforge.common.util.ForgeDirection; +import net.minecraftforge.fluids.FluidStack; + +import buildcraft.api.gates.ITrigger; + +import forestry.api.core.EnumHumidity; +import forestry.api.core.ForestryAPI; +import forestry.core.EnumErrorCode; +import forestry.core.config.Config; +import forestry.core.config.Defaults; +import forestry.core.gadgets.TileBase; +import forestry.core.interfaces.ILiquidTankContainer; +import forestry.core.network.GuiId; +import forestry.core.triggers.ForestryTrigger; +import forestry.core.utils.Fluids; +import forestry.core.utils.ForestryTank; +import forestry.core.utils.InventoryAdapter; +import forestry.core.utils.LiquidHelper; +import forestry.core.utils.StackUtils; +import forestry.core.utils.Utils; + +public class MachineRaintank extends TileBase implements ISidedInventory, ILiquidTankContainer { + + /* CONSTANTS */ + public static final short SLOT_RESOURCE = 0; + public static final short SLOT_PRODUCT = 1; + private static final FluidStack STACK_WATER = LiquidHelper.getLiquid(Defaults.LIQUID_WATER, Defaults.RAINTANK_AMOUNT_PER_UPDATE); + + /* MEMBER */ + public ForestryTank resourceTank = new ForestryTank(Defaults.RAINTANK_TANK_CAPACITY); + private final InventoryAdapter inventory = new InventoryAdapter(3, "Items"); + private boolean isValidBiome = true; + private int fillingTime; + private ItemStack usedEmpty; + + public MachineRaintank() { + setHints(Config.hints.get("raintank")); + + // Raintanks in desert and snow biomes are useless + if (worldObj != null) { + BiomeGenBase biome = Utils.getBiomeAt(worldObj, xCoord, zCoord); + if (EnumHumidity.getFromValue(biome.rainfall) == EnumHumidity.ARID) { + setErrorState(EnumErrorCode.INVALIDBIOME); + isValidBiome = false; + } + } + } + + @Override + public String getInventoryName() { + return "factory2.1"; + } + + @Override + public void openGui(EntityPlayer player, TileBase tile) { + player.openGui(ForestryAPI.instance, GuiId.RaintankGUI.ordinal(), player.worldObj, xCoord, yCoord, zCoord); + } + + @Override + public void writeToNBT(NBTTagCompound nbttagcompound) { + super.writeToNBT(nbttagcompound); + + nbttagcompound.setBoolean("IsValidBiome", isValidBiome); + + NBTTagCompound NBTresourceSlot = new NBTTagCompound(); + resourceTank.writeToNBT(NBTresourceSlot); + nbttagcompound.setTag("ResourceTank", NBTresourceSlot); + + inventory.writeToNBT(nbttagcompound); + } + + @Override + public void readFromNBT(NBTTagCompound nbttagcompound) { + super.readFromNBT(nbttagcompound); + + isValidBiome = nbttagcompound.getBoolean("IsValidBiome"); + + resourceTank = new ForestryTank(Defaults.RAINTANK_TANK_CAPACITY); + if (nbttagcompound.hasKey("ResourceTank")) + resourceTank.readFromNBT(nbttagcompound.getCompoundTag("ResourceTank")); + + inventory.readFromNBT(nbttagcompound); + } + + @Override + public void updateServerSide() { + if (!isValidBiome) + setErrorState(EnumErrorCode.INVALIDBIOME); + else if (!worldObj.canBlockSeeTheSky(xCoord, yCoord + 1, zCoord)) + setErrorState(EnumErrorCode.NOSKY); + else if (!worldObj.isRaining()) + setErrorState(EnumErrorCode.NOTRAINING); + else { + resourceTank.fill(STACK_WATER, true); + setErrorState(EnumErrorCode.OK); + } + + if (worldObj.getTotalWorldTime() % 16 != 0) + return; + + if (!StackUtils.isIdenticalItem(usedEmpty, inventory.getStackInSlot(SLOT_RESOURCE))) { + fillingTime = 0; + usedEmpty = null; + } + + if (usedEmpty == null) + usedEmpty = inventory.getStackInSlot(SLOT_RESOURCE); + + if (!isFilling()) + tryToStartFillling(); + else { + fillingTime--; + if (fillingTime <= 0 && LiquidHelper.fillContainers(this, inventory, SLOT_RESOURCE, SLOT_PRODUCT, Fluids.WATER.get())) + fillingTime = 0; + } + } + + public boolean isFilling() { + return fillingTime > 0; + } + + private void tryToStartFillling() { + // Nothing to do if no empty cans are available + if (!LiquidHelper.fillContainers(this, inventory, SLOT_RESOURCE, SLOT_PRODUCT, Fluids.WATER.get(), false)) + return; + + fillingTime = Defaults.RAINTANK_FILLING_TIME; + } + + public int getFillProgressScaled(int i) { + return (fillingTime * i) / Defaults.RAINTANK_FILLING_TIME; + } + + /* IINVENTORY */ + @Override + public int getSizeInventory() { + return inventory.getSizeInventory(); + } + + @Override + public ItemStack getStackInSlot(int i) { + return inventory.getStackInSlot(i); + } + + @Override + public ItemStack decrStackSize(int i, int j) { + return inventory.decrStackSize(i, j); + } + + @Override + public void setInventorySlotContents(int i, ItemStack itemstack) { + inventory.setInventorySlotContents(i, itemstack); + } + + @Override + public ItemStack getStackInSlotOnClosing(int slot) { + return inventory.getStackInSlotOnClosing(slot); + } + + @Override + public int getInventoryStackLimit() { + return inventory.getInventoryStackLimit(); + } + + @Override + public void openInventory() { + } + + @Override + public void closeInventory() { + } + + /** + * TODO: just a specialsource workaround + */ + @Override + public boolean isUseableByPlayer(EntityPlayer player) { + return super.isUseableByPlayer(player); + } + + /** + * TODO: just a specialsource workaround + */ + @Override + public boolean hasCustomInventoryName() { + return super.hasCustomInventoryName(); + } + + /** + * TODO: just a specialsource workaround + */ + @Override + public boolean isItemValidForSlot(int slotIndex, ItemStack itemstack) { + return super.isItemValidForSlot(slotIndex, itemstack); + } + + /** + * TODO: just a specialsource workaround + */ + @Override + public boolean canInsertItem(int i, ItemStack itemstack, int j) { + return super.canInsertItem(i, itemstack, j); + } + + /** + * TODO: just a specialsource workaround + */ + @Override + public boolean canExtractItem(int i, ItemStack itemstack, int j) { + return super.canExtractItem(i, itemstack, j); + } + + /** + * TODO: just a specialsource workaround + */ + @Override + public int[] getAccessibleSlotsFromSide(int side) { + return super.getAccessibleSlotsFromSide(side); + } + + /* ISIDEDINVENTORY */ + @Override + public InventoryAdapter getInternalInventory() { + return inventory; + } + + @Override + protected boolean canTakeStackFromSide(int slotIndex, ItemStack itemstack, int side) { + if (!super.canTakeStackFromSide(slotIndex, itemstack, side)) + return false; + + return slotIndex == SLOT_PRODUCT; + } + + @Override + protected boolean canPutStackFromSide(int slotIndex, ItemStack itemstack, int side) { + if (!super.canPutStackFromSide(slotIndex, itemstack, side)) + return false; + + if (slotIndex != SLOT_RESOURCE) + return false; + + return LiquidHelper.getEmptyContainer(itemstack, STACK_WATER) != null; + } + + /* SMP GUI */ + public void getGUINetworkData(int i, int j) { + switch (i) { + case 0: + fillingTime = j; + break; + } + } + + public void sendGUINetworkData(Container container, ICrafting iCrafting) { + iCrafting.sendProgressBarUpdate(container, 0, fillingTime); + } + + // / ILIQUIDCONTAINER IMPLEMENTATION + @Override + public int fill(ForgeDirection from, FluidStack resource, boolean doFill) { + // We only accept water + if (!resource.isFluidEqual(STACK_WATER)) + return 0; + + int used = resourceTank.fill(resource, doFill); + + if (doFill && used > 0) + // updateNetworkTime.markTime(worldObj); + sendNetworkUpdate(); + + return used; + } + + @Override + public FluidStack drain(ForgeDirection from, int quantityMax, boolean doEmpty) { + return resourceTank.drain(quantityMax, doEmpty); + } + + @Override + public ForestryTank[] getTanks() { + return new ForestryTank[] { resourceTank }; + } + + /* ITRIGGERPROVIDER */ + @Override + public LinkedList getCustomTriggers() { + LinkedList res = new LinkedList(); + res.add(ForestryTrigger.lowResource25); + res.add(ForestryTrigger.lowResource10); + res.add(ForestryTrigger.hasWork); + return res; + } +} diff --git a/forestry_common/factory/forestry/factory/gadgets/MachineSqueezer.java b/forestry_common/factory/forestry/factory/gadgets/MachineSqueezer.java new file mode 100755 index 000000000..d52cc908c --- /dev/null +++ b/forestry_common/factory/forestry/factory/gadgets/MachineSqueezer.java @@ -0,0 +1,558 @@ +/******************************************************************************* + * Copyright 2011-2014 by SirSengir + * + * This work is licensed under a Creative Commons Attribution-NonCommercial-NoDerivs 3.0 Unported License. + * + * To view a copy of this license, visit http://creativecommons.org/licenses/by-nc-nd/3.0/. + ******************************************************************************/ +package forestry.factory.gadgets; + +import java.util.ArrayList; +import java.util.HashMap; +import java.util.LinkedList; +import java.util.Map; +import java.util.Stack; + +import net.minecraft.entity.player.EntityPlayer; +import net.minecraft.inventory.Container; +import net.minecraft.inventory.ICrafting; +import net.minecraft.inventory.ISidedInventory; +import net.minecraft.item.ItemStack; +import net.minecraft.nbt.NBTTagCompound; +import net.minecraft.nbt.NBTTagList; + +import net.minecraftforge.common.util.ForgeDirection; +import net.minecraftforge.fluids.FluidContainerRegistry.FluidContainerData; +import net.minecraftforge.fluids.FluidStack; + +import buildcraft.api.gates.ITrigger; +import buildcraft.api.inventory.ISpecialInventory; +import buildcraft.api.power.PowerHandler; + +import forestry.api.core.ForestryAPI; +import forestry.api.recipes.ISqueezerManager; +import forestry.core.EnumErrorCode; +import forestry.core.config.Config; +import forestry.core.config.Defaults; +import forestry.core.gadgets.TileBase; +import forestry.core.gadgets.TilePowered; +import forestry.core.interfaces.ILiquidTankContainer; +import forestry.core.network.EntityNetData; +import forestry.core.network.GuiId; +import forestry.core.triggers.ForestryTrigger; +import forestry.core.utils.EnumTankLevel; +import forestry.core.utils.ForestryTank; +import forestry.core.utils.InventoryAdapter; +import forestry.core.utils.LiquidHelper; +import forestry.core.utils.StackUtils; +import forestry.core.utils.Utils; + +public class MachineSqueezer extends TilePowered implements ISpecialInventory, ISidedInventory, ILiquidTankContainer { + + /* CONSTANTS */ + private static final short SLOT_RESOURCE_1 = 0; + private static final short SLOTS_RESOURCE_COUNT = 9; + private static final short SLOT_REMNANT = 9; + private static final short SLOT_CAN_INPUT = 10; + private static final short SLOT_CAN_OUTPUT = 11; + + /* RECIPE MANAGMENT */ + public static class Recipe { + public final int timePerItem; + public final ItemStack[] resources; + public final FluidStack liquid; + public final ItemStack remnants; + public final int chance; + + public Recipe(int timePerItem, ItemStack[] resources, FluidStack liquid, ItemStack remnants, int chance) { + this.timePerItem = timePerItem; + this.resources = resources; + this.liquid = liquid; + this.remnants = remnants; + this.chance = chance; + } + + public boolean matches(ItemStack[] res) { + // No recipe without resource! + if (res == null || res.length <= 0) + return false; + + boolean matchedAll = true; + + for (ItemStack stack : resources) { + boolean matched = false; + for (ItemStack matchStack : res) { + if (matchStack == null) + continue; + + // If the item matches, we need enough items + if (matchStack.isItemEqual(stack)) + if (matchStack.stackSize >= stack.stackSize) { + matched = true; + break; + } + } + if (!matched) + matchedAll = false; + } + return matchedAll; + } + } + + public static class RecipeManager implements ISqueezerManager { + public static ArrayList recipes = new ArrayList(); + + @Override + public void addRecipe(int timePerItem, ItemStack[] resources, FluidStack liquid, ItemStack remnants, int chance) { + recipes.add(new MachineSqueezer.Recipe(timePerItem, resources, liquid, remnants, chance)); + } + + @Override + public void addRecipe(int timePerItem, ItemStack[] resources, FluidStack liquid) { + addRecipe(timePerItem, resources, liquid, null, 0); + } + + public static Recipe findMatchingRecipe(ItemStack[] items) { + for (int i = 0; i < recipes.size(); i++) { + Recipe recipe = recipes.get(i); + if (recipe.matches(items)) + return recipe; + } + + return null; + } + + @Override + public Map getRecipes() { + HashMap recipeList = new HashMap(); + + for (Recipe recipe : recipes) + recipeList.put(recipe.resources, new Object[] { recipe.remnants, recipe.liquid }); + + return recipeList; + } + } + + /* MEMBER */ + @EntityNetData + public ForestryTank productTank = new ForestryTank(Defaults.PROCESSOR_TANK_CAPACITY); + + private final InventoryAdapter inventory = new InventoryAdapter(12, "Items"); + private Recipe currentRecipe; + + private final Stack pendingLiquids = new Stack(); + private final Stack pendingRemnants = new Stack(); + private int productionTime; + private int timePerItem; + + public MachineSqueezer() { + setHints(Config.hints.get("squeezer")); + } + + @Override + public String getInventoryName() { + return "factory.5"; + } + + @Override + public void openGui(EntityPlayer player, TileBase tile) { + player.openGui(ForestryAPI.instance, GuiId.SqueezerGUI.ordinal(), player.worldObj, xCoord, yCoord, zCoord); + } + + @Override + protected void configurePowerProvider(PowerHandler provider) { + provider.configure(50, 110, 5, 400); + } + + /* LOADING & SAVING */ + @Override + public void writeToNBT(NBTTagCompound nbttagcompound) { + super.writeToNBT(nbttagcompound); + + nbttagcompound.setInteger("ProductionTime", productionTime); + nbttagcompound.setInteger("TimePerItem", timePerItem); + + // Inventory + inventory.writeToNBT(nbttagcompound); + + // Pending remnants + NBTTagList nbttaglist = new NBTTagList(); + ItemStack[] remnants = pendingRemnants.toArray(new ItemStack[pendingRemnants.size()]); + for (int i = 0; i < remnants.length; i++) + if (remnants[i] != null) { + NBTTagCompound nbttagcompound1 = new NBTTagCompound(); + nbttagcompound1.setByte("Slot", (byte) i); + remnants[i].writeToNBT(nbttagcompound1); + nbttaglist.appendTag(nbttagcompound1); + } + nbttagcompound.setTag("PendingRemnants", nbttaglist); + + // Pending liquids + nbttaglist = new NBTTagList(); + FluidStack[] liquids = pendingLiquids.toArray(new FluidStack[pendingLiquids.size()]); + for (int i = 0; i < liquids.length; i++) + if (liquids[i] != null) { + NBTTagCompound nbttagcompound1 = new NBTTagCompound(); + nbttagcompound1.setByte("Slot", (byte) i); + liquids[i].writeToNBT(nbttagcompound1); + nbttaglist.appendTag(nbttagcompound1); + } + nbttagcompound.setTag("PendingLiquids", nbttaglist); + + // ProductTank + NBTTagCompound NBTproductSlot = new NBTTagCompound(); + productTank.writeToNBT(NBTproductSlot); + nbttagcompound.setTag("ProductTank", NBTproductSlot); + } + + @Override + public void readFromNBT(NBTTagCompound nbttagcompound) { + super.readFromNBT(nbttagcompound); + + productionTime = nbttagcompound.getInteger("ProductionTime"); + timePerItem = nbttagcompound.getInteger("TimePerItem"); + + // Inventory + inventory.readFromNBT(nbttagcompound); + + // Pending remnants + NBTTagList nbttaglist = nbttagcompound.getTagList("PendingRemnants", 10); + for (int i = 0; i < nbttaglist.tagCount(); i++) { + NBTTagCompound nbttagcompound1 = nbttaglist.getCompoundTagAt(i); + pendingRemnants.add(ItemStack.loadItemStackFromNBT(nbttagcompound1)); + } + + // Pending liquids + nbttaglist = nbttagcompound.getTagList("PendingLiquids", 10); + for (int i = 0; i < nbttaglist.tagCount(); i++) { + NBTTagCompound nbttagcompound1 = nbttaglist.getCompoundTagAt(i); + pendingLiquids.add(FluidStack.loadFluidStackFromNBT(nbttagcompound1)); + } + + // Product tank + productTank = new ForestryTank(Defaults.PROCESSOR_TANK_CAPACITY); + if (nbttagcompound.hasKey("ProductTank")) + productTank.readFromNBT(nbttagcompound.getCompoundTag("ProductTank")); + + checkRecipe(); + } + + // / WORKING + @Override + public void updateServerSide() { + + // Can/capsule input/output needs to be handled here. + if (inventory.getStackInSlot(SLOT_CAN_INPUT) != null) { + + FluidContainerData container = LiquidHelper.getEmptyContainer(inventory.getStackInSlot(SLOT_CAN_INPUT), productTank.getFluid()); + if (container != null) { + inventory.setInventorySlotContents(SLOT_CAN_OUTPUT, bottleIntoContainer(inventory.getStackInSlot(SLOT_CAN_INPUT), inventory.getStackInSlot(SLOT_CAN_OUTPUT), container, productTank)); + if (inventory.getStackInSlot(SLOT_CAN_INPUT).stackSize <= 0) + inventory.setInventorySlotContents(SLOT_CAN_INPUT, null); + } + + } + + if (worldObj.getTotalWorldTime() % 20 * 10 != 0) + return; + + checkRecipe(); + if (getErrorState() == EnumErrorCode.NORECIPE && currentRecipe != null) + setErrorState(EnumErrorCode.OK); + + } + + @Override + public boolean workCycle() { + + checkRecipe(); + + // If we add pending products, we skip to the next work cycle. + tryAddPending(); + + if (!pendingLiquids.isEmpty() || !pendingRemnants.isEmpty()) + return false; + + // Continue work if nothing needs to be added + if (productionTime <= 0) + return false; + + if (currentRecipe == null) + return false; + + productionTime--; + // Still not done, return + if (productionTime > 0) { + setErrorState(EnumErrorCode.OK); + return true; + } + + // We are done, add products to queue + pendingLiquids.push(currentRecipe.liquid.copy()); + if (currentRecipe.remnants != null && worldObj.rand.nextInt(100) < currentRecipe.chance) + pendingRemnants.push(currentRecipe.remnants.copy()); + + removeResources(currentRecipe.resources); + + checkRecipe(); + resetRecipe(); + + tryAddPending(); + setErrorState(EnumErrorCode.OK); + + return true; + } + + private void checkRecipe() { + Recipe sameRec = RecipeManager.findMatchingRecipe(inventory.getStacks(SLOT_RESOURCE_1, 9)); + + if (sameRec == null) + setErrorState(EnumErrorCode.NORECIPE); + + if (currentRecipe != sameRec) { + currentRecipe = sameRec; + resetRecipe(); + } + } + + private void resetRecipe() { + if (currentRecipe == null) { + productionTime = 0; + timePerItem = 0; + return; + } + + productionTime = currentRecipe.timePerItem; + timePerItem = currentRecipe.timePerItem; + } + + private boolean tryAddPending() { + + if (!pendingLiquids.isEmpty()) { + FluidStack next = pendingLiquids.peek(); + if (addProduct(next)) { + pendingLiquids.pop(); + return true; + } + } + + if (!pendingRemnants.isEmpty()) { + ItemStack next = pendingRemnants.peek(); + if (addRemnant(next)) { + pendingRemnants.pop(); + return true; + } + } + + if (!pendingLiquids.isEmpty() || !pendingRemnants.isEmpty()) + setErrorState(EnumErrorCode.NOSPACE); + return false; + } + + private boolean addProduct(FluidStack stack) { + stack.amount -= productTank.fill(stack, true); + + if (stack.amount <= 0) + return true; + else + return false; + } + + private boolean addRemnant(ItemStack stack) { + return inventory.tryAddStack(stack, SLOT_REMNANT, 1, true); + } + + private void removeResources(ItemStack[] stacks) { + inventory.removeResources(stacks, SLOT_RESOURCE_1, SLOTS_RESOURCE_COUNT); + } + + @Override + public boolean isWorking() { + return currentRecipe != null && productTank.getFluidAmount() < productTank.getCapacity(); + } + + @Override + public boolean hasWork() { + return currentRecipe != null && productTank.getFluidAmount() < productTank.getCapacity(); + } + + public int getProgressScaled(int i) { + if (timePerItem == 0) + return i; + + return (productionTime * i) / timePerItem; + } + + public int getResourceScaled(int i) { + return (productTank.getFluidAmount() * i) / Defaults.PROCESSOR_TANK_CAPACITY; + } + + @Override + public EnumTankLevel getSecondaryLevel() { + return Utils.rateTankLevel(getResourceScaled(100)); + } + + /* SMP GUI */ + public void getGUINetworkData(int i, int j) { + switch (i) { + case 0: + productionTime = j; + break; + case 1: + timePerItem = j; + break; + } + } + + public void sendGUINetworkData(Container container, ICrafting iCrafting) { + iCrafting.sendProgressBarUpdate(container, 0, productionTime); + iCrafting.sendProgressBarUpdate(container, 1, timePerItem); + } + + /* IINVENTORY */ + @Override public int getSizeInventory() { return inventory.getSizeInventory(); } + @Override public ItemStack getStackInSlot(int i) { return inventory.getStackInSlot(i); } + @Override public ItemStack decrStackSize(int i, int j) { return inventory.decrStackSize(i, j); } + @Override public void setInventorySlotContents(int i, ItemStack itemstack) { inventory.setInventorySlotContents(i, itemstack); } + @Override public ItemStack getStackInSlotOnClosing(int slot) { return inventory.getStackInSlotOnClosing(slot); } + @Override public int getInventoryStackLimit() { return inventory.getInventoryStackLimit(); } + @Override public void openInventory() {} + @Override public void closeInventory() {} + + /** + * TODO: just a specialsource workaround + */ + @Override + public boolean isUseableByPlayer(EntityPlayer player) { + return super.isUseableByPlayer(player); + } + + /** + * TODO: just a specialsource workaround + */ + @Override + public boolean hasCustomInventoryName() { + return super.hasCustomInventoryName(); + } + + /** + * TODO: just a specialsource workaround + */ + @Override + public boolean isItemValidForSlot(int slotIndex, ItemStack itemstack) { + return super.isItemValidForSlot(slotIndex, itemstack); + } + + /** + * TODO: just a specialsource workaround + */ + @Override + public boolean canInsertItem(int i, ItemStack itemstack, int j) { + return super.canInsertItem(i, itemstack, j); + } + + /** + * TODO: just a specialsource workaround + */ + @Override + public boolean canExtractItem(int i, ItemStack itemstack, int j) { + return super.canExtractItem(i, itemstack, j); + } + + /** + * TODO: just a specialsource workaround + */ + @Override + public int[] getAccessibleSlotsFromSide(int side) { + return super.getAccessibleSlotsFromSide(side); + } + + /* ISIDEDINVENTORY */ + @Override + public InventoryAdapter getInternalInventory() { + return inventory; + } + + @Override + protected boolean canTakeStackFromSide(int slotIndex, ItemStack itemstack, int side) { + + if(!super.canTakeStackFromSide(slotIndex, itemstack, side)) + return false; + + return slotIndex == SLOT_REMNANT || slotIndex == SLOT_CAN_OUTPUT; + } + + + @Override + protected boolean canPutStackFromSide(int slotIndex, ItemStack itemstack, int side) { + + if(!super.canPutStackFromSide(slotIndex, itemstack, side)) + return false; + + if(slotIndex == SLOT_CAN_INPUT) { + return LiquidHelper.isEmptyContainer(itemstack); + } + + if(slotIndex >= SLOT_RESOURCE_1 && slotIndex < SLOT_RESOURCE_1 + SLOTS_RESOURCE_COUNT) { + return !LiquidHelper.isEmptyContainer(itemstack); + } + + return false; + } + /* ISPECIALINVENTORY */ + @Override + public int addItem(ItemStack stack, boolean doAdd, ForgeDirection from) { + + // Try to add to can slot if input is from top or bottom. + if (LiquidHelper.isEmptyContainer(stack)) { + return inventory.addStack(stack, SLOT_CAN_INPUT, 1, false, doAdd); + } else { + return inventory.addStack(stack, SLOT_RESOURCE_1, SLOTS_RESOURCE_COUNT, false, doAdd); + } + } + + @Override + public ItemStack[] extractItem(boolean doRemove, ForgeDirection from, int maxItemCount) { + ItemStack product; + + if (inventory.getStackInSlot(SLOT_CAN_OUTPUT) != null) { + + product = new ItemStack(inventory.getStackInSlot(SLOT_CAN_OUTPUT).getItem(), 1, inventory.getStackInSlot(SLOT_CAN_OUTPUT).getItemDamage()); + if (doRemove) { + inventory.decrStackSize(SLOT_CAN_OUTPUT, 1); + } + return new ItemStack[] { product }; + } else { + + if (inventory.getStackInSlot(SLOT_REMNANT) == null) + return StackUtils.EMPTY_STACK_ARRAY; + + product = new ItemStack(inventory.getStackInSlot(SLOT_REMNANT).getItem(), 1, inventory.getStackInSlot(SLOT_REMNANT).getItemDamage()); + if (doRemove) { + inventory.decrStackSize(SLOT_REMNANT, 1); + } + return new ItemStack[] { product }; + } + + } + + /* ILIQUIDCONTAINER IMPLEMENTATION */ + @Override + public FluidStack drain(ForgeDirection from, int quantityMax, boolean doEmpty) { + return productTank.drain(quantityMax, doEmpty); + } + + @Override + public ForestryTank[] getTanks() { + return new ForestryTank[] { productTank }; + } + + /* ITRIGGERPROVIDER */ + @Override + public LinkedList getCustomTriggers() { + LinkedList res = new LinkedList(); + res.add(ForestryTrigger.hasWork); + return res; + } + +} diff --git a/forestry_common/factory/forestry/factory/gadgets/MachineStill.java b/forestry_common/factory/forestry/factory/gadgets/MachineStill.java new file mode 100755 index 000000000..00b9d33bd --- /dev/null +++ b/forestry_common/factory/forestry/factory/gadgets/MachineStill.java @@ -0,0 +1,495 @@ +/******************************************************************************* + * Copyright 2011-2014 by SirSengir + * + * This work is licensed under a Creative Commons Attribution-NonCommercial-NoDerivs 3.0 Unported License. + * + * To view a copy of this license, visit http://creativecommons.org/licenses/by-nc-nd/3.0/. + ******************************************************************************/ +package forestry.factory.gadgets; + +import java.util.ArrayList; +import java.util.HashMap; +import java.util.LinkedList; +import java.util.Map; + +import net.minecraft.entity.player.EntityPlayer; +import net.minecraft.inventory.Container; +import net.minecraft.inventory.ICrafting; +import net.minecraft.inventory.ISidedInventory; +import net.minecraft.item.ItemStack; +import net.minecraft.nbt.NBTTagCompound; + +import net.minecraftforge.common.util.ForgeDirection; +import net.minecraftforge.fluids.FluidContainerRegistry.FluidContainerData; +import net.minecraftforge.fluids.FluidStack; + +import buildcraft.api.gates.ITrigger; +import buildcraft.api.inventory.ISpecialInventory; +import buildcraft.api.power.PowerHandler; + +import forestry.api.core.ForestryAPI; +import forestry.api.recipes.IStillManager; +import forestry.core.EnumErrorCode; +import forestry.core.config.Config; +import forestry.core.config.Defaults; +import forestry.core.gadgets.TileBase; +import forestry.core.gadgets.TilePowered; +import forestry.core.interfaces.ILiquidTankContainer; +import forestry.core.network.EntityNetData; +import forestry.core.network.GuiId; +import forestry.core.triggers.ForestryTrigger; +import forestry.core.utils.EnumTankLevel; +import forestry.core.utils.ForestryTank; +import forestry.core.utils.InventoryAdapter; +import forestry.core.utils.LiquidHelper; +import forestry.core.utils.StackUtils; +import forestry.core.utils.Utils; + +public class MachineStill extends TilePowered implements ISpecialInventory, ISidedInventory, ILiquidTankContainer { + + /* CONSTANTS */ + public static final short SLOT_PRODUCT = 0; + public static final short SLOT_RESOURCE = 1; + public static final short SLOT_CAN = 2; + + public static class Recipe { + public final int timePerUnit; + public final FluidStack input; + public final FluidStack output; + + public Recipe(int timePerUnit, FluidStack input, FluidStack output) { + this.timePerUnit = timePerUnit; + if(input == null) + throw new IllegalArgumentException("Still recipes need an input. Input was null."); + if(output == null) + throw new IllegalArgumentException("Still recipes need an output. Output was null."); + this.input = input; + this.output = output; + } + + public boolean matches(FluidStack res) { + if (res == null && input == null) + return true; + else if (res == null && input != null) + return false; + else if (res != null && input == null) + return false; + else + return input.isFluidEqual(res); + } + } + + public static class RecipeManager implements IStillManager { + public static ArrayList recipes = new ArrayList(); + + @Override + public void addRecipe(int timePerUnit, FluidStack input, FluidStack output) { + recipes.add(new MachineStill.Recipe(timePerUnit, input, output)); + } + + public static Recipe findMatchingRecipe(FluidStack item) { + for (int i = 0; i < recipes.size(); i++) { + Recipe recipe = recipes.get(i); + if (recipe.matches(item)) + return recipe; + } + return null; + } + + public static boolean isInput(FluidStack res) { + return findMatchingRecipe(res) != null; + } + + @Override + public Map getRecipes() { + HashMap recipeList = new HashMap(); + + for (Recipe recipe : recipes) + recipeList.put(new Object[] { recipe.input }, new Object[] { recipe.output }); + + return recipeList; + } + } + + /* MEMBER */ + @EntityNetData + public ForestryTank resourceTank = new ForestryTank(Defaults.PROCESSOR_TANK_CAPACITY); + @EntityNetData + public ForestryTank productTank = new ForestryTank(Defaults.PROCESSOR_TANK_CAPACITY); + + private final InventoryAdapter inventory = new InventoryAdapter(3, "Items"); + + private Recipe currentRecipe; + private FluidStack bufferedLiquid; + public int distillationTime = 0; + public int distillationTotalTime = 0; + + public MachineStill() { + setHints(Config.hints.get("still")); + } + + @Override + public String getInventoryName() { + return "factory.6"; + } + + @Override + public void openGui(EntityPlayer player, TileBase tile) { + player.openGui(ForestryAPI.instance, GuiId.StillGUI.ordinal(), player.worldObj, xCoord, yCoord, zCoord); + } + + @Override + protected void configurePowerProvider(PowerHandler provider) { + provider.configure(50, 110, 5, 800); + } + + @Override + public void writeToNBT(NBTTagCompound nbttagcompound) { + super.writeToNBT(nbttagcompound); + + nbttagcompound.setInteger("DistillationTime", distillationTime); + nbttagcompound.setInteger("DistillationTotalTime", distillationTotalTime); + + NBTTagCompound NBTresourceSlot = new NBTTagCompound(); + NBTTagCompound NBTproductSlot = new NBTTagCompound(); + + resourceTank.writeToNBT(NBTresourceSlot); + productTank.writeToNBT(NBTproductSlot); + + nbttagcompound.setTag("ResourceTank", NBTresourceSlot); + nbttagcompound.setTag("ProductTank", NBTproductSlot); + + inventory.writeToNBT(nbttagcompound); + } + + @Override + public void readFromNBT(NBTTagCompound nbttagcompound) { + super.readFromNBT(nbttagcompound); + + distillationTime = nbttagcompound.getInteger("DistillationTime"); + distillationTotalTime = nbttagcompound.getInteger("DistillationTotalTime"); + + resourceTank = new ForestryTank(Defaults.PROCESSOR_TANK_CAPACITY); + productTank = new ForestryTank(Defaults.PROCESSOR_TANK_CAPACITY); + if (nbttagcompound.hasKey("ResourceTank")) { + resourceTank.readFromNBT(nbttagcompound.getCompoundTag("ResourceTank")); + productTank.readFromNBT(nbttagcompound.getCompoundTag("ProductTank")); + } + + inventory.readFromNBT(nbttagcompound); + + checkRecipe(); + } + + @Override + public void updateServerSide() { + + // Check if we have suitable items waiting in the item slot + if (inventory.getStackInSlot(SLOT_CAN) != null) { + FluidContainerData container = LiquidHelper.getLiquidContainer(inventory.getStackInSlot(SLOT_CAN)); + + if (container != null && RecipeManager.isInput(container.fluid)) { + + inventory.setInventorySlotContents(SLOT_CAN, StackUtils.replenishByContainer(this, inventory.getStackInSlot(SLOT_CAN), container, resourceTank)); + if (inventory.getStackInSlot(SLOT_CAN).stackSize <= 0) + inventory.setInventorySlotContents(SLOT_CAN, null); + + } + } + + // Can product liquid if possible + if (inventory.getStackInSlot(SLOT_RESOURCE) != null) { + FluidContainerData container = LiquidHelper.getEmptyContainer(inventory.getStackInSlot(SLOT_RESOURCE), productTank.getFluid()); + if (container != null) { + inventory.setInventorySlotContents(SLOT_PRODUCT, bottleIntoContainer(inventory.getStackInSlot(SLOT_RESOURCE), inventory.getStackInSlot(SLOT_PRODUCT), container, productTank)); + if (inventory.getStackInSlot(SLOT_RESOURCE).stackSize <= 0) + inventory.setInventorySlotContents(SLOT_RESOURCE, null); + } + } + + if (worldObj.getTotalWorldTime() % 20 * 10 != 0) + return; + + checkRecipe(); + if (getErrorState() == EnumErrorCode.NORECIPE && currentRecipe != null) + setErrorState(EnumErrorCode.OK); + + } + + @Override + public boolean workCycle() { + + checkRecipe(); + + // Ongoing process + if (distillationTime > 0 && currentRecipe != null) { + + distillationTime -= currentRecipe.input.amount; + addProduct(currentRecipe.output.fluidID, currentRecipe.output.amount); + + setErrorState(EnumErrorCode.OK); + return true; + + } else if (currentRecipe != null && productTank.getFluidAmount() + currentRecipe.output.amount <= Defaults.PROCESSOR_TANK_CAPACITY) { + + int resReq = currentRecipe.timePerUnit * currentRecipe.input.amount; + // Start next cycle if enough bio mass is available + if (resourceTank.getFluidAmount() >= resReq) { + + distillationTime = distillationTotalTime = resReq; + resourceTank.drain(resReq, true); + bufferedLiquid = new FluidStack(currentRecipe.input.fluidID, resReq); + + setErrorState(EnumErrorCode.OK); + return true; + + } else + setErrorState(EnumErrorCode.NORESOURCE); + + } + + bufferedLiquid = null; + return false; + } + + private void addProduct(int id, int amount) { + + productTank.fill(new FluidStack(id, amount), true); + } + + public void checkRecipe() { + Recipe sameRec = RecipeManager.findMatchingRecipe(resourceTank.getFluid()); + + if (sameRec == null && bufferedLiquid != null && distillationTime > 0) + sameRec = RecipeManager.findMatchingRecipe(new FluidStack(bufferedLiquid.fluidID, distillationTime)); + + if (sameRec == null) + setErrorState(EnumErrorCode.NORECIPE); + + if (currentRecipe != sameRec) { + currentRecipe = sameRec; + resetRecipe(); + } + } + + private void resetRecipe() { + } + + @Override + public boolean isWorking() { + return distillationTime > 0 || currentRecipe != null && productTank.getFluidAmount() + currentRecipe.output.amount <= Defaults.PROCESSOR_TANK_CAPACITY; + } + + @Override + public boolean hasWork() { + if (currentRecipe == null) + return false; + + return (distillationTime > 0 || resourceTank.getFluidAmount() >= currentRecipe.timePerUnit * currentRecipe.input.amount) + && productTank.getFluidAmount() <= productTank.getCapacity() - currentRecipe.output.amount; + } + + public int getDistillationProgressScaled(int i) { + if (distillationTotalTime == 0) + return i; + + return (distillationTime * i) / distillationTotalTime; + } + + public int getResourceScaled(int i) { + return (resourceTank.getFluidAmount() * i) / Defaults.PROCESSOR_TANK_CAPACITY; + } + + public int getProductScaled(int i) { + return (productTank.getFluidAmount() * i) / Defaults.PROCESSOR_TANK_CAPACITY; + } + + @Override + public EnumTankLevel getPrimaryLevel() { + return Utils.rateTankLevel(getResourceScaled(100)); + } + + @Override + public EnumTankLevel getSecondaryLevel() { + return Utils.rateTankLevel(getProductScaled(100)); + } + + /* SMP GUI */ + public void getGUINetworkData(int i, int j) { + + switch (i) { + case 0: + distillationTime = j; + break; + case 1: + distillationTotalTime = j; + break; + } + } + + public void sendGUINetworkData(Container container, ICrafting iCrafting) { + iCrafting.sendProgressBarUpdate(container, 0, distillationTime); + iCrafting.sendProgressBarUpdate(container, 1, distillationTotalTime); + } + + /* ISPECIALINVENTORY */ + @Override + public int addItem(ItemStack stack, boolean doAdd, ForgeDirection from) { + int inventorySlot; + + FluidContainerData container = LiquidHelper.getLiquidContainer(stack); + if (container != null && RecipeManager.isInput(container.fluid)) + inventorySlot = SLOT_CAN; + else if (LiquidHelper.isEmptyContainer(stack)) + inventorySlot = SLOT_RESOURCE; + else + return 0; + + return inventory.addStack(stack, inventorySlot, 1, false, doAdd); + } + + /** + * Transport pipes cannot extract items from the still. + */ + @Override + public ItemStack[] extractItem(boolean doRemove, ForgeDirection from, int maxItemCount) { + ItemStack product = null; + + if (inventory.getStackInSlot(SLOT_PRODUCT) != null) { + + product = new ItemStack(inventory.getStackInSlot(SLOT_PRODUCT).getItem(), 1, inventory.getStackInSlot(SLOT_PRODUCT).getItemDamage()); + if (doRemove) { + inventory.decrStackSize(SLOT_PRODUCT, 1); + } + } + + if (product != null) + return new ItemStack[] { product }; + else + return StackUtils.EMPTY_STACK_ARRAY; + } + + /* IINVENTORY */ + @Override public int getSizeInventory() { return inventory.getSizeInventory(); } + @Override public ItemStack getStackInSlot(int i) { return inventory.getStackInSlot(i); } + @Override public ItemStack decrStackSize(int i, int j) { return inventory.decrStackSize(i, j); } + @Override public void setInventorySlotContents(int i, ItemStack itemstack) { inventory.setInventorySlotContents(i, itemstack); } + @Override public ItemStack getStackInSlotOnClosing(int slot) { return inventory.getStackInSlotOnClosing(slot); } + @Override public int getInventoryStackLimit() { return inventory.getInventoryStackLimit(); } + @Override public void openInventory() {} + @Override public void closeInventory() {} + + /** + * TODO: just a specialsource workaround + */ + @Override + public boolean isUseableByPlayer(EntityPlayer player) { + return super.isUseableByPlayer(player); + } + + /** + * TODO: just a specialsource workaround + */ + @Override + public boolean hasCustomInventoryName() { + return super.hasCustomInventoryName(); + } + + /** + * TODO: just a specialsource workaround + */ + @Override + public boolean isItemValidForSlot(int slotIndex, ItemStack itemstack) { + return super.isItemValidForSlot(slotIndex, itemstack); + } + + /** + * TODO: just a specialsource workaround + */ + @Override + public boolean canInsertItem(int i, ItemStack itemstack, int j) { + return super.canInsertItem(i, itemstack, j); + } + + /** + * TODO: just a specialsource workaround + */ + @Override + public boolean canExtractItem(int i, ItemStack itemstack, int j) { + return super.canExtractItem(i, itemstack, j); + } + + /** + * TODO: just a specialsource workaround + */ + @Override + public int[] getAccessibleSlotsFromSide(int side) { + return super.getAccessibleSlotsFromSide(side); + } + + /* ISIDEDINVENTORY */ + @Override + public InventoryAdapter getInternalInventory() { + return inventory; + } + + @Override + protected boolean canTakeStackFromSide(int slotIndex, ItemStack itemstack, int side) { + + if(!super.canTakeStackFromSide(slotIndex, itemstack, side)) + return false; + + return slotIndex == SLOT_PRODUCT; + } + + @Override + protected boolean canPutStackFromSide(int slotIndex, ItemStack itemstack, int side) { + + if(!super.canPutStackFromSide(slotIndex, itemstack, side)) + return false; + + if(slotIndex == SLOT_RESOURCE) + return LiquidHelper.isEmptyContainer(itemstack); + + if(slotIndex == SLOT_CAN) { + FluidContainerData container = LiquidHelper.getLiquidContainer(itemstack); + return container != null && RecipeManager.isInput(container.fluid); + } + + return false; + } + + /* ILIQUIDCONTAINER */ + @Override + public int fill(ForgeDirection from, FluidStack resource, boolean doFill) { + + if (!MachineStill.RecipeManager.isInput(resource)) + return 0; + + int used = resourceTank.fill(resource, doFill); + + if (doFill && used > 0) + sendNetworkUpdate(); + + return used; + } + + @Override + public FluidStack drain(ForgeDirection from, int quantityMax, boolean doEmpty) { + return productTank.drain(quantityMax, doEmpty); + } + + @Override + public ForestryTank[] getTanks() { + return new ForestryTank[] { resourceTank, productTank }; + } + + /* ITRIGGERPROVIDER */ + @Override + public LinkedList getCustomTriggers() { + LinkedList res = new LinkedList(); + res.add(ForestryTrigger.hasWork); + return res; + } + +} diff --git a/forestry_common/factory/forestry/factory/gadgets/MillRainmaker.java b/forestry_common/factory/forestry/factory/gadgets/MillRainmaker.java new file mode 100755 index 000000000..39469dddd --- /dev/null +++ b/forestry_common/factory/forestry/factory/gadgets/MillRainmaker.java @@ -0,0 +1,205 @@ +/******************************************************************************* + * Copyright 2011-2014 by SirSengir + * + * This work is licensed under a Creative Commons Attribution-NonCommercial-NoDerivs 3.0 Unported License. + * + * To view a copy of this license, visit http://creativecommons.org/licenses/by-nc-nd/3.0/. + ******************************************************************************/ +package forestry.factory.gadgets; + +import net.minecraft.entity.player.EntityPlayer; +import net.minecraft.item.ItemStack; +import net.minecraft.nbt.NBTTagCompound; + +import net.minecraftforge.common.util.ForgeDirection; + +import buildcraft.api.inventory.ISpecialInventory; + +import forestry.api.fuels.FuelManager; +import forestry.api.fuels.RainSubstrate; +import forestry.core.gadgets.Mill; +import forestry.core.gadgets.TileBase; +import forestry.core.proxy.Proxies; + +public class MillRainmaker extends Mill implements ISpecialInventory { + + private int duration; + private boolean reverse; + + public MillRainmaker() { + speed = 0.01f; + } + + @Override + public String getInventoryName() { + return "Rainmaker"; + } + + @Override + public void openGui(EntityPlayer player, TileBase tile) { + if (!Proxies.common.isSimulating(player.worldObj)) + return; + + if (player.inventory.getCurrentItem() == null) + return; + + // We don't have a gui, but we can be activated + if (FuelManager.rainSubstrate.containsKey(player.inventory.getCurrentItem()) && charge == 0) { + RainSubstrate substrate = FuelManager.rainSubstrate.get(player.inventory.getCurrentItem()); + if (substrate.item.isItemEqual(player.inventory.getCurrentItem())) { + addCharge(substrate); + player.inventory.getCurrentItem().stackSize--; + } + } + sendNetworkUpdate(); + } + + @Override + public void readFromNBT(NBTTagCompound nbttagcompound) { + super.readFromNBT(nbttagcompound); + + charge = nbttagcompound.getInteger("Charge"); + progress = nbttagcompound.getFloat("Progress"); + stage = nbttagcompound.getInteger("Stage"); + duration = nbttagcompound.getInteger("Duration"); + reverse = nbttagcompound.getBoolean("Reverse"); + } + + @Override + public void writeToNBT(NBTTagCompound nbttagcompound) { + super.writeToNBT(nbttagcompound); + + nbttagcompound.setInteger("Charge", charge); + nbttagcompound.setFloat("Progress", progress); + nbttagcompound.setInteger("Stage", stage); + nbttagcompound.setInteger("Duration", duration); + nbttagcompound.setBoolean("Reverse", reverse); + } + + public void addCharge(RainSubstrate substrate) { + charge = 1; + speed = substrate.speed; + duration = substrate.duration; + reverse = substrate.reverse; + } + + @Override + public void activate() { + if (Proxies.render.hasRendering()) { + worldObj.playSoundEffect(xCoord, yCoord, zCoord, "ambient.weather.thunder", 4F, + (1.0F + (worldObj.rand.nextFloat() - worldObj.rand.nextFloat()) * 0.2F) * 0.7F); + + float f = xCoord + 0.5F; + float f1 = yCoord + 0.0F + (worldObj.rand.nextFloat() * 6F) / 16F; + float f2 = zCoord + 0.5F; + float f3 = 0.52F; + float f4 = worldObj.rand.nextFloat() * 0.6F - 0.3F; + + Proxies.common.addEntityExplodeFX(worldObj, (f - f3), f1, (f2 + f4), 0F, 0F, 0F); + Proxies.common.addEntityExplodeFX(worldObj, (f + f3), f1, (f2 + f4), 0F, 0F, 0F); + Proxies.common.addEntityExplodeFX(worldObj, (f + f4), f1, (f2 - f3), 0F, 0F, 0F); + Proxies.common.addEntityExplodeFX(worldObj, (f + f4), f1, (f2 + f3), 0F, 0F, 0F); + } + + if (Proxies.common.isSimulating(worldObj)) { + if (reverse) + worldObj.getWorldInfo().setRaining(false); + else { + worldObj.getWorldInfo().setRaining(true); + worldObj.getWorldInfo().setRainTime(duration); + } + charge = 0; + duration = 0; + reverse = false; + sendNetworkUpdate(); + } + } + + @Override + public boolean workCycle() { + return false; + } + + @Override + public int addItem(ItemStack stack, boolean doAdd, ForgeDirection from) { + if (charge != 0) + return 0; + + if (!FuelManager.rainSubstrate.containsKey(stack)) + return 0; + + RainSubstrate substrate = FuelManager.rainSubstrate.get(stack); + if (!substrate.item.isItemEqual(stack)) + return 0; + + if (doAdd) + addCharge(substrate); + return 1; + } + + @Override + public ItemStack[] extractItem(boolean doRemove, ForgeDirection from, int maxItemCount) { + return null; + } + + @Override + public int getSizeInventory() { + return 0; + } + + @Override + public ItemStack getStackInSlot(int var1) { + return null; + } + + @Override + public ItemStack decrStackSize(int var1, int var2) { + return null; + } + + @Override + public ItemStack getStackInSlotOnClosing(int var1) { + return null; + } + + @Override + public void setInventorySlotContents(int var1, ItemStack var2) { + } + + @Override + public int getInventoryStackLimit() { + return 0; + } + + @Override + public void openInventory() { + } + + @Override + public void closeInventory() { + } + + /** + * TODO: just a specialsource workaround + */ + @Override + public boolean isUseableByPlayer(EntityPlayer player) { + return super.isUseableByPlayer(player); + } + + /** + * TODO: just a specialsource workaround + */ + @Override + public boolean hasCustomInventoryName() { + return super.hasCustomInventoryName(); + } + + /** + * TODO: just a specialsource workaround + */ + @Override + public boolean isItemValidForSlot(int slotIndex, ItemStack itemstack) { + return super.isItemValidForSlot(slotIndex, itemstack); + } +} diff --git a/forestry_common/factory/forestry/factory/gadgets/TileWorktable.java b/forestry_common/factory/forestry/factory/gadgets/TileWorktable.java new file mode 100755 index 000000000..21953c97e --- /dev/null +++ b/forestry_common/factory/forestry/factory/gadgets/TileWorktable.java @@ -0,0 +1,539 @@ +/******************************************************************************* + * Copyright 2011-2014 by SirSengir + * + * This work is licensed under a Creative Commons Attribution-NonCommercial-NoDerivs 3.0 Unported License. + * + * To view a copy of this license, visit http://creativecommons.org/licenses/by-nc-nd/3.0/. + ******************************************************************************/ +package forestry.factory.gadgets; + +import java.util.LinkedList; + +import net.minecraft.entity.player.EntityPlayer; +import net.minecraft.inventory.Container; +import net.minecraft.inventory.IInventory; +import net.minecraft.inventory.InventoryCrafting; +import net.minecraft.item.ItemStack; +import net.minecraft.item.crafting.CraftingManager; +import net.minecraft.item.crafting.IRecipe; +import net.minecraft.nbt.NBTTagCompound; +import net.minecraft.nbt.NBTTagList; +import net.minecraft.world.World; + +import forestry.api.core.ForestryAPI; +import forestry.api.core.INBTTagable; +import forestry.core.gadgets.TileBase; +import forestry.core.gui.ContainerDummy; +import forestry.core.interfaces.ICrafter; +import forestry.core.network.ForestryPacket; +import forestry.core.network.GuiId; +import forestry.core.network.PacketIds; +import forestry.core.network.PacketTileNBT; +import forestry.core.network.PacketTileUpdate; +import forestry.core.proxy.Proxies; +import forestry.core.utils.InventoryAdapter; +import forestry.core.utils.PlainInventory; +import forestry.core.utils.StackUtils; +import forestry.core.utils.TileInventoryAdapter; + +public class TileWorktable extends TileBase implements ICrafter { + + /* CONSTANTS */ + public final static int SLOT_CRAFTING_1 = 0; + public final static int SLOT_CRAFTING_RESULT = 9; + public final static short SLOT_INVENTORY_1 = 0; + public final static short SLOT_INVENTORY_COUNT = 18; + private final static Container DUMMY_CONTAINER = new ContainerDummy(); + private final static RecipeBridge RECIPE_BRIDGE = new RecipeBridge(); + + private static class RecipeBridge { + + private final LinkedList overrides = new LinkedList(); + + public IRecipe getRecipe(InventoryCrafting crafting, World world) { + for (IRecipe recipe : overrides) { + if (recipe.matches(crafting, world)) + return recipe; + } + + for (Object obj : CraftingManager.getInstance().getRecipeList()) { + IRecipe recipe = (IRecipe) obj; + if (recipe.matches(crafting, world)) + return recipe; + } + + return null; + } + } + + /* RECIPE MEMORY */ + public static final class Recipe implements IRecipe, INBTTagable { + + private InventoryAdapter matrix; + private long lastUsed; + private boolean locked; + private World cachedWorld; + private IRecipe cachedRecipe; + + public Recipe(InventoryCrafting crafting) { + this.matrix = new InventoryAdapter(new PlainInventory(crafting)); + } + + public Recipe(NBTTagCompound nbttagcompound) { + readFromNBT(nbttagcompound); + } + + public void setCacheWorld(World world) { + this.cachedWorld = world; + } + + private boolean updateCachedIRecipe() { + + if (cachedRecipe != null) + return true; + + InventoryCrafting crafting = new InventoryCrafting(DUMMY_CONTAINER, 3, 3); + for (int i = 0; i < crafting.getSizeInventory(); i++) { + crafting.setInventorySlotContents(i, matrix.getStackInSlot(i)); + } + + cachedRecipe = RECIPE_BRIDGE.getRecipe(crafting, cachedWorld); + return cachedRecipe != null; + } + + public void updateLastUse(World world) { + lastUsed = world.getTotalWorldTime(); + setCacheWorld(world); + } + + public void toogleLock() { + locked = !locked; + } + + public InventoryAdapter getMatrix() { + return matrix; + } + + @Override + public ItemStack getCraftingResult(InventoryCrafting inventorycrafting) { + if (updateCachedIRecipe()) + return cachedRecipe.getRecipeOutput(); + + return null; + } + + @Override + public ItemStack getRecipeOutput() { + if (updateCachedIRecipe()) + return cachedRecipe.getRecipeOutput(); + + return null; + } + + public long getLastUsed() { + return this.lastUsed; + } + + public boolean isLocked() { + return this.locked; + } + + @Override + public int getRecipeSize() { + return matrix.getSizeInventory(); + } + + @Override + public boolean matches(InventoryCrafting crafting, World world) { + if (crafting.getSizeInventory() != matrix.getSizeInventory()) + return false; + + if (!updateCachedIRecipe()) + return false; + + return cachedRecipe.matches(crafting, world); + } + + @Override + public final void readFromNBT(NBTTagCompound nbttagcompound) { + matrix = new InventoryAdapter(new InventoryCrafting(DUMMY_CONTAINER, 3, 3)); + matrix.readFromNBT(nbttagcompound); + sanitizeMatrix(); + lastUsed = nbttagcompound.getLong("LastUsed"); + locked = nbttagcompound.getBoolean("Locked"); + } + + @Override + public void writeToNBT(NBTTagCompound nbttagcompound) { + sanitizeMatrix(); + matrix.writeToNBT(nbttagcompound); + nbttagcompound.setLong("LastUsed", lastUsed); + nbttagcompound.setBoolean("Locked", locked); + } + + /** + * This is a nasty hack to hide a bug where the recipe stacks somehow + * get the stackSize set to -1. Which makes the recipe no longer work, + * ever. I've seen the bug, even inspected the NBT data of an afflicted + * worktable, but can't duplicate it, and can't trace it. -CovertJaguar + */ + private void sanitizeMatrix() { + for (int slot = 0; slot < matrix.getSizeInventory(); slot++) { + ItemStack stack = matrix.getStackInSlot(slot); + if (stack != null) + stack.stackSize = 1; + } + } + } + + public static class RecipeMemory implements INBTTagable, IInventory { + + private LinkedList recipes = new LinkedList(); + private long lastUpdate; + + public long getLastUpdate() { + return lastUpdate; + } + + public Recipe getOrCreateRecipe(World world, InventoryCrafting crafting) { + + Recipe memory = getMemorized(crafting, world); + if (memory != null) { + return memory; + } + + return new Recipe(crafting); + } + + public void memorizeRecipe(World world, Recipe recipe) { + + lastUpdate = world.getTotalWorldTime(); + recipe.updateLastUse(world); + + if (recipes.contains(recipe)) + return; + if (recipes.size() < 8) { + recipes.add(recipe); + return; + } + + Recipe oldest = null; + for (Recipe existing : recipes) { + if (oldest != null && oldest.getLastUsed() < existing.getLastUsed()) + continue; + if (existing.isLocked()) + continue; + + oldest = existing; + } + if (oldest != null) { + recipes.remove(oldest); + recipes.add(recipe); + } + + } + + public Recipe getRecipe(int recipeIndex) { + if (recipes.size() > recipeIndex) + return recipes.get(recipeIndex); + + return null; + } + + public ItemStack getRecipeOutput(int recipeIndex) { + if (recipes.size() > recipeIndex) + return recipes.get(recipeIndex).getRecipeOutput(); + else + return null; + } + + public boolean isLocked(int recipeIndex) { + if (recipes.size() > recipeIndex) + return recipes.get(recipeIndex).isLocked(); + + return false; + } + + public void toggleLock(World world, int recipeIndex) { + lastUpdate = world.getTotalWorldTime(); + if (recipes.size() > recipeIndex) + recipes.get(recipeIndex).toogleLock(); + } + + private Recipe getMemorized(InventoryCrafting crafting, World world) { + for (Recipe recipe : recipes) { + if (recipe.matches(crafting, world)) + return recipe; + } + + return null; + } + + @Override + public void readFromNBT(NBTTagCompound nbttagcompound) { + recipes = new LinkedList(); + if (!nbttagcompound.hasKey("RecipeMemory")) + return; + + NBTTagList nbttaglist = nbttagcompound.getTagList("RecipeMemory", 10); + for (int j = 0; j < nbttaglist.tagCount(); ++j) { + NBTTagCompound nbttagcompound2 = nbttaglist.getCompoundTagAt(j); + recipes.add(new Recipe(nbttagcompound2)); + } + } + + @Override + public void writeToNBT(NBTTagCompound nbttagcompound) { + NBTTagList nbttaglist = new NBTTagList(); + for (int i = 0; i < recipes.size(); i++) { + if (recipes.get(i) != null) { + NBTTagCompound nbttagcompound2 = new NBTTagCompound(); + recipes.get(i).writeToNBT(nbttagcompound2); + nbttaglist.appendTag(nbttagcompound2); + } + } + nbttagcompound.setTag("RecipeMemory", nbttaglist); + } + + @Override + public int getSizeInventory() { + return recipes.size(); + } + + @Override + public ItemStack getStackInSlot(int i) { + return getRecipeOutput(i); + } + + @Override + public ItemStack decrStackSize(int i, int j) { + return null; + } + + @Override + public ItemStack getStackInSlotOnClosing(int i) { + return null; + } + + @Override + public void setInventorySlotContents(int i, ItemStack itemstack) { + } + + @Override + public String getInventoryName() { + return ""; + } + + @Override + public boolean hasCustomInventoryName() { + return false; + } + + @Override + public int getInventoryStackLimit() { + return 64; + } + + @Override + public void markDirty() { + } + + @Override + public boolean isUseableByPlayer(EntityPlayer entityplayer) { + return true; + } + + @Override + public void openInventory() { + } + + @Override + public void closeInventory() { + } + + @Override + public boolean isItemValidForSlot(int i, ItemStack itemstack) { + return false; + } + } + /* MEMBERS */ + private Recipe currentRecipe; + private final RecipeMemory memorized; + private final TileInventoryAdapter craftingInventory; + private final TileInventoryAdapter accessibleInventory; + + public TileWorktable() { + craftingInventory = new TileInventoryAdapter(this, 10, "CraftItems"); + accessibleInventory = new TileInventoryAdapter(this, 18, "Items"); + + memorized = new RecipeMemory(); + } + + @Override + public String getInventoryName() { + return "factory2.2"; + } + + @Override + public void openGui(EntityPlayer player, TileBase tile) { + player.openGui(ForestryAPI.instance, GuiId.WorktableGUI.ordinal(), player.worldObj, xCoord, yCoord, zCoord); + } + + /* LOADING & SAVING */ + @Override + public void writeToNBT(NBTTagCompound nbttagcompound) { + super.writeToNBT(nbttagcompound); + + craftingInventory.writeToNBT(nbttagcompound); + accessibleInventory.writeToNBT(nbttagcompound); + + memorized.writeToNBT(nbttagcompound); + } + + @Override + public void readFromNBT(NBTTagCompound nbttagcompound) { + super.readFromNBT(nbttagcompound); + + craftingInventory.readFromNBT(nbttagcompound); + accessibleInventory.readFromNBT(nbttagcompound); + + memorized.readFromNBT(nbttagcompound); + } + + /* NETWORK */ + @Override + public void fromPacket(ForestryPacket packetRaw) { + if (packetRaw instanceof PacketTileUpdate) { + super.fromPacket(packetRaw); + return; + } + + PacketTileNBT packet = (PacketTileNBT) packetRaw; + readFromNBT(packet.getTagCompound()); + } + + public void sendAll(EntityPlayer player) { + Proxies.net.sendToPlayer(new PacketTileNBT(PacketIds.TILE_NBT, this), player); + } + + /* RECIPE SELECTION */ + public RecipeMemory getMemory() { + return memorized; + } + + public void chooseRecipe(int recipeIndex) { + if (recipeIndex == 9) { + for (int slot = 0; slot < craftingInventory.getSizeInventory(); slot++) { + craftingInventory.setInventorySlotContents(slot, null); + } + return; + } + + Recipe recipe = memorized.getRecipe(recipeIndex); + recipe.sanitizeMatrix(); + IInventory matrix = recipe.getMatrix(); + if (matrix == null) + return; + + for (int slot = 0; slot < matrix.getSizeInventory(); slot++) { + craftingInventory.setInventorySlotContents(slot, matrix.getStackInSlot(slot)); + } + } + + /* CRAFTING */ + public void setRecipe(InventoryCrafting crafting) { + + IRecipe recipe = RECIPE_BRIDGE.getRecipe(crafting, worldObj); + currentRecipe = recipe != null ? memorized.getOrCreateRecipe(worldObj, crafting) : null; + updateCraftResult(); + } + + private void updateCraftResult() { + if (currentRecipe != null) { + ItemStack result = currentRecipe.getCraftingResult(null); + if (result != null) { + craftingInventory.setInventorySlotContents(SLOT_CRAFTING_RESULT, result.copy()); + return; + } + } + + craftingInventory.setInventorySlotContents(SLOT_CRAFTING_RESULT, null); + } + + private boolean validateResources() { + // Need at least one matched set + if (currentRecipe == null) + return false; + return StackUtils.containsSets(currentRecipe.getMatrix().getStacks(SLOT_CRAFTING_1, 9), accessibleInventory.getStacks(SLOT_INVENTORY_1, SLOT_INVENTORY_COUNT), currentRecipe.getRecipeOutput(), true, true) > 0; + } + + private void removeResources(EntityPlayer player) { + removeSets(1, craftingInventory.getStacks(SLOT_CRAFTING_1, 9), player); + } + + private void removeSets(int count, ItemStack[] set, EntityPlayer player) { + + for (int i = 0; i < count; i++) { + ItemStack[] condensedSet = StackUtils.condenseStacks(set); + for (ItemStack req : condensedSet) { + for (int j = SLOT_INVENTORY_1; j < SLOT_INVENTORY_1 + SLOT_INVENTORY_COUNT; j++) { + ItemStack pol = accessibleInventory.getStackInSlot(j); + if (pol == null) + continue; + + if (!StackUtils.isCraftingEquivalent(pol, req, true, true)) + continue; + + ItemStack removed = accessibleInventory.decrStackSize(j, req.stackSize); + req.stackSize -= removed.stackSize; + + if (req.getItem().hasContainerItem(req)) + StackUtils.stowContainerItem(removed, accessibleInventory, j, player); + if (req.stackSize <= 0) + break; + } + } + } + + } + + @Override + public boolean canTakeStack(int slotIndex) { + return validateResources(); + } + + @Override + public ItemStack takenFromSlot(int slotIndex, boolean consumeRecipe, EntityPlayer player) { + if (!validateResources()) + return null; + + if (Proxies.common.isSimulating(worldObj)) + memorized.memorizeRecipe(worldObj, currentRecipe); + removeResources(player); + updateCraftResult(); + return currentRecipe.getRecipeOutput().copy(); + } + + @Override + public ItemStack getResult() { + if (currentRecipe == null) + return null; + + if (currentRecipe.getRecipeOutput() != null) + return currentRecipe.getRecipeOutput().copy(); + return null; + } + + /* INVENTORY */ + @Override + public InventoryAdapter getInternalInventory() { + return accessibleInventory; + } + + /** + * @return Inaccessible crafting inventory for the craft grid. + */ + public InventoryAdapter getCraftingInventory() { + return craftingInventory; + } +} diff --git a/forestry_common/factory/forestry/factory/gui/ContainerBottler.java b/forestry_common/factory/forestry/factory/gui/ContainerBottler.java new file mode 100755 index 000000000..612db6a0d --- /dev/null +++ b/forestry_common/factory/forestry/factory/gui/ContainerBottler.java @@ -0,0 +1,59 @@ +/******************************************************************************* + * Copyright 2011-2014 by SirSengir + * + * This work is licensed under a Creative Commons Attribution-NonCommercial-NoDerivs 3.0 Unported License. + * + * To view a copy of this license, visit http://creativecommons.org/licenses/by-nc-nd/3.0/. + ******************************************************************************/ +package forestry.factory.gui; + +import net.minecraft.entity.player.EntityPlayer; +import net.minecraft.entity.player.InventoryPlayer; +import net.minecraft.inventory.ICrafting; +import net.minecraft.inventory.Slot; + +import forestry.core.gui.ContainerLiquidTanks; +import forestry.core.gui.slots.SlotClosed; +import forestry.core.gui.slots.SlotLiquidContainer; +import forestry.factory.gadgets.MachineBottler; + +public class ContainerBottler extends ContainerLiquidTanks { + + protected MachineBottler tile; + + public ContainerBottler(InventoryPlayer player, MachineBottler tile) { + super(tile, tile); + + this.tile = tile; + this.addSlot(new SlotLiquidContainer(tile, MachineBottler.SLOT_RESOURCE, 116, 19, true)); + this.addSlot(new SlotClosed(tile, MachineBottler.SLOT_PRODUCT, 116, 55)); + this.addSlot(new SlotLiquidContainer(tile, MachineBottler.SLOT_CAN, 26, 38)); + + int var3; + for (var3 = 0; var3 < 3; ++var3) + for (int var4 = 0; var4 < 9; ++var4) + this.addSlot(new Slot(player, var4 + var3 * 9 + 9, 8 + var4 * 18, 84 + var3 * 18)); + + for (var3 = 0; var3 < 9; ++var3) + this.addSlot(new Slot(player, var3, 8 + var3 * 18, 142)); + + } + + // @Override client side only + public void updateProgressBar(int i, int j) { + tile.getGUINetworkData(i, j); + } + + @Override + public void detectAndSendChanges() { + super.detectAndSendChanges(); + + for (int i = 0; i < crafters.size(); i++) + tile.sendGUINetworkData(this, (ICrafting) crafters.get(i)); + } + + @Override + public boolean canInteractWith(EntityPlayer entityplayer) { + return tile.isUseableByPlayer(entityplayer); + } +} diff --git a/forestry_common/factory/forestry/factory/gui/ContainerCarpenter.java b/forestry_common/factory/forestry/factory/gui/ContainerCarpenter.java new file mode 100755 index 000000000..30a24fefb --- /dev/null +++ b/forestry_common/factory/forestry/factory/gui/ContainerCarpenter.java @@ -0,0 +1,177 @@ +/******************************************************************************* + * Copyright 2011-2014 by SirSengir + * + * This work is licensed under a Creative Commons Attribution-NonCommercial-NoDerivs 3.0 Unported License. + * + * To view a copy of this license, visit http://creativecommons.org/licenses/by-nc-nd/3.0/. + ******************************************************************************/ +package forestry.factory.gui; + +import net.minecraft.entity.player.EntityPlayer; +import net.minecraft.entity.player.InventoryPlayer; +import net.minecraft.inventory.ICrafting; +import net.minecraft.inventory.IInventory; +import net.minecraft.inventory.InventoryCraftResult; +import net.minecraft.inventory.Slot; +import net.minecraft.item.ItemStack; + +import forestry.core.gui.ContainerLiquidTanks; +import forestry.core.gui.slots.SlotCraftAuto; +import forestry.core.gui.slots.SlotLiquidContainer; +import forestry.core.gui.slots.SlotLocked; +import forestry.core.gui.slots.SlotOutput; +import forestry.core.interfaces.IContainerCrafting; +import forestry.core.proxy.Proxies; +import forestry.factory.gadgets.MachineCarpenter; + +public class ContainerCarpenter extends ContainerLiquidTanks implements IContainerCrafting { + + private class SlotCrate extends SlotCraftAuto { + + public SlotCrate(IContainerCrafting container, IInventory iinventory, int slotNumber, int x, int y) { + super(container, iinventory, slotNumber, x, y); + } + + @Override + public boolean isItemValid(ItemStack stack) { + return MachineCarpenter.RecipeManager.isBox(stack); + } + } + private MachineCarpenter machine; + private final IInventory craftingInventory; + private IInventory internalInventory; + public InventoryCraftingAuto craftMatrix; + public InventoryCraftResult craftResult; + + public ContainerCarpenter(InventoryPlayer inventoryplayer, MachineCarpenter tile) { + super(tile.getInternalInventory(), tile); + + machine = tile; + machine.activeContainer = this; + craftingInventory = machine.getCraftingInventory(); + internalInventory = machine.getInternalInventory(); + + craftMatrix = new InventoryCraftingAuto(this, 3, 3); + craftResult = new InventoryCraftResult(); + + // Internal inventory + for (int i = 0; i < 2; i++) { + for (int k = 0; k < 9; k++) { + addSlot(new Slot(internalInventory, MachineCarpenter.SLOT_INVENTORY_1 + k + i * 9, 8 + k * 18, 90 + i * 18)); + } + } + + // Liquid Input + this.addSlot(new SlotLiquidContainer(internalInventory, MachineCarpenter.SLOT_CAN_INPUT, 120, 20)); + // Boxes + this.addSlot(new SlotCrate(this, internalInventory, MachineCarpenter.SLOT_BOX, 83, 20)); + // Product + this.addSlot(new SlotOutput(internalInventory, MachineCarpenter.SLOT_PRODUCT, 120, 56)); + + // CraftResult display + addSlot(new SlotLocked(craftResult, 0, 80, 51)); + + // Crafting matrix + for (int l = 0; l < 3; l++) { + for (int k1 = 0; k1 < 3; k1++) { + addSlot(new SlotCraftMatrix(this, craftingInventory, k1 + l * 3, 10 + k1 * 18, 20 + l * 18)); + } + } + + // Player inventory + for (int i1 = 0; i1 < 3; i1++) { + for (int l1 = 0; l1 < 9; l1++) { + addSlot(new Slot(inventoryplayer, l1 + i1 * 9 + 9, 8 + l1 * 18, 136 + i1 * 18)); + } + } + // Player hotbar + for (int j1 = 0; j1 < 9; j1++) { + addSlot(new Slot(inventoryplayer, j1, 8 + j1 * 18, 194)); + } + + // Update crafting matrix with current contents of tileentity. + for (int i = 0; i < craftMatrix.getSizeInventory(); i++) { + craftMatrix.setInventorySlotContents(i, craftingInventory.getStackInSlot(i)); + } + } + + public ContainerCarpenter(MachineCarpenter tile) { + super(tile.getInternalInventory(), tile); + craftMatrix = new InventoryCraftingAuto(this, 3, 3); + craftResult = new InventoryCraftResult(); + craftingInventory = tile.getCraftingInventory(); + + // Update crafting matrix with current contents of tileentity. + for (int i = 0; i < craftMatrix.getSizeInventory(); i++) { + craftMatrix.setInventorySlotContents(i, craftingInventory.getStackInSlot(i)); + } + } + + @Override + public void updateProgressBar(int i, int j) { + machine.getGUINetworkData(i, j); + } + + @Override + public void detectAndSendChanges() { + super.detectAndSendChanges(); + + for (int i = 0; i < crafters.size(); i++) { + machine.sendGUINetworkData(this, (ICrafting) crafters.get(i)); + } + + updateProductSlot(); + } + + /** + * Replaces the original onCraftMatrixChanged + * + * @param iinventory + * @param slot + */ + @Override + public void onCraftMatrixChanged(IInventory iinventory, int slot) { + craftingInventory.setInventorySlotContents(slot, iinventory.getStackInSlot(slot)); + if (slot < craftMatrix.stackList.length) + craftMatrix.stackList[slot] = iinventory.getStackInSlot(slot); + resetProductDisplay(); + } + + public void updateProductDisplay() { + // Update crafting matrix with current contents of tileentity. + for (int i = 0; i < craftMatrix.getSizeInventory(); i++) { + craftMatrix.setInventorySlotContents(i, craftingInventory.getStackInSlot(i)); + } + resetProductDisplay(); + } + + private void resetProductDisplay() { + if (machine != null) { + machine.setCurrentRecipe(MachineCarpenter.RecipeManager.findMatchingRecipe(machine.resourceTank.getFluid(), machine.getBoxStack(), craftMatrix, + machine.getWorldObj())); + updateProductSlot(); + } + } + + private void updateProductSlot() { + // Update crafting display + if (machine.currentRecipe != null) + craftResult.setInventorySlotContents(0, machine.currentRecipe.getCraftingResult()); + else + craftResult.setInventorySlotContents(0, null); + } + + @Override + public void onContainerClosed(EntityPlayer entityplayer) { + machine.activeContainer = null; + if (entityplayer == null) + return; + + InventoryPlayer inventoryplayer = entityplayer.inventory; + if (inventoryplayer.getItemStack() != null) { + Proxies.common.dropItemPlayer(entityplayer, inventoryplayer.getItemStack()); + inventoryplayer.setItemStack(null); + } + + } +} diff --git a/forestry_common/factory/forestry/factory/gui/ContainerCentrifuge.java b/forestry_common/factory/forestry/factory/gui/ContainerCentrifuge.java new file mode 100755 index 000000000..4dbee591d --- /dev/null +++ b/forestry_common/factory/forestry/factory/gui/ContainerCentrifuge.java @@ -0,0 +1,57 @@ +/******************************************************************************* + * Copyright 2011-2014 by SirSengir + * + * This work is licensed under a Creative Commons Attribution-NonCommercial-NoDerivs 3.0 Unported License. + * + * To view a copy of this license, visit http://creativecommons.org/licenses/by-nc-nd/3.0/. + ******************************************************************************/ +package forestry.factory.gui; + +import net.minecraft.entity.player.InventoryPlayer; +import net.minecraft.inventory.ICrafting; +import net.minecraft.inventory.Slot; + +import forestry.core.gui.ContainerForestry; +import forestry.core.gui.slots.SlotClosed; +import forestry.factory.gadgets.MachineCentrifuge; + +public class ContainerCentrifuge extends ContainerForestry { + + protected MachineCentrifuge tile; + + public ContainerCentrifuge(InventoryPlayer player, MachineCentrifuge tile) { + super(tile); + + this.tile = tile; + + // Resource + this.addSlot(new Slot(tile, 0, 34, 37)); + + // Product Inventory + for (int l = 0; l < 3; l++) + for (int k = 0; k < 3; k++) + addSlot(new SlotClosed(tile, 1 + k + l * 3, 98 + k * 18, 19 + l * 18)); + + // Player inventory + for (int i1 = 0; i1 < 3; i1++) + for (int l1 = 0; l1 < 9; l1++) + addSlot(new Slot(player, l1 + i1 * 9 + 9, 8 + l1 * 18, 84 + i1 * 18)); + // Player hotbar + for (int j1 = 0; j1 < 9; j1++) + addSlot(new Slot(player, j1, 8 + j1 * 18, 142)); + } + + @Override + public void updateProgressBar(int i, int j) { + tile.getGUINetworkData(i, j); + } + + @Override + public void detectAndSendChanges() { + super.detectAndSendChanges(); + + for (int i = 0; i < crafters.size(); i++) + tile.sendGUINetworkData(this, (ICrafting) crafters.get(i)); + } + +} diff --git a/forestry_common/factory/forestry/factory/gui/ContainerFabricator.java b/forestry_common/factory/forestry/factory/gui/ContainerFabricator.java new file mode 100755 index 000000000..6214b55a7 --- /dev/null +++ b/forestry_common/factory/forestry/factory/gui/ContainerFabricator.java @@ -0,0 +1,68 @@ +/******************************************************************************* + * Copyright 2011-2014 by SirSengir + * + * This work is licensed under a Creative Commons Attribution-NonCommercial-NoDerivs 3.0 Unported License. + * + * To view a copy of this license, visit http://creativecommons.org/licenses/by-nc-nd/3.0/. + ******************************************************************************/ +package forestry.factory.gui; + +import net.minecraft.entity.player.InventoryPlayer; +import net.minecraft.inventory.ICrafting; +import net.minecraft.inventory.Slot; + +import forestry.core.gui.ContainerLiquidTanks; +import forestry.core.gui.slots.SlotCrafter; +import forestry.factory.gadgets.MachineFabricator; + +public class ContainerFabricator extends ContainerLiquidTanks { + + private MachineFabricator tile; + + public ContainerFabricator(InventoryPlayer player, MachineFabricator tile) { + super(tile, tile); + this.tile = tile; + + // Internal inventory + for (int i = 0; i < 2; i++) + for (int k = 0; k < 9; k++) + addSlot(new Slot(tile, MachineFabricator.SLOT_INVENTORY_1 + k + i * 9, 8 + k * 18, 84 + i * 18)); + + // Molten resource + this.addSlot(new Slot(tile, MachineFabricator.SLOT_METAL, 26, 21)); + + // Plan + this.addSlot(new Slot(tile, MachineFabricator.SLOT_PLAN, 139, 17)); + + // Result + this.addSlot(new SlotCrafter(tile, tile, MachineFabricator.SLOT_RESULT, 139, 53)); + + // Crafting matrix + for (int l = 0; l < 3; l++) + for (int k = 0; k < 3; k++) + addSlot(new Slot(tile, MachineFabricator.SLOT_CRAFTING_1 + k + l * 3, 67 + k * 18, 17 + l * 18)); + + // Player inventory + for (int i = 0; i < 3; i++) + for (int k = 0; k < 9; k++) + addSlot(new Slot(player, k + i * 9 + 9, 8 + k * 18, 129 + i * 18)); + // Player hotbar + for (int j = 0; j < 9; j++) + addSlot(new Slot(player, j, 8 + j * 18, 187)); + + } + + // @Override client side only + public void updateProgressBar(int i, int j) { + tile.getGUINetworkData(i, j); + } + + @Override + public void detectAndSendChanges() { + super.detectAndSendChanges(); + + for (int i = 0; i < crafters.size(); i++) + tile.sendGUINetworkData(this, (ICrafting) crafters.get(i)); + } + +} diff --git a/forestry_common/factory/forestry/factory/gui/ContainerFermenter.java b/forestry_common/factory/forestry/factory/gui/ContainerFermenter.java new file mode 100755 index 000000000..aff002beb --- /dev/null +++ b/forestry_common/factory/forestry/factory/gui/ContainerFermenter.java @@ -0,0 +1,60 @@ +/******************************************************************************* + * Copyright 2011-2014 by SirSengir + * + * This work is licensed under a Creative Commons Attribution-NonCommercial-NoDerivs 3.0 Unported License. + * + * To view a copy of this license, visit http://creativecommons.org/licenses/by-nc-nd/3.0/. + ******************************************************************************/ +package forestry.factory.gui; + +import net.minecraft.entity.player.EntityPlayer; +import net.minecraft.entity.player.InventoryPlayer; +import net.minecraft.inventory.ICrafting; +import net.minecraft.inventory.Slot; + +import forestry.core.gui.ContainerLiquidTanks; +import forestry.core.gui.slots.SlotCustom; +import forestry.core.gui.slots.SlotLiquidContainer; +import forestry.core.gui.slots.SlotOutput; +import forestry.factory.gadgets.MachineFermenter; + +public class ContainerFermenter extends ContainerLiquidTanks { + protected MachineFermenter fermenter; + + public ContainerFermenter(InventoryPlayer player, MachineFermenter fermenter) { + super(fermenter, fermenter); + + this.fermenter = fermenter; + this.addSlot(new SlotCustom(fermenter, MachineFermenter.SLOT_RESOURCE, 85, 23, true)); + this.addSlot(new SlotCustom(fermenter, MachineFermenter.SLOT_FUEL, 75, 57, true)); + this.addSlot(new SlotOutput(fermenter, MachineFermenter.SLOT_CAN_OUTPUT, 150, 58)); + this.addSlot(new SlotLiquidContainer(fermenter, MachineFermenter.SLOT_CAN_INPUT, 150, 22, true)); + this.addSlot(new SlotLiquidContainer(fermenter, MachineFermenter.SLOT_INPUT, 10, 40)); + + for (int i = 0; i < 3; ++i) + for (int var4 = 0; var4 < 9; ++var4) + this.addSlot(new Slot(player, var4 + i * 9 + 9, 8 + var4 * 18, 84 + i * 18)); + + for (int i = 0; i < 9; ++i) + this.addSlot(new Slot(player, i, 8 + i * 18, 142)); + + } + + @Override + public void updateProgressBar(int i, int j) { + fermenter.getGUINetworkData(i, j); + } + + @Override + public void detectAndSendChanges() { + super.detectAndSendChanges(); + + for (int i = 0; i < crafters.size(); i++) + fermenter.sendGUINetworkData(this, (ICrafting) crafters.get(i)); + } + + @Override + public boolean canInteractWith(EntityPlayer entityplayer) { + return fermenter.isUseableByPlayer(entityplayer); + } +} diff --git a/forestry_common/factory/forestry/factory/gui/ContainerMoistener.java b/forestry_common/factory/forestry/factory/gui/ContainerMoistener.java new file mode 100755 index 000000000..70625ea4d --- /dev/null +++ b/forestry_common/factory/forestry/factory/gui/ContainerMoistener.java @@ -0,0 +1,81 @@ +/******************************************************************************* + * Copyright 2011-2014 by SirSengir + * + * This work is licensed under a Creative Commons Attribution-NonCommercial-NoDerivs 3.0 Unported License. + * + * To view a copy of this license, visit http://creativecommons.org/licenses/by-nc-nd/3.0/. + ******************************************************************************/ +package forestry.factory.gui; + +import net.minecraft.entity.player.EntityPlayer; +import net.minecraft.entity.player.InventoryPlayer; +import net.minecraft.inventory.ICrafting; +import net.minecraft.inventory.IInventory; +import net.minecraft.inventory.Slot; + +import forestry.core.gui.ContainerLiquidTanks; +import forestry.core.gui.slots.SlotCraftAuto; +import forestry.core.gui.slots.SlotWorking; +import forestry.core.interfaces.IContainerCrafting; +import forestry.factory.gadgets.MachineMoistener; + +public class ContainerMoistener extends ContainerLiquidTanks implements IContainerCrafting { + + protected MachineMoistener tile; + + public ContainerMoistener(InventoryPlayer player, MachineMoistener tile) { + super(tile, tile); + + this.tile = tile; + // Stash + for (int l = 0; l < 2; l++) + for (int k1 = 0; k1 < 3; k1++) + addSlot(new Slot(tile, k1 + l * 3, 39 + k1 * 18, 16 + l * 18)); + // Reservoir + for (int k1 = 0; k1 < 3; k1++) + addSlot(new Slot(tile, k1 + 6, 39 + k1 * 18, 22 + 36)); + + // Working slot + this.addSlot(new SlotWorking(tile, 9, 105, 37)); + + // Product slot + this.addSlot(new Slot(tile, 10, 143, 55)); + // Boxes + this.addSlot(new SlotCraftAuto(this, tile, 11, 143, 19)); + + // Player inventory + int var3; + for (var3 = 0; var3 < 3; ++var3) + for (int var4 = 0; var4 < 9; ++var4) + this.addSlot(new Slot(player, var4 + var3 * 9 + 9, 8 + var4 * 18, 84 + var3 * 18)); + + for (var3 = 0; var3 < 9; ++var3) + this.addSlot(new Slot(player, var3, 8 + var3 * 18, 142)); + + } + + // @Override client side only + public void updateProgressBar(int i, int j) { + tile.getGUINetworkData(i, j); + } + + @Override + public void detectAndSendChanges() { + super.detectAndSendChanges(); + + for (int i = 0; i < crafters.size(); i++) + tile.sendGUINetworkData(this, (ICrafting) crafters.get(i)); + } + + @Override + public void onCraftMatrixChanged(IInventory iinventory, int slot) { + inventory.setInventorySlotContents(slot, iinventory.getStackInSlot(slot)); + tile.checkRecipe(); + } + + @Override + public boolean canInteractWith(EntityPlayer player) { + return this.tile.isUseableByPlayer(player); + } + +} diff --git a/forestry_common/factory/forestry/factory/gui/ContainerRaintank.java b/forestry_common/factory/forestry/factory/gui/ContainerRaintank.java new file mode 100755 index 000000000..2e7eb584d --- /dev/null +++ b/forestry_common/factory/forestry/factory/gui/ContainerRaintank.java @@ -0,0 +1,57 @@ +/******************************************************************************* + * Copyright 2011-2014 by SirSengir + * + * This work is licensed under a Creative Commons Attribution-NonCommercial-NoDerivs 3.0 Unported License. + * + * To view a copy of this license, visit http://creativecommons.org/licenses/by-nc-nd/3.0/. + ******************************************************************************/ +package forestry.factory.gui; + +import net.minecraft.entity.player.EntityPlayer; +import net.minecraft.entity.player.InventoryPlayer; +import net.minecraft.inventory.ICrafting; +import net.minecraft.inventory.Slot; + +import forestry.core.gui.ContainerLiquidTanks; +import forestry.core.gui.slots.SlotClosed; +import forestry.core.gui.slots.SlotLiquidContainer; +import forestry.factory.gadgets.MachineRaintank; + +public class ContainerRaintank extends ContainerLiquidTanks { + + protected MachineRaintank tile; + + public ContainerRaintank(InventoryPlayer player, MachineRaintank tile) { + super(tile, tile); + + this.tile = tile; + this.addSlot(new SlotLiquidContainer(tile, MachineRaintank.SLOT_RESOURCE, 116, 19, true)); + this.addSlot(new SlotClosed(tile, MachineRaintank.SLOT_PRODUCT, 116, 55)); + + for (int i = 0; i < 3; ++i) + for (int j = 0; j < 9; ++j) + this.addSlot(new Slot(player, j + i * 9 + 9, 8 + j * 18, 84 + i * 18)); + + for (int i = 0; i < 9; ++i) + this.addSlot(new Slot(player, i, 8 + i * 18, 142)); + + } + + // @Override client side only + public void updateProgressBar(int i, int j) { + tile.getGUINetworkData(i, j); + } + + @Override + public void detectAndSendChanges() { + super.detectAndSendChanges(); + + for (int i = 0; i < crafters.size(); i++) + tile.sendGUINetworkData(this, (ICrafting) crafters.get(i)); + } + + @Override + public boolean canInteractWith(EntityPlayer entityplayer) { + return tile.isUseableByPlayer(entityplayer); + } +} diff --git a/forestry_common/factory/forestry/factory/gui/ContainerSqueezer.java b/forestry_common/factory/forestry/factory/gui/ContainerSqueezer.java new file mode 100755 index 000000000..107379538 --- /dev/null +++ b/forestry_common/factory/forestry/factory/gui/ContainerSqueezer.java @@ -0,0 +1,63 @@ +/******************************************************************************* + * Copyright 2011-2014 by SirSengir + * + * This work is licensed under a Creative Commons Attribution-NonCommercial-NoDerivs 3.0 Unported License. + * + * To view a copy of this license, visit http://creativecommons.org/licenses/by-nc-nd/3.0/. + ******************************************************************************/ +package forestry.factory.gui; + +import net.minecraft.entity.player.InventoryPlayer; +import net.minecraft.inventory.ICrafting; +import net.minecraft.inventory.Slot; + +import forestry.core.gui.ContainerLiquidTanks; +import forestry.core.gui.slots.SlotClosed; +import forestry.core.gui.slots.SlotLiquidContainer; +import forestry.factory.gadgets.MachineSqueezer; + +public class ContainerSqueezer extends ContainerLiquidTanks { + + protected MachineSqueezer tile; + + public ContainerSqueezer(InventoryPlayer player, MachineSqueezer tile) { + super(tile, tile); + + this.tile = tile; + + // Resource inventory + for (int l = 0; l < 3; l++) + for (int k = 0; k < 3; k++) + addSlot(new Slot(tile, k + l * 3, 19 + k * 18, 18 + l * 18)); + + // Remnants slot + this.addSlot(new SlotClosed(tile, 9, 123, 19)); + + // Can slot + this.addSlot(new SlotLiquidContainer(tile, 10, 106, 55, true)); + // Output slot + this.addSlot(new SlotClosed(tile, 11, 140, 55)); + + // Player inventory + for (int i1 = 0; i1 < 3; i1++) + for (int l1 = 0; l1 < 9; l1++) + addSlot(new Slot(player, l1 + i1 * 9 + 9, 8 + l1 * 18, 84 + i1 * 18)); + // Player hotbar + for (int j1 = 0; j1 < 9; j1++) + addSlot(new Slot(player, j1, 8 + j1 * 18, 142)); + } + + @Override + public void updateProgressBar(int i, int j) { + tile.getGUINetworkData(i, j); + } + + @Override + public void detectAndSendChanges() { + super.detectAndSendChanges(); + + for (int i = 0; i < crafters.size(); i++) + tile.sendGUINetworkData(this, (ICrafting) crafters.get(i)); + } + +} diff --git a/forestry_common/factory/forestry/factory/gui/ContainerStill.java b/forestry_common/factory/forestry/factory/gui/ContainerStill.java new file mode 100755 index 000000000..6f80b54dd --- /dev/null +++ b/forestry_common/factory/forestry/factory/gui/ContainerStill.java @@ -0,0 +1,56 @@ +/******************************************************************************* + * Copyright 2011-2014 by SirSengir + * + * This work is licensed under a Creative Commons Attribution-NonCommercial-NoDerivs 3.0 Unported License. + * + * To view a copy of this license, visit http://creativecommons.org/licenses/by-nc-nd/3.0/. + ******************************************************************************/ +package forestry.factory.gui; + +import net.minecraft.entity.player.EntityPlayer; +import net.minecraft.entity.player.InventoryPlayer; +import net.minecraft.inventory.ICrafting; +import net.minecraft.inventory.Slot; + +import forestry.core.gui.ContainerLiquidTanks; +import forestry.core.gui.slots.SlotLiquidContainer; +import forestry.factory.gadgets.MachineStill; + +public class ContainerStill extends ContainerLiquidTanks { + protected MachineStill processor; + + public ContainerStill(InventoryPlayer player, MachineStill tile) { + super(tile, tile); + + this.processor = tile; + this.addSlot(new Slot(tile, MachineStill.SLOT_PRODUCT, 150, 54)); + this.addSlot(new SlotLiquidContainer(tile, MachineStill.SLOT_RESOURCE, 150, 18, true)); + this.addSlot(new SlotLiquidContainer(tile, MachineStill.SLOT_CAN, 10, 36)); + + for (int i = 0; i < 3; ++i) + for (int j = 0; j < 9; ++j) + this.addSlot(new Slot(player, j + i * 9 + 9, 8 + j * 18, 84 + i * 18)); + + for (int i = 0; i < 9; ++i) + this.addSlot(new Slot(player, i, 8 + i * 18, 142)); + + } + + // @Override client side only + public void updateProgressBar(int i, int j) { + processor.getGUINetworkData(i, j); + } + + @Override + public void detectAndSendChanges() { + super.detectAndSendChanges(); + + for (int i = 0; i < crafters.size(); i++) + processor.sendGUINetworkData(this, (ICrafting) crafters.get(i)); + } + + @Override + public boolean canInteractWith(EntityPlayer entityplayer) { + return processor.isUseableByPlayer(entityplayer); + } +} diff --git a/forestry_common/factory/forestry/factory/gui/ContainerWorktable.java b/forestry_common/factory/forestry/factory/gui/ContainerWorktable.java new file mode 100755 index 000000000..829bc84ef --- /dev/null +++ b/forestry_common/factory/forestry/factory/gui/ContainerWorktable.java @@ -0,0 +1,129 @@ +/******************************************************************************* + * Copyright 2011-2014 by SirSengir + * + * This work is licensed under a Creative Commons Attribution-NonCommercial-NoDerivs 3.0 Unported License. + * + * To view a copy of this license, visit http://creativecommons.org/licenses/by-nc-nd/3.0/. + ******************************************************************************/ +package forestry.factory.gui; + +import net.minecraft.entity.player.EntityPlayer; +import net.minecraft.inventory.IInventory; +import net.minecraft.inventory.InventoryCraftResult; +import net.minecraft.inventory.InventoryCrafting; +import net.minecraft.inventory.Slot; + +import forestry.core.gui.ContainerForestry; +import forestry.core.gui.IGuiSelectable; +import forestry.core.gui.slots.SlotCrafter; +import forestry.core.interfaces.IContainerCrafting; +import forestry.core.network.PacketIds; +import forestry.core.network.PacketPayload; +import forestry.core.network.PacketUpdate; +import forestry.core.proxy.Proxies; +import forestry.factory.gadgets.TileWorktable; + +public class ContainerWorktable extends ContainerForestry implements IContainerCrafting, IGuiSelectable { + + EntityPlayer player; + TileWorktable tile; + IInventory craftingInventory; + IInventory internalInventory; + InventoryCrafting craftMatrix = new InventoryCrafting(this, 3, 3); + InventoryCraftResult craftResult = new InventoryCraftResult(); + long lastUpdate; + + public ContainerWorktable(EntityPlayer player, TileWorktable tile) { + super(tile.getInternalInventory()); + this.tile = tile; + + craftingInventory = tile.getCraftingInventory(); + internalInventory = tile.getInternalInventory(); + + // Internal inventory + for (int i = 0; i < 2; i++) { + for (int k = 0; k < 9; k++) { + addSlot(new Slot(internalInventory, TileWorktable.SLOT_INVENTORY_1 + k + i * 9, 8 + k * 18, 90 + i * 18)); + } + } + + // Crafting matrix + for (int l = 0; l < 3; l++) { + for (int k1 = 0; k1 < 3; k1++) { + addSlot(new SlotCraftMatrix(this, craftingInventory, k1 + l * 3, 11 + k1 * 18, 20 + l * 18)); + } + } + + // CraftResult display + addSlot(new SlotCrafter(craftingInventory, tile, TileWorktable.SLOT_CRAFTING_RESULT, 77, 38)); + + // Player inventory + for (int i1 = 0; i1 < 3; i1++) { + for (int l1 = 0; l1 < 9; l1++) { + addSlot(new Slot(player.inventory, l1 + i1 * 9 + 9, 8 + l1 * 18, 136 + i1 * 18)); + } + } + // Player hotbar + for (int j1 = 0; j1 < 9; j1++) { + addSlot(new Slot(player.inventory, j1, 8 + j1 * 18, 194)); + } + + // Update crafting matrix with current contents of tileentity. + updateMatrix(); + updateRecipe(); + + this.player = player; + tile.sendAll(player); + } + + @Override + public void detectAndSendChanges() { + super.detectAndSendChanges(); + if (lastUpdate == tile.getMemory().getLastUpdate()) + return; + + lastUpdate = tile.getMemory().getLastUpdate(); + tile.sendAll(player); + } + + @Override + public void onCraftMatrixChanged(IInventory iinventory, int slot) { +// craftingInventory.setInventorySlotContents(slot, iinventory.getStackInSlot(slot)); + if (slot < craftMatrix.getSizeInventory()) + craftMatrix.setInventorySlotContents(slot, iinventory.getStackInSlot(slot)); + updateRecipe(); + } + + private void updateMatrix() { + for (int i = 0; i < craftMatrix.getSizeInventory(); i++) { + craftMatrix.setInventorySlotContents(i, craftingInventory.getStackInSlot(i)); + } + } + + private void updateRecipe() { + tile.setRecipe(craftMatrix); + } + + public void sendRecipeClick(int mouseButton, int recipeIndex) { + PacketPayload payload = new PacketPayload(2, 0, 0); + payload.intPayload[0] = mouseButton; + payload.intPayload[1] = recipeIndex; + PacketUpdate packet = new PacketUpdate(PacketIds.GUI_SELECTION_CHANGE, payload); + Proxies.net.sendToServer(packet); + } + + @Override + public void handleSelectionChange(EntityPlayer player, PacketUpdate packet) { + if (packet.payload.intPayload[0] > 0) { + tile.getMemory().toggleLock(player.worldObj, packet.payload.intPayload[1]); + } else { + tile.chooseRecipe(packet.payload.intPayload[1]); + updateMatrix(); + updateRecipe(); + } + } + + @Override + public void setSelection(PacketUpdate packet) { + } +} diff --git a/forestry_common/factory/forestry/factory/gui/GuiBottler.java b/forestry_common/factory/forestry/factory/gui/GuiBottler.java new file mode 100755 index 000000000..f49cf4713 --- /dev/null +++ b/forestry_common/factory/forestry/factory/gui/GuiBottler.java @@ -0,0 +1,42 @@ +/******************************************************************************* + * Copyright 2011-2014 by SirSengir + * + * This work is licensed under a Creative Commons Attribution-NonCommercial-NoDerivs 3.0 Unported License. + * + * To view a copy of this license, visit http://creativecommons.org/licenses/by-nc-nd/3.0/. + ******************************************************************************/ +package forestry.factory.gui; + +import net.minecraft.entity.player.InventoryPlayer; + +import forestry.core.config.Defaults; +import forestry.core.gui.GuiForestry; +import forestry.core.gui.widgets.TankWidget; +import forestry.core.utils.StringUtil; +import forestry.factory.gadgets.MachineBottler; + +public class GuiBottler extends GuiForestry { + + public GuiBottler(InventoryPlayer inventory, MachineBottler processor) { + super(Defaults.TEXTURE_PATH_GUI + "/bottler.png", new ContainerBottler(inventory, processor), processor); + widgetManager.add(new TankWidget(this.widgetManager, 53, 17, 0)); + } + + @Override + protected void drawGuiContainerForegroundLayer(int mouseX, int mouseY) { + super.drawGuiContainerForegroundLayer(mouseX, mouseY); + String name = StringUtil.localize("tile.for." + tile.getInventoryName()); + this.fontRendererObj.drawString(name, getCenteredOffset(name), 6, fontColor.get("gui.title")); + } + + @Override + protected void drawGuiContainerBackgroundLayer(float var1, int mouseX, int mouseY) { + super.drawGuiContainerBackgroundLayer(var1, mouseX, mouseY); + MachineBottler boiler = tile; + + if (boiler.isWorking()) { + int i1 = boiler.getFillProgressScaled(24); + drawTexturedModalRect(guiLeft + 80, guiTop + 39, 176, 74, 24 - i1, 16); + } + } +} diff --git a/forestry_common/factory/forestry/factory/gui/GuiCarpenter.java b/forestry_common/factory/forestry/factory/gui/GuiCarpenter.java new file mode 100755 index 000000000..d8d5b4c67 --- /dev/null +++ b/forestry_common/factory/forestry/factory/gui/GuiCarpenter.java @@ -0,0 +1,51 @@ +/******************************************************************************* + * Copyright 2011-2014 by SirSengir + * + * This work is licensed under a Creative Commons Attribution-NonCommercial-NoDerivs 3.0 Unported License. + * + * To view a copy of this license, visit http://creativecommons.org/licenses/by-nc-nd/3.0/. + ******************************************************************************/ +package forestry.factory.gui; + +import net.minecraft.entity.player.InventoryPlayer; + +import forestry.core.config.Defaults; +import forestry.core.gui.GuiForestry; +import forestry.core.gui.widgets.TankWidget; +import forestry.core.utils.StringUtil; +import forestry.factory.gadgets.MachineCarpenter; + +public class GuiCarpenter extends GuiForestry { + + public GuiCarpenter(InventoryPlayer inventory, MachineCarpenter tile) { + super(Defaults.TEXTURE_PATH_GUI + "/carpenter.png", new ContainerCarpenter(inventory, tile), tile); + this.ySize = 218; + + widgetManager.add(new TankWidget(this.widgetManager, 150, 17, 0)); + } + + @Override + public void onGuiClosed() { + super.onGuiClosed(); + inventorySlots.onContainerClosed(mc.thePlayer); + } + + @Override + protected void drawGuiContainerForegroundLayer(int mouseX, int mouseY) { + super.drawGuiContainerForegroundLayer(mouseX, mouseY); + String name = StringUtil.localize("tile.for." + tile.getInventoryName()); + this.fontRendererObj.drawString(name, getCenteredOffset(name), 6, fontColor.get("gui.title")); + } + + @Override + protected void drawGuiContainerBackgroundLayer(float var1, int mouseX, int mouseY) { + super.drawGuiContainerBackgroundLayer(var1, mouseX, mouseY); + MachineCarpenter machine = tile; + + if (machine.isWorking()) { + int progressScaled = 16 - machine.getCraftingProgressScaled(16); + drawTexturedModalRect(guiLeft + 98, guiTop + 51 + 16 - progressScaled, 176, 60 + 16 - progressScaled, 4, progressScaled); + } + } + +} diff --git a/forestry_common/factory/forestry/factory/gui/GuiCentrifuge.java b/forestry_common/factory/forestry/factory/gui/GuiCentrifuge.java new file mode 100755 index 000000000..6615d8527 --- /dev/null +++ b/forestry_common/factory/forestry/factory/gui/GuiCentrifuge.java @@ -0,0 +1,38 @@ +/******************************************************************************* + * Copyright 2011-2014 by SirSengir + * + * This work is licensed under a Creative Commons Attribution-NonCommercial-NoDerivs 3.0 Unported License. + * + * To view a copy of this license, visit http://creativecommons.org/licenses/by-nc-nd/3.0/. + ******************************************************************************/ +package forestry.factory.gui; + +import net.minecraft.entity.player.InventoryPlayer; + +import forestry.core.config.Defaults; +import forestry.core.gui.GuiForestry; +import forestry.core.utils.StringUtil; +import forestry.factory.gadgets.MachineCentrifuge; + +public class GuiCentrifuge extends GuiForestry { + + public GuiCentrifuge(InventoryPlayer inventory, MachineCentrifuge tile) { + super(Defaults.TEXTURE_PATH_GUI + "/centrifuge.png", new ContainerCentrifuge(inventory, tile), tile); + } + + @Override + protected void drawGuiContainerForegroundLayer(int mouseX, int mouseY) { + super.drawGuiContainerForegroundLayer(mouseX, mouseY); + String name = StringUtil.localize("tile.for." + tile.getInventoryName()); + this.fontRendererObj.drawString(name, getCenteredOffset(name), 6, fontColor.get("gui.title")); + } + + @Override + protected void drawGuiContainerBackgroundLayer(float var1, int mouseX, int mouseY) { + super.drawGuiContainerBackgroundLayer(var1, mouseX, mouseY); + MachineCentrifuge machine = tile; + + int progress = 16 - machine.getProgressScaled(16); + drawTexturedModalRect(guiLeft + 62, guiTop + 36 + 17 - progress, 176, 17 - progress, 4, progress); + } +} diff --git a/forestry_common/factory/forestry/factory/gui/GuiFabricator.java b/forestry_common/factory/forestry/factory/gui/GuiFabricator.java new file mode 100755 index 000000000..9d11fe70b --- /dev/null +++ b/forestry_common/factory/forestry/factory/gui/GuiFabricator.java @@ -0,0 +1,47 @@ +/******************************************************************************* + * Copyright 2011-2014 by SirSengir + * + * This work is licensed under a Creative Commons Attribution-NonCommercial-NoDerivs 3.0 Unported License. + * + * To view a copy of this license, visit http://creativecommons.org/licenses/by-nc-nd/3.0/. + ******************************************************************************/ +package forestry.factory.gui; + +import net.minecraft.entity.player.InventoryPlayer; + +import forestry.core.config.Defaults; +import forestry.core.gui.GuiForestry; +import forestry.core.gui.widgets.ReservoirWidget; +import forestry.core.utils.StringUtil; +import forestry.factory.gadgets.MachineFabricator; + +public class GuiFabricator extends GuiForestry { + + public GuiFabricator(InventoryPlayer player, MachineFabricator tile) { + super(Defaults.TEXTURE_PATH_GUI + "/fabricator.png", new ContainerFabricator(player, tile), tile); + this.ySize = 211; + widgetManager.add(new ReservoirWidget(this.widgetManager, 26, 48, 0)); + } + + @Override + protected void drawGuiContainerForegroundLayer(int mouseX, int mouseY) { + super.drawGuiContainerForegroundLayer(mouseX, mouseY); + String name = StringUtil.localize("tile.for." + tile.getInventoryName()); + this.fontRendererObj.drawString(name, getCenteredOffset(name), 6, fontColor.get("gui.title")); + } + + @Override + protected void drawGuiContainerBackgroundLayer(float var1, int mouseX, int mouseY) { + super.drawGuiContainerBackgroundLayer(var1, mouseX, mouseY); + + MachineFabricator fabricator = tile; + int heatScaled = fabricator.getHeatScaled(52); + if (heatScaled > 0) + drawTexturedModalRect(guiLeft + 55, guiTop + 17 + 52 - heatScaled, 192, 0 + 52 - heatScaled, 4, heatScaled); + + int meltingPointScaled = fabricator.getMeltingPointScaled(52); + if (meltingPointScaled > 0) + drawTexturedModalRect(guiLeft + 52, guiTop + 15 + 52 - meltingPointScaled, 196, 0, 10, 5); + } + +} diff --git a/forestry_common/factory/forestry/factory/gui/GuiFermenter.java b/forestry_common/factory/forestry/factory/gui/GuiFermenter.java new file mode 100755 index 000000000..8abea8c09 --- /dev/null +++ b/forestry_common/factory/forestry/factory/gui/GuiFermenter.java @@ -0,0 +1,49 @@ +/******************************************************************************* + * Copyright 2011-2014 by SirSengir + * + * This work is licensed under a Creative Commons Attribution-NonCommercial-NoDerivs 3.0 Unported License. + * + * To view a copy of this license, visit http://creativecommons.org/licenses/by-nc-nd/3.0/. + ******************************************************************************/ +package forestry.factory.gui; + +import net.minecraft.entity.player.InventoryPlayer; + +import forestry.core.config.Defaults; +import forestry.core.gui.GuiForestry; +import forestry.core.gui.widgets.TankWidget; +import forestry.core.utils.StringUtil; +import forestry.factory.gadgets.MachineFermenter; + +public class GuiFermenter extends GuiForestry { + + public GuiFermenter(InventoryPlayer inventory, MachineFermenter tile) { + super(Defaults.TEXTURE_PATH_GUI + "/fermenter.png", new ContainerFermenter(inventory, tile), tile); + widgetManager.add(new TankWidget(this.widgetManager, 35, 19, 0)); + widgetManager.add(new TankWidget(this.widgetManager, 125, 19, 1)); + } + + @Override + protected void drawGuiContainerForegroundLayer(int mouseX, int mouseY) { + super.drawGuiContainerForegroundLayer(mouseX, mouseY); + String name = StringUtil.localize("tile.for." + tile.getInventoryName()); + this.fontRendererObj.drawString(name, getCenteredOffset(name), 6, fontColor.get("gui.title")); + } + + @Override + protected void drawGuiContainerBackgroundLayer(float var1, int mouseX, int mouseY) { + super.drawGuiContainerBackgroundLayer(var1, mouseX, mouseY); + MachineFermenter machine = tile; + + // Fuel remaining + int fuelRemain = machine.getBurnTimeRemainingScaled(16); + if (fuelRemain > 0) + drawTexturedModalRect(guiLeft + 98, guiTop + 46 + 17 - fuelRemain, 176, 78 + 17 - fuelRemain, 4, fuelRemain); + + // Raw bio mush remaining + int bioRemain = machine.getFermentationProgressScaled(16); + if (bioRemain > 0) + drawTexturedModalRect(guiLeft + 74, guiTop + 32 + 17 - bioRemain, 176, 60 + 17 - bioRemain, 4, bioRemain); + } + +} diff --git a/forestry_common/factory/forestry/factory/gui/GuiMoistener.java b/forestry_common/factory/forestry/factory/gui/GuiMoistener.java new file mode 100755 index 000000000..32500d264 --- /dev/null +++ b/forestry_common/factory/forestry/factory/gui/GuiMoistener.java @@ -0,0 +1,50 @@ +/******************************************************************************* + * Copyright 2011-2014 by SirSengir + * + * This work is licensed under a Creative Commons Attribution-NonCommercial-NoDerivs 3.0 Unported License. + * + * To view a copy of this license, visit http://creativecommons.org/licenses/by-nc-nd/3.0/. + ******************************************************************************/ +package forestry.factory.gui; + +import net.minecraft.entity.player.InventoryPlayer; + +import forestry.core.config.Defaults; +import forestry.core.gui.GuiForestry; +import forestry.core.gui.widgets.TankWidget; +import forestry.core.utils.StringUtil; +import forestry.factory.gadgets.MachineMoistener; + +public class GuiMoistener extends GuiForestry { + + public GuiMoistener(InventoryPlayer inventory, MachineMoistener tile) { + super(Defaults.TEXTURE_PATH_GUI + "/moistener.png", new ContainerMoistener(inventory, tile), tile); + widgetManager.add(new TankWidget(this.widgetManager, 16, 16, 0)); + } + + @Override + protected void drawGuiContainerForegroundLayer(int mouseX, int mouseY) { + super.drawGuiContainerForegroundLayer(mouseX, mouseY); + String name = StringUtil.localize("tile.for." + tile.getInventoryName()); + this.fontRendererObj.drawString(name, getCenteredOffset(name), 6, fontColor.get("gui.title")); + } + + @Override + protected void drawGuiContainerBackgroundLayer(float var1, int mouseX, int mouseY) { + super.drawGuiContainerBackgroundLayer(var1, mouseX, mouseY); + MachineMoistener machine = tile; + + // Mycelium production progress + if (machine.isProducing()) { + int i1 = machine.getProductionProgressScaled(16); + drawTexturedModalRect(guiLeft + 124, guiTop + 36, 176, 74, 16 - i1, 16); + } + + // Resource consumption progress + if (machine.isWorking()) { + int i1 = machine.getConsumptionProgressScaled(54); + drawTexturedModalRect(guiLeft + 93, guiTop + 18 + i1, 176, 92 + i1, 29, 54 - i1); + } + } + +} diff --git a/forestry_common/factory/forestry/factory/gui/GuiRaintank.java b/forestry_common/factory/forestry/factory/gui/GuiRaintank.java new file mode 100755 index 000000000..dff6dcaa8 --- /dev/null +++ b/forestry_common/factory/forestry/factory/gui/GuiRaintank.java @@ -0,0 +1,43 @@ +/******************************************************************************* + * Copyright 2011-2014 by SirSengir + * + * This work is licensed under a Creative Commons Attribution-NonCommercial-NoDerivs 3.0 Unported License. + * + * To view a copy of this license, visit http://creativecommons.org/licenses/by-nc-nd/3.0/. + ******************************************************************************/ +package forestry.factory.gui; + +import net.minecraft.entity.player.InventoryPlayer; + +import forestry.core.config.Defaults; +import forestry.core.gui.GuiForestry; +import forestry.core.gui.widgets.TankWidget; +import forestry.core.utils.StringUtil; +import forestry.factory.gadgets.MachineRaintank; + +public class GuiRaintank extends GuiForestry { + + public GuiRaintank(InventoryPlayer inventory, MachineRaintank tile) { + super(Defaults.TEXTURE_PATH_GUI + "/raintank.png", new ContainerRaintank(inventory, tile), tile); + widgetManager.add(new TankWidget(this.widgetManager, 53, 17, 0)); + } + + @Override + protected void drawGuiContainerForegroundLayer(int mouseX, int mouseY) { + super.drawGuiContainerForegroundLayer(mouseX, mouseY); + String name = StringUtil.localize("tile.for." + tile.getInventoryName()); + this.fontRendererObj.drawString(name, getCenteredOffset(name), 6, fontColor.get("gui.title")); + } + + @Override + protected void drawGuiContainerBackgroundLayer(float var1, int mouseX, int mouseY) { + super.drawGuiContainerBackgroundLayer(var1, mouseX, mouseY); + MachineRaintank machine = tile; + + if (machine.isFilling()) { + int progress = machine.getFillProgressScaled(24); + drawTexturedModalRect(guiLeft + 80, guiTop + 39, 176, 74, 24 - progress, 16); + } + + } +} diff --git a/forestry_common/factory/forestry/factory/gui/GuiSqueezer.java b/forestry_common/factory/forestry/factory/gui/GuiSqueezer.java new file mode 100755 index 000000000..2edd8a27f --- /dev/null +++ b/forestry_common/factory/forestry/factory/gui/GuiSqueezer.java @@ -0,0 +1,41 @@ +/******************************************************************************* + * Copyright 2011-2014 by SirSengir + * + * This work is licensed under a Creative Commons Attribution-NonCommercial-NoDerivs 3.0 Unported License. + * + * To view a copy of this license, visit http://creativecommons.org/licenses/by-nc-nd/3.0/. + ******************************************************************************/ +package forestry.factory.gui; + +import net.minecraft.entity.player.InventoryPlayer; + +import forestry.core.config.Defaults; +import forestry.core.gui.GuiForestry; +import forestry.core.gui.widgets.TankWidget; +import forestry.core.utils.StringUtil; +import forestry.factory.gadgets.MachineSqueezer; + +public class GuiSqueezer extends GuiForestry { + + public GuiSqueezer(InventoryPlayer inventory, MachineSqueezer tile) { + super(Defaults.TEXTURE_PATH_GUI + "/squeezer.png", new ContainerSqueezer(inventory, tile), tile); + widgetManager.add(new TankWidget(this.widgetManager, 85, 15, 0)); + } + + @Override + protected void drawGuiContainerForegroundLayer(int mouseX, int mouseY) { + super.drawGuiContainerForegroundLayer(mouseX, mouseY); + String name = StringUtil.localize("tile.for." + tile.getInventoryName()); + this.fontRendererObj.drawString(name, getCenteredOffset(name), 6, fontColor.get("gui.title")); + } + + @Override + protected void drawGuiContainerBackgroundLayer(float var1, int mouseX, int mouseY) { + super.drawGuiContainerBackgroundLayer(var1, mouseX, mouseY); + MachineSqueezer machine = tile; + + int progress = machine.getProgressScaled(43); + drawTexturedModalRect(guiLeft + 75, guiTop + 20, 176, 60, 43 - progress, 18); + } + +} diff --git a/forestry_common/factory/forestry/factory/gui/GuiStill.java b/forestry_common/factory/forestry/factory/gui/GuiStill.java new file mode 100755 index 000000000..981a67728 --- /dev/null +++ b/forestry_common/factory/forestry/factory/gui/GuiStill.java @@ -0,0 +1,47 @@ +/******************************************************************************* + * Copyright 2011-2014 by SirSengir + * + * This work is licensed under a Creative Commons Attribution-NonCommercial-NoDerivs 3.0 Unported License. + * + * To view a copy of this license, visit http://creativecommons.org/licenses/by-nc-nd/3.0/. + ******************************************************************************/ +package forestry.factory.gui; + +import net.minecraft.entity.player.InventoryPlayer; + +import forestry.core.config.Defaults; +import forestry.core.gui.GuiForestry; +import forestry.core.gui.widgets.TankWidget; +import forestry.core.utils.StringUtil; +import forestry.factory.gadgets.MachineStill; + +public class GuiStill extends GuiForestry { + + public GuiStill(InventoryPlayer inventory, MachineStill tile) { + super(Defaults.TEXTURE_PATH_GUI + "/still.png", new ContainerStill(inventory, tile), tile); + widgetManager.add(new TankWidget(this.widgetManager, 35, 15, 0)); + widgetManager.add(new TankWidget(this.widgetManager, 125, 15, 1)); + } + + @Override + protected void drawGuiContainerForegroundLayer(int mouseX, int mouseY) { + super.drawGuiContainerForegroundLayer(mouseX, mouseY); + String name = StringUtil.localize("tile.for." + tile.getInventoryName()); + this.fontRendererObj.drawString(name, getCenteredOffset(name), 6, fontColor.get("gui.title")); + } + + @Override + protected void drawGuiContainerBackgroundLayer(float var1, int mouseX, int mouseY) { + super.drawGuiContainerBackgroundLayer(var1, mouseX, mouseY); + MachineStill boiler = tile; + + if (boiler.isWorking()) + drawTexturedModalRect(guiLeft + 81, guiTop + 57, 176, 60, 14, 14); + + int massRemaining = boiler.getDistillationProgressScaled(16); + if (massRemaining > 0) + drawTexturedModalRect(guiLeft + 84, guiTop + 17 + 17 - massRemaining, 176, 74 + 17 - massRemaining, 4, massRemaining); + + } + +} diff --git a/forestry_common/factory/forestry/factory/gui/GuiWorktable.java b/forestry_common/factory/forestry/factory/gui/GuiWorktable.java new file mode 100755 index 000000000..2ef596c06 --- /dev/null +++ b/forestry_common/factory/forestry/factory/gui/GuiWorktable.java @@ -0,0 +1,144 @@ +/******************************************************************************* + * Copyright 2011-2014 by SirSengir + * + * This work is licensed under a Creative Commons Attribution-NonCommercial-NoDerivs 3.0 Unported License. + * + * To view a copy of this license, visit http://creativecommons.org/licenses/by-nc-nd/3.0/. + ******************************************************************************/ +package forestry.factory.gui; + +import net.minecraft.client.renderer.OpenGlHelper; +import net.minecraft.client.renderer.RenderHelper; +import net.minecraft.entity.player.EntityPlayer; +import net.minecraft.init.Items; +import net.minecraft.item.ItemStack; + +import org.lwjgl.opengl.GL11; + +import forestry.core.config.Defaults; +import forestry.core.gui.GuiForestry; +import forestry.core.gui.WidgetManager; +import forestry.core.gui.widgets.Widget; +import forestry.core.proxy.Proxies; +import forestry.core.render.SpriteSheet; +import forestry.core.render.TextureManager; +import forestry.core.utils.StringUtil; +import forestry.factory.gadgets.TileWorktable; + +public class GuiWorktable extends GuiForestry { + + private class MemorizedSlot extends Widget { + + int slotNumber; + + public MemorizedSlot(WidgetManager manager, int xPos, int yPos, int slot) { + super(manager, xPos, yPos); + this.slotNumber = slot; + } + + private ItemStack getOutputStack() { + return worktable.getMemory().getRecipeOutput(slotNumber); + } + + @Override + public void draw(int startX, int startY) { + GL11.glPushAttrib(GL11.GL_ENABLE_BIT); + GL11.glDisable(GL11.GL_LIGHTING); + GL11.glEnable(GL11.GL_DEPTH_TEST); + RenderHelper.enableGUIStandardItemLighting(); + OpenGlHelper.setLightmapTextureCoords(OpenGlHelper.lightmapTexUnit, 240, 240); + GL11.glColor4f(1.0F, 1.0F, 1.0F, 1.0F); + + ItemStack output = getOutputStack(); + if (output != null) + manager.gui.drawItemStack(output, startX + xPos, startY + yPos); + //RenderHelper.disableStandardItemLighting(); + + GL11.glDisable(GL11.GL_DEPTH_TEST); + + if (worktable.getMemory().isLocked(slotNumber)) { + manager.gui.setZLevel(110f); + Proxies.common.bindTexture(SpriteSheet.ITEMS); + manager.gui.drawTexturedModelRectFromIcon(startX + xPos, startY + yPos, TextureManager.getInstance().getDefault("slots/locked"), 16, 16); + manager.gui.setZLevel(0f); + } + + GL11.glPopAttrib(); + } + + @Override + protected String getLegacyTooltip(EntityPlayer player) { + ItemStack output = getOutputStack(); + return output != null ? output.getDisplayName() : null; + } + + @Override + public void handleMouseClick(int mouseX, int mouseY, int mouseButton) { + container.sendRecipeClick(mouseButton, slotNumber); + } + } + + private class BookSlot extends Widget { + + private final ItemStack BOOK = new ItemStack(Items.book); + + public BookSlot(WidgetManager manager, int xPos, int yPos) { + super(manager, xPos, yPos); + } + + @Override + public void draw(int startX, int startY) { + GL11.glPushAttrib(GL11.GL_ENABLE_BIT); + GL11.glDisable(GL11.GL_LIGHTING); + GL11.glEnable(GL11.GL_DEPTH_TEST); + RenderHelper.enableGUIStandardItemLighting(); + OpenGlHelper.setLightmapTextureCoords(OpenGlHelper.lightmapTexUnit, 240, 240); + GL11.glColor4f(1.0F, 1.0F, 1.0F, 1.0F); + + manager.gui.drawItemStack(BOOK, startX + xPos, startY + yPos); + + GL11.glPopAttrib(); + } + + @Override + protected String getLegacyTooltip(EntityPlayer player) { + return StringUtil.localize("gui.worktable.clear"); + } + + @Override + public void handleMouseClick(int mouseX, int mouseY, int mouseButton) { + container.sendRecipeClick(mouseButton, 9); + } + } + private final TileWorktable worktable; + protected ContainerWorktable container; + + public GuiWorktable(EntityPlayer player, TileWorktable tile) { + super(Defaults.TEXTURE_PATH_GUI + "/worktable.png", new ContainerWorktable(player, tile)); + + ySize = 218; + worktable = tile; + this.tile = tile; + container = (ContainerWorktable) inventorySlots; + + widgetManager.add(new BookSlot(widgetManager, 128, 38)); + + widgetManager.add(new MemorizedSlot(widgetManager, 146, 20, 0)); + widgetManager.add(new MemorizedSlot(widgetManager, 146, 38, 1)); + widgetManager.add(new MemorizedSlot(widgetManager, 146, 56, 2)); + + widgetManager.add(new MemorizedSlot(widgetManager, 128, 56, 3)); + widgetManager.add(new MemorizedSlot(widgetManager, 110, 56, 4)); + + widgetManager.add(new MemorizedSlot(widgetManager, 110, 38, 5)); + widgetManager.add(new MemorizedSlot(widgetManager, 110, 20, 6)); + widgetManager.add(new MemorizedSlot(widgetManager, 128, 20, 7)); + } + + @Override + protected void drawGuiContainerForegroundLayer(int mouseX, int mouseY) { + super.drawGuiContainerForegroundLayer(mouseX, mouseY); + String name = StringUtil.localize("tile.for." + tile.getInventoryName()); + this.fontRendererObj.drawString(name, getCenteredOffset(name), 6, fontColor.get("gui.title")); + } +} diff --git a/forestry_common/factory/forestry/factory/gui/InventoryCraftingAuto.java b/forestry_common/factory/forestry/factory/gui/InventoryCraftingAuto.java new file mode 100755 index 000000000..7636cafeb --- /dev/null +++ b/forestry_common/factory/forestry/factory/gui/InventoryCraftingAuto.java @@ -0,0 +1,102 @@ +/******************************************************************************* + * Copyright 2011-2014 by SirSengir + * + * This work is licensed under a Creative Commons Attribution-NonCommercial-NoDerivs 3.0 Unported License. + * + * To view a copy of this license, visit http://creativecommons.org/licenses/by-nc-nd/3.0/. + ******************************************************************************/ +package forestry.factory.gui; + +import net.minecraft.entity.player.EntityPlayer; +import net.minecraft.inventory.InventoryCrafting; +import net.minecraft.item.ItemStack; + +public class InventoryCraftingAuto extends InventoryCrafting { + + private ContainerCarpenter eventHandler; + public ItemStack stackList[]; + private int inventoryWidth; + + public InventoryCraftingAuto(ContainerCarpenter container, int i, int j) { + super(container, i, j); + int k = i * j; + stackList = new ItemStack[k]; + eventHandler = container; + inventoryWidth = i; + } + + @Override + public ItemStack getStackInSlot(int i) { + if (i >= getSizeInventory()) + return null; + else + return stackList[i]; + } + + @Override + public ItemStack getStackInRowAndColumn(int i, int j) { + if (i < 0 || i >= inventoryWidth) + return null; + else { + int k = i + j * inventoryWidth; + return getStackInSlot(k); + } + } + + @Override + public ItemStack decrStackSize(int i, int j) { + if (stackList[i] != null) { + if (stackList[i].stackSize <= j) { + ItemStack itemstack = stackList[i]; + stackList[i] = null; + eventHandler.onCraftMatrixChanged(this, i); + return itemstack; + } + ItemStack itemstack1 = stackList[i].splitStack(j); + if (stackList[i].stackSize == 0) + stackList[i] = null; + eventHandler.onCraftMatrixChanged(this, i); + return itemstack1; + } else + return null; + } + + @Override + public void setInventorySlotContents(int i, ItemStack itemstack) { + stackList[i] = itemstack; + eventHandler.onCraftMatrixChanged(this, i); + } + + @Override + public String getInventoryName() { + return "Crafting"; + } + + @Override + public int getSizeInventory() { + return stackList.length; + } + + @Override + public int getInventoryStackLimit() { + return 64; + } + + @Override + public void markDirty() { + } + + @Override + public boolean isUseableByPlayer(EntityPlayer entityplayer) { + return true; + } + + @Override + public void openInventory() { + } + + @Override + public void closeInventory() { + } + +} diff --git a/forestry_common/factory/forestry/factory/gui/SlotCraftMatrix.java b/forestry_common/factory/forestry/factory/gui/SlotCraftMatrix.java new file mode 100755 index 000000000..75f75b049 --- /dev/null +++ b/forestry_common/factory/forestry/factory/gui/SlotCraftMatrix.java @@ -0,0 +1,37 @@ +/******************************************************************************* + * Copyright 2011-2014 by SirSengir + * + * This work is licensed under a Creative Commons Attribution-NonCommercial-NoDerivs 3.0 Unported License. + * + * To view a copy of this license, visit http://creativecommons.org/licenses/by-nc-nd/3.0/. + ******************************************************************************/ +package forestry.factory.gui; + +import net.minecraft.inventory.IInventory; + +import forestry.core.gui.slots.SlotForestry; +import forestry.core.interfaces.IContainerCrafting; + +/** + * Informs the passed container of slot changes. Contains a dummy itemstack. + */ +public class SlotCraftMatrix extends SlotForestry { + + private IContainerCrafting eventHandler; + private int slot; + + public SlotCraftMatrix(IContainerCrafting container, IInventory iinventory, int i, int j, int k) { + super(iinventory, i, j, k); + setPhantom(); + this.eventHandler = container; + this.slot = i; + stackLimit = 1; + } + + @Override + public void onSlotChanged() { + super.onSlotChanged(); + eventHandler.onCraftMatrixChanged(inventory, slot); + } + +} diff --git a/forestry_common/factory/forestry/factory/recipes/CraftGuideBottler.java b/forestry_common/factory/forestry/factory/recipes/CraftGuideBottler.java new file mode 100755 index 000000000..a3a06c0bf --- /dev/null +++ b/forestry_common/factory/forestry/factory/recipes/CraftGuideBottler.java @@ -0,0 +1,54 @@ +/******************************************************************************* + * Copyright 2011-2014 by SirSengir + * + * This work is licensed under a Creative Commons Attribution-NonCommercial-NoDerivs 3.0 Unported License. + * + * To view a copy of this license, visit http://creativecommons.org/licenses/by-nc-nd/3.0/. + ******************************************************************************/ +package forestry.factory.recipes; + +import net.minecraft.item.ItemStack; + +import uristqwerty.CraftGuide.api.ItemSlot; +import uristqwerty.CraftGuide.api.LiquidSlot; +import uristqwerty.CraftGuide.api.RecipeGenerator; +import uristqwerty.CraftGuide.api.RecipeProvider; +import uristqwerty.CraftGuide.api.RecipeTemplate; +import uristqwerty.CraftGuide.api.Slot; +import uristqwerty.CraftGuide.api.SlotType; + +import forestry.core.config.Defaults; +import forestry.core.config.ForestryBlock; +import forestry.factory.gadgets.MachineBottler; + +public class CraftGuideBottler implements RecipeProvider { + + private final Slot[] slots = new Slot[4]; + + public CraftGuideBottler() { + slots[0] = new ItemSlot(12, 12, 16, 16).drawOwnBackground(); + slots[1] = new LiquidSlot(12, 30); + slots[2] = new ItemSlot(50, 21, 16, 16).setSlotType(SlotType.OUTPUT_SLOT).drawOwnBackground(); + slots[3] = new ItemSlot(31, 21, 16, 16).setSlotType(SlotType.MACHINE_SLOT); + } + + @Override + public void generateRecipes(RecipeGenerator generator) { + + if (ForestryBlock.factoryTESR == null) + return; + + ItemStack machine = new ItemStack(ForestryBlock.factoryTESR, 1, Defaults.DEFINITION_BOTTLER_META); + RecipeTemplate template = generator.createRecipeTemplate(slots, machine); + + for (MachineBottler.Recipe recipe : MachineBottler.RecipeManager.recipes) { + Object[] array = new Object[4]; + + array[0] = recipe.can; + array[1] = recipe.input; + array[2] = recipe.bottled; + array[3] = machine; + generator.addRecipe(template, array); + } + } +} diff --git a/forestry_common/factory/forestry/factory/recipes/CraftGuideCarpenter.java b/forestry_common/factory/forestry/factory/recipes/CraftGuideCarpenter.java new file mode 100755 index 000000000..1d3645fef --- /dev/null +++ b/forestry_common/factory/forestry/factory/recipes/CraftGuideCarpenter.java @@ -0,0 +1,63 @@ +/******************************************************************************* + * Copyright 2011-2014 by SirSengir + * + * This work is licensed under a Creative Commons Attribution-NonCommercial-NoDerivs 3.0 Unported License. + * + * To view a copy of this license, visit http://creativecommons.org/licenses/by-nc-nd/3.0/. + ******************************************************************************/ +package forestry.factory.recipes; + +import net.minecraft.item.ItemStack; + +import uristqwerty.CraftGuide.api.ItemSlot; +import uristqwerty.CraftGuide.api.LiquidSlot; +import uristqwerty.CraftGuide.api.RecipeGenerator; +import uristqwerty.CraftGuide.api.RecipeProvider; +import uristqwerty.CraftGuide.api.RecipeTemplate; +import uristqwerty.CraftGuide.api.Slot; +import uristqwerty.CraftGuide.api.SlotType; + +import forestry.core.config.Defaults; +import forestry.core.config.ForestryBlock; +import forestry.core.utils.RecipeUtil; +import forestry.factory.gadgets.MachineCarpenter; + +public class CraftGuideCarpenter implements RecipeProvider { + + private final Slot[] slots = new Slot[12]; + + public CraftGuideCarpenter() { + for (int i = 0; i < 3; i++) + for (int j = 0; j < 3; j++) + slots[i + j * 3] = new ItemSlot(i * 18 + 3, j * 18 + 3, 16, 16).drawOwnBackground(); + slots[9] = new ItemSlot(59, 21, 16, 16, true).setSlotType(SlotType.OUTPUT_SLOT).drawOwnBackground(); + slots[10] = new LiquidSlot(59, 39); + slots[11] = new ItemSlot(59, 3, 16, 16).setSlotType(SlotType.MACHINE_SLOT); + } + + @Override + public void generateRecipes(RecipeGenerator generator) { + + if (ForestryBlock.factoryTESR == null) + return; + + ItemStack machine = new ItemStack(ForestryBlock.factoryTESR, 1, Defaults.DEFINITION_CARPENTER_META); + RecipeTemplate template = generator.createRecipeTemplate(slots, machine); + + for (MachineCarpenter.Recipe recipe : MachineCarpenter.RecipeManager.recipes) { + Object[] array = new Object[12]; + + Object[] flattened = RecipeUtil.getCraftingRecipeAsArray(recipe.asIRecipe()); + if (flattened == null) + flattened = generator.getCraftingRecipe(recipe.asIRecipe()); + if (flattened == null) + continue; + System.arraycopy(flattened, 0, array, 0, flattened.length); + if (recipe.getLiquid() != null) + array[10] = recipe.getLiquid(); + array[11] = machine; + generator.addRecipe(template, array); + } + } + +} diff --git a/forestry_common/factory/forestry/factory/recipes/CraftGuideCentrifuge.java b/forestry_common/factory/forestry/factory/recipes/CraftGuideCentrifuge.java new file mode 100755 index 000000000..dd0ab8910 --- /dev/null +++ b/forestry_common/factory/forestry/factory/recipes/CraftGuideCentrifuge.java @@ -0,0 +1,62 @@ +/******************************************************************************* + * Copyright 2011-2014 by SirSengir + * + * This work is licensed under a Creative Commons Attribution-NonCommercial-NoDerivs 3.0 Unported License. + * + * To view a copy of this license, visit http://creativecommons.org/licenses/by-nc-nd/3.0/. + ******************************************************************************/ +package forestry.factory.recipes; + +import java.util.Map.Entry; + +import net.minecraft.item.ItemStack; + +import uristqwerty.CraftGuide.api.ChanceSlot; +import uristqwerty.CraftGuide.api.ItemSlot; +import uristqwerty.CraftGuide.api.RecipeGenerator; +import uristqwerty.CraftGuide.api.RecipeProvider; +import uristqwerty.CraftGuide.api.RecipeTemplate; +import uristqwerty.CraftGuide.api.Slot; +import uristqwerty.CraftGuide.api.SlotType; + +import forestry.core.config.Defaults; +import forestry.core.config.ForestryBlock; +import forestry.factory.gadgets.MachineCentrifuge; + +public class CraftGuideCentrifuge implements RecipeProvider { + + private final Slot[] slots = new Slot[11]; + + public CraftGuideCentrifuge() { + for (int i = 0; i < 3; i++) + for (int j = 0; j < 3; j++) + slots[i + j * 3] = new ChanceSlot(i * 18 + 24, j * 18 + 3, 16, 16).setRatio(100).setSlotType(SlotType.OUTPUT_SLOT).drawOwnBackground(); + slots[9] = new ItemSlot(4, 31, 16, 16, true).drawOwnBackground(); + slots[10] = new ItemSlot(4, 11, 16, 16).setSlotType(SlotType.MACHINE_SLOT); + } + + @Override + public void generateRecipes(RecipeGenerator generator) { + + if (ForestryBlock.factoryTESR == null) + return; + + ItemStack machine = new ItemStack(ForestryBlock.factoryTESR, 1, Defaults.DEFINITION_CENTRIFUGE_META); + RecipeTemplate template = generator.createRecipeTemplate(slots, machine); + + for (MachineCentrifuge.Recipe recipe : MachineCentrifuge.RecipeManager.recipes) { + Object[] array = new Object[11]; + @SuppressWarnings("unchecked") + Entry[] entries = recipe.products.entrySet().toArray(new Entry[0]); + + for (int i = 0; i < Math.min(entries.length, 9); i++) { + array[i] = entries[i].getValue() > 0 ? new Object[] { entries[i].getKey(), entries[i].getValue() } : null; + } + + array[9] = recipe.resource; + array[10] = machine; + + generator.addRecipe(template, array); + } + } +} diff --git a/forestry_common/factory/forestry/factory/recipes/CraftGuideCustomRecipes.java b/forestry_common/factory/forestry/factory/recipes/CraftGuideCustomRecipes.java new file mode 100755 index 000000000..b97a8d672 --- /dev/null +++ b/forestry_common/factory/forestry/factory/recipes/CraftGuideCustomRecipes.java @@ -0,0 +1,55 @@ +/******************************************************************************* + * Copyright 2011-2014 by SirSengir + * + * This work is licensed under a Creative Commons Attribution-NonCommercial-NoDerivs 3.0 Unported License. + * + * To view a copy of this license, visit http://creativecommons.org/licenses/by-nc-nd/3.0/. + ******************************************************************************/ +package forestry.factory.recipes; + +import net.minecraft.init.Blocks; +import net.minecraft.item.ItemStack; +import net.minecraft.item.crafting.CraftingManager; + +import uristqwerty.CraftGuide.api.ItemSlot; +import uristqwerty.CraftGuide.api.RecipeGenerator; +import uristqwerty.CraftGuide.api.RecipeProvider; +import uristqwerty.CraftGuide.api.RecipeTemplate; +import uristqwerty.CraftGuide.api.SlotType; + +import forestry.core.interfaces.IDescriptiveRecipe; +import forestry.core.utils.RecipeUtil; + +public class CraftGuideCustomRecipes implements RecipeProvider { + + private final ItemSlot[] slots = new ItemSlot[10]; + + public CraftGuideCustomRecipes() { + for (int i = 0; i < 3; i++) + for (int j = 0; j < 3; j++) + slots[i + j * 3] = new ItemSlot(i * 18 + 3, j * 18 + 3, 16, 16); + slots[9] = new ItemSlot(59, 21, 16, 16, true).setSlotType(SlotType.OUTPUT_SLOT); + } + + @Override + public void generateRecipes(RecipeGenerator generator) { + + ItemStack machine = new ItemStack(Blocks.crafting_table); + RecipeTemplate template = generator.createRecipeTemplate(slots, machine, "/gui/CraftGuideRecipe.png", 1, 1, 82, 1); + + for (Object rec : CraftingManager.getInstance().getRecipeList()) { + if (!(rec instanceof IDescriptiveRecipe)) + continue; + + Object[] array = new Object[10]; + + Object[] flattened = RecipeUtil.getCraftingRecipeAsArray(rec); + if (flattened == null) + continue; + System.arraycopy(flattened, 0, array, 0, flattened.length); + generator.addRecipe(template, array); + + } + } + +} diff --git a/forestry_common/factory/forestry/factory/recipes/CraftGuideFabricator.java b/forestry_common/factory/forestry/factory/recipes/CraftGuideFabricator.java new file mode 100755 index 000000000..514a8f3b5 --- /dev/null +++ b/forestry_common/factory/forestry/factory/recipes/CraftGuideFabricator.java @@ -0,0 +1,63 @@ +/******************************************************************************* + * Copyright 2011-2014 by SirSengir + * + * This work is licensed under a Creative Commons Attribution-NonCommercial-NoDerivs 3.0 Unported License. + * + * To view a copy of this license, visit http://creativecommons.org/licenses/by-nc-nd/3.0/. + ******************************************************************************/ +package forestry.factory.recipes; + +import net.minecraft.item.ItemStack; + +import uristqwerty.CraftGuide.api.ItemSlot; +import uristqwerty.CraftGuide.api.LiquidSlot; +import uristqwerty.CraftGuide.api.RecipeGenerator; +import uristqwerty.CraftGuide.api.RecipeProvider; +import uristqwerty.CraftGuide.api.RecipeTemplate; +import uristqwerty.CraftGuide.api.Slot; +import uristqwerty.CraftGuide.api.SlotType; + +import forestry.core.config.Defaults; +import forestry.core.config.ForestryBlock; +import forestry.core.utils.RecipeUtil; +import forestry.factory.gadgets.MachineFabricator; + +public class CraftGuideFabricator implements RecipeProvider { + + private final Slot[] slots = new Slot[12]; + + public CraftGuideFabricator() { + for (int i = 0; i < 3; i++) + for (int j = 0; j < 3; j++) + slots[i + j * 3] = new ItemSlot(i * 18 + 3, j * 18 + 3, 16, 16).drawOwnBackground(); + slots[9] = new ItemSlot(59, 21, 16, 16, true).setSlotType(SlotType.OUTPUT_SLOT).drawOwnBackground(); + slots[10] = new LiquidSlot(59, 39); + slots[11] = new ItemSlot(59, 3, 16, 16).setSlotType(SlotType.MACHINE_SLOT); + } + + @Override + public void generateRecipes(RecipeGenerator generator) { + + if (ForestryBlock.factoryTESR == null) + return; + + ItemStack machine = new ItemStack(ForestryBlock.factoryPlain, 1, Defaults.DEFINITION_FABRICATOR_META); + RecipeTemplate template = generator.createRecipeTemplate(slots, machine); + + for (MachineFabricator.Recipe recipe : MachineFabricator.RecipeManager.recipes) { + Object[] array = new Object[12]; + + Object[] flattened = RecipeUtil.getCraftingRecipeAsArray(recipe.asIRecipe()); + if (flattened == null) + flattened = generator.getCraftingRecipe(recipe.asIRecipe()); + if (flattened == null) + continue; + System.arraycopy(flattened, 0, array, 0, flattened.length); + if (recipe.getLiquid() != null) + array[10] = recipe.getLiquid(); + array[11] = machine; + generator.addRecipe(template, array); + } + } + +} diff --git a/forestry_common/factory/forestry/factory/recipes/CraftGuideFermenter.java b/forestry_common/factory/forestry/factory/recipes/CraftGuideFermenter.java new file mode 100755 index 000000000..6ff3d293c --- /dev/null +++ b/forestry_common/factory/forestry/factory/recipes/CraftGuideFermenter.java @@ -0,0 +1,66 @@ +/******************************************************************************* + * Copyright 2011-2014 by SirSengir + * + * This work is licensed under a Creative Commons Attribution-NonCommercial-NoDerivs 3.0 Unported License. + * + * To view a copy of this license, visit http://creativecommons.org/licenses/by-nc-nd/3.0/. + ******************************************************************************/ +package forestry.factory.recipes; + +import java.util.ArrayList; +import java.util.List; + +import net.minecraft.item.ItemStack; + +import net.minecraftforge.fluids.FluidStack; + +import uristqwerty.CraftGuide.api.ItemSlot; +import uristqwerty.CraftGuide.api.LiquidSlot; +import uristqwerty.CraftGuide.api.RecipeGenerator; +import uristqwerty.CraftGuide.api.RecipeProvider; +import uristqwerty.CraftGuide.api.RecipeTemplate; +import uristqwerty.CraftGuide.api.Slot; +import uristqwerty.CraftGuide.api.SlotType; + +import forestry.api.fuels.FuelManager; +import forestry.core.config.Defaults; +import forestry.core.config.ForestryBlock; +import forestry.factory.gadgets.MachineFermenter; + +public class CraftGuideFermenter implements RecipeProvider { + + private final Slot[] slots = new Slot[5]; + + public CraftGuideFermenter() { + slots[0] = new ItemSlot(3, 12, 16, 16, true); + slots[1] = new ItemSlot(3, 30, 16, 16, true); + slots[2] = new LiquidSlot(21, 21); + slots[3] = new LiquidSlot(59, 21).setSlotType(SlotType.OUTPUT_SLOT); + slots[4] = new ItemSlot(40, 21, 16, 16).setSlotType(SlotType.MACHINE_SLOT); + } + + @Override + public void generateRecipes(RecipeGenerator generator) { + + if (ForestryBlock.factoryTESR == null) + return; + + ItemStack machine = new ItemStack(ForestryBlock.factoryTESR, 1, Defaults.DEFINITION_FERMENTER_META); + RecipeTemplate template = generator.createRecipeTemplate(slots, machine); + List fuels = new ArrayList(FuelManager.fermenterFuel.keySet()); + + for (MachineFermenter.Recipe recipe : MachineFermenter.RecipeManager.recipes) { + Object[] array = new Object[5]; + + array[0] = recipe.resource; + array[1] = fuels; + array[2] = recipe.liquid; + FluidStack output = recipe.output.copy(); + output.amount *= recipe.fermentationValue; + output.amount *= recipe.modifier; + array[3] = output; + array[4] = machine; + generator.addRecipe(template, array); + } + } +} diff --git a/forestry_common/factory/forestry/factory/recipes/CraftGuideIntegration.java b/forestry_common/factory/forestry/factory/recipes/CraftGuideIntegration.java new file mode 100755 index 000000000..c95a42be1 --- /dev/null +++ b/forestry_common/factory/forestry/factory/recipes/CraftGuideIntegration.java @@ -0,0 +1,48 @@ +/******************************************************************************* + * Copyright 2011-2014 by SirSengir + * + * This work is licensed under a Creative Commons Attribution-NonCommercial-NoDerivs 3.0 Unported License. + * + * To view a copy of this license, visit http://creativecommons.org/licenses/by-nc-nd/3.0/. + ******************************************************************************/ +package forestry.factory.recipes; + +import java.lang.reflect.Method; + +import forestry.core.proxy.Proxies; + +public class CraftGuideIntegration { + + public static void register() { + registerRecipeProviders(); + } + + private static void registerRecipeProviders() { + + Proxies.log.info("Registering CraftGuide integration."); + try { + Class c = Class.forName("uristqwerty.CraftGuide.ReflectionAPI"); + Method m = c.getMethod("registerAPIObject", Object.class); + + Proxies.log.fine("Adding crafting handler custom recipes."); + m.invoke(null, new CraftGuideCustomRecipes()); + Proxies.log.fine("Adding crafting handler for the carpenter."); + m.invoke(null, new CraftGuideCarpenter()); + Proxies.log.fine("Adding crafting handler for the thermionic fabricator."); + m.invoke(null, new CraftGuideFabricator()); + Proxies.log.fine("Adding crafting handler for the centrifuge."); + m.invoke(null, new CraftGuideCentrifuge()); + Proxies.log.fine("Adding crafting handler for the squeezer."); + m.invoke(null, new CraftGuideSqueezer()); + Proxies.log.fine("Adding crafting handler for the fermenter."); + m.invoke(null, new CraftGuideFermenter()); + Proxies.log.fine("Adding crafting handler for the still."); + m.invoke(null, new CraftGuideStill()); + Proxies.log.fine("Adding crafting handler for the bottler."); + m.invoke(null, new CraftGuideBottler()); + } catch (Exception ex) { + ex.printStackTrace(); + } + } + +} diff --git a/forestry_common/factory/forestry/factory/recipes/CraftGuideSqueezer.java b/forestry_common/factory/forestry/factory/recipes/CraftGuideSqueezer.java new file mode 100755 index 000000000..9381bace9 --- /dev/null +++ b/forestry_common/factory/forestry/factory/recipes/CraftGuideSqueezer.java @@ -0,0 +1,60 @@ +/******************************************************************************* + * Copyright 2011-2014 by SirSengir + * + * This work is licensed under a Creative Commons Attribution-NonCommercial-NoDerivs 3.0 Unported License. + * + * To view a copy of this license, visit http://creativecommons.org/licenses/by-nc-nd/3.0/. + ******************************************************************************/ +package forestry.factory.recipes; + +import net.minecraft.item.ItemStack; + +import uristqwerty.CraftGuide.api.ChanceSlot; +import uristqwerty.CraftGuide.api.ItemSlot; +import uristqwerty.CraftGuide.api.LiquidSlot; +import uristqwerty.CraftGuide.api.RecipeGenerator; +import uristqwerty.CraftGuide.api.RecipeProvider; +import uristqwerty.CraftGuide.api.RecipeTemplate; +import uristqwerty.CraftGuide.api.Slot; +import uristqwerty.CraftGuide.api.SlotType; + +import forestry.core.config.Defaults; +import forestry.core.config.ForestryBlock; +import forestry.factory.gadgets.MachineSqueezer; + +public class CraftGuideSqueezer implements RecipeProvider { + + private final Slot[] slots = new Slot[12]; + + public CraftGuideSqueezer() { + for (int i = 0; i < 3; i++) + for (int j = 0; j < 3; j++) + slots[i + j * 3] = new ItemSlot(i * 18 + 3, j * 18 + 3, 16, 16).drawOwnBackground(); + slots[9] = new ChanceSlot(59, 39, 16, 16, true).setRatio(100).setSlotType(SlotType.OUTPUT_SLOT).drawOwnBackground(); + slots[10] = new LiquidSlot(59, 21).setSlotType(SlotType.OUTPUT_SLOT); + slots[11] = new ItemSlot(59, 3, 16, 16).setSlotType(SlotType.MACHINE_SLOT); + } + + @Override + public void generateRecipes(RecipeGenerator generator) { + + if (ForestryBlock.factoryTESR == null) + return; + + ItemStack machine = new ItemStack(ForestryBlock.factoryTESR, 1, Defaults.DEFINITION_SQUEEZER_META); + RecipeTemplate template = generator.createRecipeTemplate(slots, machine); + + for (MachineSqueezer.Recipe recipe : MachineSqueezer.RecipeManager.recipes) { + Object[] array = new Object[12]; + + System.arraycopy(recipe.resources, 0, array, 0, recipe.resources.length); + if (recipe.remnants != null) + array[9] = recipe.chance > 0 ? new Object[] { recipe.remnants.copy(), recipe.chance } : null; + if (recipe.liquid != null) + array[10] = recipe.liquid; + array[11] = machine; + generator.addRecipe(template, array); + } + } + +} diff --git a/forestry_common/factory/forestry/factory/recipes/CraftGuideStill.java b/forestry_common/factory/forestry/factory/recipes/CraftGuideStill.java new file mode 100755 index 000000000..985e9136e --- /dev/null +++ b/forestry_common/factory/forestry/factory/recipes/CraftGuideStill.java @@ -0,0 +1,52 @@ +/******************************************************************************* + * Copyright 2011-2014 by SirSengir + * + * This work is licensed under a Creative Commons Attribution-NonCommercial-NoDerivs 3.0 Unported License. + * + * To view a copy of this license, visit http://creativecommons.org/licenses/by-nc-nd/3.0/. + ******************************************************************************/ +package forestry.factory.recipes; + +import net.minecraft.item.ItemStack; + +import uristqwerty.CraftGuide.api.ItemSlot; +import uristqwerty.CraftGuide.api.LiquidSlot; +import uristqwerty.CraftGuide.api.RecipeGenerator; +import uristqwerty.CraftGuide.api.RecipeProvider; +import uristqwerty.CraftGuide.api.RecipeTemplate; +import uristqwerty.CraftGuide.api.Slot; +import uristqwerty.CraftGuide.api.SlotType; + +import forestry.core.config.Defaults; +import forestry.core.config.ForestryBlock; +import forestry.factory.gadgets.MachineStill; + +public class CraftGuideStill implements RecipeProvider { + + private final Slot[] slots = new Slot[3]; + + public CraftGuideStill() { + slots[0] = new LiquidSlot(12, 21); + slots[1] = new LiquidSlot(50, 21).setSlotType(SlotType.OUTPUT_SLOT); + slots[2] = new ItemSlot(31, 21, 16, 16).setSlotType(SlotType.MACHINE_SLOT); + } + + @Override + public void generateRecipes(RecipeGenerator generator) { + + if (ForestryBlock.factoryTESR == null) + return; + + ItemStack machine = new ItemStack(ForestryBlock.factoryTESR, 1, Defaults.DEFINITION_STILL_META); + RecipeTemplate template = generator.createRecipeTemplate(slots, machine); + + for (MachineStill.Recipe recipe : MachineStill.RecipeManager.recipes) { + Object[] array = new Object[3]; + + array[0] = recipe.input; + array[1] = recipe.output; + array[2] = machine; + generator.addRecipe(template, array); + } + } +} diff --git a/forestry_common/factory/forestry/plugins/PluginFactory.java b/forestry_common/factory/forestry/plugins/PluginFactory.java new file mode 100755 index 000000000..003ff5975 --- /dev/null +++ b/forestry_common/factory/forestry/plugins/PluginFactory.java @@ -0,0 +1,475 @@ +/******************************************************************************* + * Copyright 2011-2014 by SirSengir + * + * This work is licensed under a Creative Commons Attribution-NonCommercial-NoDerivs 3.0 Unported License. + * + * To view a copy of this license, visit http://creativecommons.org/licenses/by-nc-nd/3.0/. + ******************************************************************************/ +package forestry.plugins; + +import java.util.ArrayList; + +import net.minecraft.block.material.Material; +import net.minecraft.init.Blocks; +import net.minecraft.init.Items; +import net.minecraft.item.ItemStack; + +import cpw.mods.fml.common.network.IGuiHandler; + +import forestry.api.core.PluginInfo; +import forestry.api.recipes.ICraftingProvider; +import forestry.api.recipes.RecipeManagers; +import forestry.core.GameMode; +import forestry.core.config.Config; +import forestry.core.config.Defaults; +import forestry.core.config.ForestryBlock; +import forestry.core.config.ForestryItem; +import forestry.core.gadgets.BlockBase; +import forestry.core.gadgets.MachineDefinition; +import forestry.core.gadgets.MachineNBTDefinition; +import forestry.core.interfaces.IOreDictionaryHandler; +import forestry.core.interfaces.ISaveEventHandler; +import forestry.core.items.ItemForestryBlock; +import forestry.core.items.ItemNBTTile; +import forestry.core.proxy.Proxies; +import forestry.core.utils.LiquidHelper; +import forestry.core.utils.RecipeUtil; +import forestry.core.utils.ShapedRecipeCustom; +import forestry.factory.GuiHandlerFactory; +import forestry.factory.gadgets.MachineBottler; +import forestry.factory.gadgets.MachineCarpenter; +import forestry.factory.gadgets.MachineCarpenter.RecipeManager; +import forestry.factory.gadgets.MachineCentrifuge; +import forestry.factory.gadgets.MachineFabricator; +import forestry.factory.gadgets.MachineFermenter; +import forestry.factory.gadgets.MachineMoistener; +import forestry.factory.gadgets.MachineRaintank; +import forestry.factory.gadgets.MachineSqueezer; +import forestry.factory.gadgets.MachineStill; +import forestry.factory.gadgets.MillRainmaker; +import forestry.factory.gadgets.TileWorktable; +import forestry.factory.recipes.CraftGuideIntegration; + +@PluginInfo(pluginID = "Factory", name = "Factory", author = "SirSengir", url = Defaults.URL, description = "Adds a wide variety of machines to craft, produce and process products.") +public class PluginFactory extends NativePlugin { + + public static MachineDefinition definitionBottler; + public static MachineDefinition definitionCarpenter; + public static MachineDefinition definitionCentrifuge; + public static MachineDefinition definitionFermenter; + public static MachineDefinition definitionMoistener; + public static MachineDefinition definitionSqueezer; + public static MachineDefinition definitionStill; + public static MachineDefinition definitionRainmaker; + public static MachineDefinition definitionFabricator; + public static MachineDefinition definitionRaintank; + public static MachineDefinition definitionWorktable; + + @Override + public boolean isAvailable() { + return !Config.disableFactory; + } + + @Override + public void preInit() { + super.preInit(); + + RecipeManagers.craftingProviders = new ArrayList(); + // Init bottler manager + RecipeManagers.craftingProviders.add(RecipeManagers.bottlerManager = new MachineBottler.RecipeManager()); + // Init carpenter manager + RecipeManagers.craftingProviders.add(RecipeManagers.carpenterManager = new MachineCarpenter.RecipeManager()); + // Init centrifuge manager + RecipeManagers.craftingProviders.add(RecipeManagers.centrifugeManager = new MachineCentrifuge.RecipeManager()); + // Init fabricator manager + RecipeManagers.craftingProviders.add(RecipeManagers.fabricatorManager = new MachineFabricator.RecipeManager()); + // Init fermenter manager + RecipeManagers.craftingProviders.add(RecipeManagers.fermenterManager = new MachineFermenter.RecipeManager()); + // Init moistener manager + RecipeManagers.craftingProviders.add(RecipeManagers.moistenerManager = new MachineMoistener.RecipeManager()); + // Init squeezer manager + RecipeManagers.craftingProviders.add(RecipeManagers.squeezerManager = new MachineSqueezer.RecipeManager()); + // Init still manager + RecipeManagers.craftingProviders.add(RecipeManagers.stillManager = new MachineStill.RecipeManager()); + + ForestryBlock.factoryTESR = new BlockBase(Material.iron, true); + ForestryBlock.factoryTESR.setBlockName("for.factory"); + Proxies.common.registerBlock(ForestryBlock.factoryTESR, ItemForestryBlock.class); + + definitionBottler = ForestryBlock.factoryTESR.addDefinition(new MachineDefinition(Defaults.DEFINITION_BOTTLER_META, "forestry.Bottler", MachineBottler.class, + Proxies.render.getRenderDefaultMachine(Defaults.TEXTURE_PATH_BLOCKS + "/bottler_"), ShapedRecipeCustom.createShapedRecipe(new ItemStack(ForestryBlock.factoryTESR, 1, Defaults.DEFINITION_BOTTLER_META), + "X#X", + "#Y#", + "X#X", + '#', Blocks.glass, + 'X', ForestryItem.canEmpty, + 'Y', ForestryItem.sturdyCasing))); + + definitionCarpenter = ForestryBlock.factoryTESR.addDefinition(new MachineDefinition(Defaults.DEFINITION_CARPENTER_META, "forestry.Carpenter", MachineCarpenter.class, + Proxies.render.getRenderDefaultMachine(Defaults.TEXTURE_PATH_BLOCKS + "/carpenter_"), ShapedRecipeCustom.createShapedRecipe(new ItemStack(ForestryBlock.factoryTESR, 1, Defaults.DEFINITION_CARPENTER_META), + "X#X", + "XYX", + "X#X", + '#', Blocks.glass, + 'X', "ingotBronze", + 'Y', ForestryItem.sturdyCasing))); + + definitionCentrifuge = ForestryBlock.factoryTESR.addDefinition(new MachineDefinition(Defaults.DEFINITION_CENTRIFUGE_META, "forestry.Centrifuge", MachineCentrifuge.class, + Proxies.render.getRenderDefaultMachine(Defaults.TEXTURE_PATH_BLOCKS + "/centrifuge_"), ShapedRecipeCustom.createShapedRecipe(new ItemStack(ForestryBlock.factoryTESR, 1, Defaults.DEFINITION_CENTRIFUGE_META), + "X#X", + "XYX", + "X#X", + '#', Blocks.glass, + 'X', "ingotCopper", + 'Y', ForestryItem.sturdyCasing.getItemStack()))); + + definitionFermenter = ForestryBlock.factoryTESR.addDefinition(new MachineDefinition(Defaults.DEFINITION_FERMENTER_META, "forestry.Fermenter", MachineFermenter.class, + Proxies.render.getRenderDefaultMachine(Defaults.TEXTURE_PATH_BLOCKS + "/fermenter_"), ShapedRecipeCustom.createShapedRecipe(new ItemStack(ForestryBlock.factoryTESR, 1, Defaults.DEFINITION_FERMENTER_META), + "X#X", + "#Y#", + "X#X", + '#', Blocks.glass, + 'X', "gearBronze", + 'Y', ForestryItem.sturdyCasing))); + + definitionMoistener = ForestryBlock.factoryTESR.addDefinition(new MachineDefinition(Defaults.DEFINITION_MOISTENER_META, "forestry.Moistener", MachineMoistener.class, + Proxies.render.getRenderDefaultMachine(Defaults.TEXTURE_PATH_BLOCKS + "/moistener_"), ShapedRecipeCustom.createShapedRecipe(new ItemStack(ForestryBlock.factoryTESR, 1, Defaults.DEFINITION_MOISTENER_META), + "X#X", + "#Y#", + "X#X", + '#', Blocks.glass, + 'X', "gearCopper", + 'Y', ForestryItem.sturdyCasing))); + + definitionSqueezer = ForestryBlock.factoryTESR.addDefinition(new MachineDefinition(Defaults.DEFINITION_SQUEEZER_META, "forestry.Squeezer", MachineSqueezer.class, + Proxies.render.getRenderDefaultMachine(Defaults.TEXTURE_PATH_BLOCKS + "/squeezer_"), ShapedRecipeCustom.createShapedRecipe(new ItemStack(ForestryBlock.factoryTESR, 1, Defaults.DEFINITION_SQUEEZER_META), + "X#X", + "XYX", + "X#X", + '#', Blocks.glass, + 'X', "ingotTin", + 'Y', ForestryItem.sturdyCasing.getItemStack()))); + + definitionStill = ForestryBlock.factoryTESR.addDefinition(new MachineDefinition(Defaults.DEFINITION_STILL_META, "forestry.Still", MachineStill.class, + Proxies.render.getRenderDefaultMachine(Defaults.TEXTURE_PATH_BLOCKS + "/still_"), ShapedRecipeCustom.createShapedRecipe(new ItemStack(ForestryBlock.factoryTESR, 1, Defaults.DEFINITION_STILL_META), + "X#X", + "#Y#", + "X#X", + '#', Blocks.glass, + 'X', Items.redstone, + 'Y', ForestryItem.sturdyCasing))); + + definitionRainmaker = ForestryBlock.factoryTESR.addDefinition(new MachineDefinition(Defaults.DEFINITION_RAINMAKER_META, "forestry.Rainmaker", MillRainmaker.class, + Proxies.render.getRenderMill(Defaults.TEXTURE_PATH_BLOCKS + "/rainmaker_"), ShapedRecipeCustom.createShapedRecipe(new ItemStack(ForestryBlock.factoryTESR, 1, Defaults.DEFINITION_RAINMAKER_META), + "X#X", + "#Y#", + "X#X", + '#', Blocks.glass, + 'X', "gearTin", + 'Y', ForestryItem.hardenedCasing))); + + ForestryBlock.factoryPlain = new BlockBase(Material.iron); + ForestryBlock.factoryPlain.setBlockName("for.factory2"); + Proxies.common.registerBlock(ForestryBlock.factoryPlain, ItemNBTTile.class); + + definitionFabricator = ForestryBlock.factoryPlain.addDefinition(new MachineDefinition(Defaults.DEFINITION_FABRICATOR_META, "forestry.Fabricator", MachineFabricator.class, + ShapedRecipeCustom.createShapedRecipe(new ItemStack(ForestryBlock.factoryPlain, + 1, Defaults.DEFINITION_FABRICATOR_META), + "X#X", + "#Y#", + "XZX", + '#', Blocks.glass, + 'X', Items.gold_ingot, + 'Y', ForestryItem.sturdyCasing, + 'Z', Blocks.chest)).setFaces(0, 1, 2, 3, 4, 4)); + + definitionRaintank = ForestryBlock.factoryPlain.addDefinition(new MachineDefinition(Defaults.DEFINITION_RAINTANK_META, "forestry.Raintank", MachineRaintank.class, + ShapedRecipeCustom.createShapedRecipe(new ItemStack(ForestryBlock.factoryPlain, 1, Defaults.DEFINITION_RAINTANK_META), + "X#X", + "XYX", + "X#X", + '#', Blocks.glass, + 'X', Items.iron_ingot, + 'Y', ForestryItem.sturdyCasing)) + .setFaces(0, 1, 0, 0, 0, 0)); + + definitionWorktable = ForestryBlock.factoryPlain.addDefinition(new MachineNBTDefinition(Defaults.DEFINITION_WORKTABLE_META, "forestry.Worktable", TileWorktable.class, + ShapedRecipeCustom.createShapedRecipe(new ItemStack(ForestryBlock.factoryPlain, 1, Defaults.DEFINITION_WORKTABLE_META), + "B", + "W", + "C", + 'B', Items.book, + 'W', Blocks.crafting_table, + 'C', Blocks.chest)).setFaces(0, 1, 2, 3, 4, 4)); + } + + @Override + public void doInit() { + super.doInit(); + + definitionBottler.register(); + definitionCarpenter.register(); + definitionCentrifuge.register(); + definitionFabricator.register(); + definitionFermenter.register(); + definitionMoistener.register(); + definitionRaintank.register(); + definitionSqueezer.register(); + definitionStill.register(); + definitionRainmaker.register(); + definitionWorktable.register(); + + } + + @Override + public void postInit() { + super.postInit(); + + if (Proxies.common.isModLoaded("craftguide")) + CraftGuideIntegration.register(); + else + Proxies.log.info("Skipping CraftGuide integration."); + } + + @Override + protected void registerItems() { + } + + @Override + protected void registerBackpackItems() { + } + + @Override + protected void registerRecipes() { + + // / FABRICATOR + RecipeManagers.fabricatorManager.addRecipe(null, LiquidHelper.getLiquid(Defaults.LIQUID_GLASS, 500), ForestryItem.tubes.getItemStack(4, 0), new Object[] { + " X ", "#X#", "XXX", '#', Items.redstone, 'X', "ingotCopper" }); + RecipeManagers.fabricatorManager.addRecipe(null, LiquidHelper.getLiquid(Defaults.LIQUID_GLASS, 500), ForestryItem.tubes.getItemStack(4, 1), new Object[] { + " X ", "#X#", "XXX", '#', Items.redstone, 'X', "ingotTin" }); + RecipeManagers.fabricatorManager.addRecipe(null, LiquidHelper.getLiquid(Defaults.LIQUID_GLASS, 500), ForestryItem.tubes.getItemStack(4, 2), new Object[] { + " X ", "#X#", "XXX", '#', Items.redstone, 'X', "ingotBronze" }); + RecipeManagers.fabricatorManager.addRecipe(null, LiquidHelper.getLiquid(Defaults.LIQUID_GLASS, 500), ForestryItem.tubes.getItemStack(4, 3), new Object[] { + " X ", "#X#", "XXX", '#', Items.redstone, 'X', Items.iron_ingot }); + RecipeManagers.fabricatorManager.addRecipe(null, LiquidHelper.getLiquid(Defaults.LIQUID_GLASS, 500), ForestryItem.tubes.getItemStack(4, 4), new Object[] { + " X ", "#X#", "XXX", '#', Items.redstone, 'X', Items.gold_ingot }); + RecipeManagers.fabricatorManager.addRecipe(null, LiquidHelper.getLiquid(Defaults.LIQUID_GLASS, 500), ForestryItem.tubes.getItemStack(4, 5), new Object[] { + " X ", "#X#", "XXX", '#', Items.redstone, 'X', Items.diamond }); + RecipeManagers.fabricatorManager.addRecipe(null, LiquidHelper.getLiquid(Defaults.LIQUID_GLASS, 500), ForestryItem.tubes.getItemStack(4, 6), new Object[] { + " X ", "#X#", "XXX", '#', Items.redstone, 'X', Blocks.obsidian }); + RecipeManagers.fabricatorManager.addRecipe(null, LiquidHelper.getLiquid(Defaults.LIQUID_GLASS, 500), ForestryItem.tubes.getItemStack(4, 7), new Object[] { + " X ", "#X#", "XXX", '#', Items.redstone, 'X', Items.blaze_powder }); + if (PluginIC2.rubber != null) + RecipeManagers.fabricatorManager.addRecipe(null, LiquidHelper.getLiquid(Defaults.LIQUID_GLASS, 500), ForestryItem.tubes.getItemStack(4, 8), + new Object[] { " X ", "#X#", "XXX", '#', Items.redstone, 'X', PluginIC2.rubber }); + RecipeManagers.fabricatorManager.addRecipe(null, LiquidHelper.getLiquid(Defaults.LIQUID_GLASS, 500), ForestryItem.tubes.getItemStack(4, 9), new Object[] { + " X ", "#X#", "XXX", '#', Items.redstone, 'X', Items.emerald }); + RecipeManagers.fabricatorManager.addRecipe(null, LiquidHelper.getLiquid(Defaults.LIQUID_GLASS, 500), ForestryItem.tubes.getItemStack(4, 10), + new Object[] { " X ", "#X#", "XXX", '#', Items.redstone, 'X', "gemApatite" }); + RecipeManagers.fabricatorManager.addRecipe(null, LiquidHelper.getLiquid(Defaults.LIQUID_GLASS, 500), ForestryItem.tubes.getItemStack(4, 11), + new Object[] { " X ", "#X#", "XXX", '#', Items.redstone, 'X', new ItemStack(Items.dye, 1, 4) }); + + String[] dyes = { "dyeBlack", "dyeRed", "dyeGreen", "dyeBrown", "dyeBlue", "dyePurple", "dyeCyan", "dyeLightGray", "dyeGray", "dyePink", "dyeLime", + "dyeYellow", "dyeLightBlue", "dyeMagenta", "dyeOrange", "dyeWhite" }; + + if (ForestryItem.propolis != null) + for (int i = 0; i < 16; i++) { + RecipeManagers.fabricatorManager.addRecipe(ForestryItem.waxCast.getItemStack(1, Defaults.WILDCARD), LiquidHelper.getLiquid(Defaults.LIQUID_GLASS, + Defaults.BUCKET_VOLUME), new ItemStack(ForestryBlock.glass, 1, 15 - i), new Object[] { "#", "X", '#', dyes[i], + 'X', ForestryItem.propolis.getItemStack(1, Defaults.WILDCARD) }); + } + + // / SQUEEZER + RecipeManagers.squeezerManager.addRecipe(10, new ItemStack[] { new ItemStack(Items.apple) }, LiquidHelper.getLiquid(Defaults.LIQUID_JUICE, GameMode.getGameMode().getIntegerSetting("squeezer.liquid.apple")), + ForestryItem.mulch.getItemStack(), GameMode.getGameMode().getIntegerSetting("squeezer.mulch.apple")); + RecipeManagers.squeezerManager.addRecipe(10, new ItemStack[] { new ItemStack(Items.wheat_seeds) }, LiquidHelper.getLiquid(Defaults.LIQUID_SEEDOIL, GameMode + .getGameMode().getIntegerSetting("squeezer.liquid.seed"))); + RecipeManagers.squeezerManager.addRecipe(10, new ItemStack[] { new ItemStack(Items.pumpkin_seeds) }, LiquidHelper.getLiquid(Defaults.LIQUID_SEEDOIL, GameMode + .getGameMode().getIntegerSetting("squeezer.liquid.seed"))); + RecipeManagers.squeezerManager.addRecipe(10, new ItemStack[] { new ItemStack(Items.melon_seeds) }, LiquidHelper.getLiquid(Defaults.LIQUID_SEEDOIL, GameMode + .getGameMode().getIntegerSetting("squeezer.liquid.seed"))); + RecipeManagers.squeezerManager.addRecipe(10, new ItemStack[] { ForestryItem.phosphor.getItemStack(2), new ItemStack(Blocks.cobblestone) }, + LiquidHelper.getLiquid(Defaults.LIQUID_LAVA, 1600)); + RecipeManagers.squeezerManager.addRecipe(10, new ItemStack[] { new ItemStack(Blocks.cactus) }, LiquidHelper.getLiquid(Defaults.LIQUID_WATER, 500)); + RecipeManagers.squeezerManager.addRecipe(10, new ItemStack[] { new ItemStack(Items.snowball), ForestryItem.craftingMaterial.getItemStack(4, 5) }, + LiquidHelper.getLiquid(Defaults.LIQUID_ICE, 4000)); + + // STILL + RecipeManagers.stillManager.addRecipe(Defaults.STILL_DESTILLATION_DURATION, LiquidHelper.getLiquid(Defaults.LIQUID_BIOMASS, + Defaults.STILL_DESTILLATION_INPUT), LiquidHelper.getLiquid(Defaults.LIQUID_ETHANOL, Defaults.STILL_DESTILLATION_OUTPUT)); + + // MOISTENER + RecipeManagers.moistenerManager.addRecipe(new ItemStack(Items.wheat_seeds), new ItemStack(Blocks.mycelium), 5000); + RecipeManagers.moistenerManager.addRecipe(new ItemStack(Blocks.cobblestone), new ItemStack(Blocks.mossy_cobblestone), 20000); + RecipeManagers.moistenerManager.addRecipe(new ItemStack(Blocks.stonebrick), new ItemStack(Blocks.stonebrick, 1, 1), 20000); + + // FERMENTER + RecipeUtil.injectLeveledRecipe(new ItemStack(Blocks.sapling, 1, 0), GameMode.getGameMode().getIntegerSetting("fermenter.yield.sapling"), Defaults.LIQUID_BIOMASS); + RecipeUtil.injectLeveledRecipe(new ItemStack(Blocks.sapling, 1, 1), GameMode.getGameMode().getIntegerSetting("fermenter.yield.sapling"), Defaults.LIQUID_BIOMASS); + RecipeUtil.injectLeveledRecipe(new ItemStack(Blocks.sapling, 1, 2), GameMode.getGameMode().getIntegerSetting("fermenter.yield.sapling"), Defaults.LIQUID_BIOMASS); + RecipeUtil.injectLeveledRecipe(new ItemStack(Blocks.sapling, 1, 3), GameMode.getGameMode().getIntegerSetting("fermenter.yield.sapling"), Defaults.LIQUID_BIOMASS); + + RecipeUtil.injectLeveledRecipe(new ItemStack(Blocks.cactus), GameMode.getGameMode().getIntegerSetting("fermenter.yield.cactus"), Defaults.LIQUID_BIOMASS); + RecipeUtil.injectLeveledRecipe(new ItemStack(Items.wheat), GameMode.getGameMode().getIntegerSetting("fermenter.yield.wheat"), Defaults.LIQUID_BIOMASS); + RecipeUtil.injectLeveledRecipe(new ItemStack(Items.reeds), GameMode.getGameMode().getIntegerSetting("fermenter.yield.cane"), Defaults.LIQUID_BIOMASS); + RecipeUtil.injectLeveledRecipe(new ItemStack(Blocks.brown_mushroom), GameMode.getGameMode().getIntegerSetting("fermenter.yield.mushroom"), Defaults.LIQUID_BIOMASS); + RecipeUtil.injectLeveledRecipe(new ItemStack(Blocks.red_mushroom), GameMode.getGameMode().getIntegerSetting("fermenter.yield.mushroom"), Defaults.LIQUID_BIOMASS); + + // FABRICATOR + RecipeManagers.fabricatorManager.addSmelting(new ItemStack(Blocks.glass), LiquidHelper.getLiquid(Defaults.LIQUID_GLASS, 1000), 1000); + RecipeManagers.fabricatorManager.addSmelting(new ItemStack(Blocks.glass_pane), LiquidHelper.getLiquid(Defaults.LIQUID_GLASS, 375), 1000); + RecipeManagers.fabricatorManager.addSmelting(new ItemStack(Blocks.sand), LiquidHelper.getLiquid(Defaults.LIQUID_GLASS, 1000), 3000); + + // / CARPENTER + RecipeManagers.carpenterManager.addRecipe(50, LiquidHelper.getLiquid(Defaults.LIQUID_SEEDOIL, 250), null, ForestryItem.impregnatedCasing.getItemStack(), + new Object[] { "###", "# #", "###", '#', "logWood" }); + RecipeManagers.carpenterManager.addRecipe(50, LiquidHelper.getLiquid(Defaults.LIQUID_SEEDOIL, 500), null, new ItemStack(ForestryBlock.core, 1, Defaults.DEFINITION_ESCRITOIRE_META), + new Object[] { "# ", "###", "# #", '#', "plankWood" }); + + // RESOURCES + RecipeManagers.carpenterManager.addRecipe(10, LiquidHelper.getLiquid(Defaults.LIQUID_SEEDOIL, 100), null, ForestryItem.stickImpregnated.getItemStack(2), + new Object[] { "#", "#", '#', "logWood" }); + RecipeManagers.carpenterManager.addRecipe(5, LiquidHelper.getLiquid(Defaults.LIQUID_WATER, 250), null, ForestryItem.woodPulp.getItemStack(4), + new Object[] { "#", '#', "logWood" }); + RecipeManagers.carpenterManager.addRecipe(5, LiquidHelper.getLiquid(Defaults.LIQUID_WATER, 250), null, new ItemStack(Items.paper, 1), new Object[] { "#", + "#", '#', "pulpWood" }); + RecipeManagers.carpenterManager.addRecipe(5, LiquidHelper.getLiquid(Defaults.LIQUID_WATER, 1000), null, new ItemStack(ForestryBlock.soil, 9, 0), + new Object[] { "###", "#X#", "###", '#', Blocks.dirt, 'X', ForestryItem.mulch }); + RecipeManagers.carpenterManager.addRecipe(5, LiquidHelper.getLiquid(Defaults.LIQUID_WATER, 1000), null, new ItemStack(ForestryBlock.soil, 8, 1), + new Object[] { "#X#", "XYX", "#X#", '#', Blocks.dirt, 'X', Blocks.sand, 'Y', + ForestryItem.mulch }); + RecipeManagers.carpenterManager.addRecipe(75, LiquidHelper.getLiquid(Defaults.LIQUID_WATER, 5000), null, ForestryItem.hardenedCasing.getItemStack(), + new Object[] { "# #", " Y ", "# #", '#', Items.diamond, 'Y', ForestryItem.sturdyCasing }); + + // / CHIPSETS + RecipeManagers.carpenterManager.addRecipe(20, LiquidHelper.getLiquid(Defaults.LIQUID_WATER, 1000), null, ForestryItem.circuitboards.getItemStack(1, 0), + new Object[] { "R R", "R#R", "R R", '#', "ingotTin", 'R', Items.redstone }); + RecipeManagers.carpenterManager.addRecipe(40, LiquidHelper.getLiquid(Defaults.LIQUID_WATER, 1000), null, ForestryItem.circuitboards.getItemStack(1, 1), + new Object[] { "R#R", "R#R", "R#R", '#', "ingotBronze", 'R', Items.redstone }); + RecipeManagers.carpenterManager.addRecipe(80, LiquidHelper.getLiquid(Defaults.LIQUID_WATER, 1000), null, ForestryItem.circuitboards.getItemStack(1, 2), + new Object[] { "R#R", "R#R", "R#R", '#', Items.iron_ingot, 'R', Items.redstone }); + RecipeManagers.carpenterManager.addRecipe(80, LiquidHelper.getLiquid(Defaults.LIQUID_WATER, 1000), null, ForestryItem.circuitboards.getItemStack(1, 3), + new Object[] { "R#R", "R#R", "R#R", '#', Items.gold_ingot, 'R', Items.redstone }); + RecipeManagers.carpenterManager.addRecipe(40, LiquidHelper.getLiquid(Defaults.LIQUID_WATER, 1000), null, ForestryItem.solderingIron.getItemStack(), + new Object[] { " # ", "# #", " B", '#', Items.iron_ingot, 'B', "ingotBronze" }); + // ForestryCore.oreHandler.registerCarpenterRecipe(solderingIron); + + // RAIN SUBSTRATES + RecipeManagers.carpenterManager.addRecipe(5, LiquidHelper.getLiquid(Defaults.LIQUID_WATER, 1000), null, ForestryItem.iodineCharge.getItemStack(), + new Object[] { "Z#Z", "#Y#", "X#X", '#', ForestryItem.pollen, 'X', Items.gunpowder, + 'Y', ForestryItem.canEmpty, 'Z', ForestryItem.honeyDrop }); + // ForestryCore.oreHandler.registerCarpenterRecipe(iodineCapsule); + RecipeManagers.carpenterManager.addRecipe( + 5, + LiquidHelper.getLiquid(Defaults.LIQUID_WATER, 1000), + null, + ForestryItem.craftingMaterial.getItemStack(1, 4), + new Object[] { "Z#Z", "#Y#", "X#X", '#', ForestryItem.royalJelly, 'X', Items.gunpowder, + 'Y', ForestryItem.canEmpty, 'Z', ForestryItem.honeydew }); + // ForestryCore.oreHandler.registerCarpenterRecipe(dissipationCharge); + + // Ender pearl + RecipeManagers.carpenterManager.addRecipe(100, null, new ItemStack(Items.ender_pearl, 1), new Object[] { " # ", "###", " # ", '#', + ForestryItem.craftingMaterial.getItemStack(1, 1) }); + // Woven Silk + RecipeManagers.carpenterManager.addRecipe(10, LiquidHelper.getLiquid(Defaults.LIQUID_WATER, 500), null, ForestryItem.craftingMaterial.getItemStack(1, 3), + new Object[] { "###", "###", "###", '#', ForestryItem.craftingMaterial.getItemStack(1, 2) }); + + // Boxes + RecipeManagers.carpenterManager.addRecipe(5, LiquidHelper.getLiquid(Defaults.LIQUID_WATER, 1000), null, ForestryItem.carton.getItemStack(2), + new Object[] { " # ", "# #", " # ", '#', "pulpWood" }); + RecipeManagers.carpenterManager.addRecipe(20, LiquidHelper.getLiquid(Defaults.LIQUID_WATER, 1000), null, ForestryItem.crate.getItemStack(24), + new Object[] { " # ", "# #", " # ", '#', "logWood" }); + + // Assembly Kits + RecipeManagers.carpenterManager.addRecipe(20, null, ForestryItem.carton.getItemStack(), ForestryItem.kitPickaxe.getItemStack(), new Object[] { + "###", + " X ", + " X ", + '#', "ingotBronze", + 'X', "stickWood" }); + + RecipeManagers.carpenterManager.addRecipe(20, null, ForestryItem.carton.getItemStack(), ForestryItem.kitShovel.getItemStack(), + new Object[] { " # ", " X ", " X ", '#', "ingotBronze", 'X', "stickWood" }); + + // Reclamation + RecipeManagers.carpenterManager.addRecipe(null, ForestryItem.ingotBronze.getItemStack(2, ForestryItem.ingotBronze.item().getMaxDamage()), + new Object[] { "#", '#', ForestryItem.brokenBronzePickaxe }); + RecipeManagers.carpenterManager.addRecipe(null, ForestryItem.ingotBronze.getItemStack(), new Object[] { "#", '#', ForestryItem.brokenBronzeShovel }); + + // Crating and uncrating condensed + RecipeManagers.carpenterManager.addCrating(ForestryItem.cratedWood.getItemStack()); + RecipeManagers.carpenterManager.addCrating(ForestryItem.cratedCobblestone.getItemStack()); + RecipeManagers.carpenterManager.addCrating(ForestryItem.cratedDirt.getItemStack()); + RecipeManagers.carpenterManager.addCrating(ForestryItem.cratedStone.getItemStack()); + RecipeManagers.carpenterManager.addCrating(ForestryItem.cratedBrick.getItemStack()); + RecipeManagers.carpenterManager.addCrating(ForestryItem.cratedCacti.getItemStack()); + RecipeManagers.carpenterManager.addCrating(ForestryItem.cratedSand.getItemStack()); + RecipeManagers.carpenterManager.addCrating(ForestryItem.cratedObsidian.getItemStack()); + RecipeManagers.carpenterManager.addCrating(ForestryItem.cratedNetherrack.getItemStack()); + RecipeManagers.carpenterManager.addCrating(ForestryItem.cratedSoulsand.getItemStack()); + RecipeManagers.carpenterManager.addCrating(ForestryItem.cratedSandstone.getItemStack()); + RecipeManagers.carpenterManager.addCrating(ForestryItem.cratedBogearth.getItemStack()); + RecipeManagers.carpenterManager.addCrating(ForestryItem.cratedHumus.getItemStack()); + RecipeManagers.carpenterManager.addCrating(ForestryItem.cratedNetherbrick.getItemStack()); + RecipeManagers.carpenterManager.addCrating(ForestryItem.cratedPeat.getItemStack()); + RecipeManagers.carpenterManager.addCrating(ForestryItem.cratedApatite.getItemStack()); + RecipeManagers.carpenterManager.addCrating(ForestryItem.cratedFertilizer.getItemStack()); + ((RecipeManager) RecipeManagers.carpenterManager).addCrating("ingotTin", ForestryItem.ingotTin.getItemStack(), ForestryItem.cratedTin.getItemStack()); + ((RecipeManager) RecipeManagers.carpenterManager).addCrating("ingotCopper", ForestryItem.ingotCopper.getItemStack(), ForestryItem.cratedCopper.getItemStack()); + ((RecipeManager) RecipeManagers.carpenterManager).addCrating("ingotBronze", ForestryItem.ingotBronze.getItemStack(), ForestryItem.cratedBronze.getItemStack()); + RecipeManagers.carpenterManager.addCrating(ForestryItem.cratedWheat.getItemStack()); + RecipeManagers.carpenterManager.addCrating(ForestryItem.cratedMycelium.getItemStack()); + RecipeManagers.carpenterManager.addCrating(ForestryItem.cratedMulch.getItemStack()); + RecipeManagers.carpenterManager.addCrating(ForestryItem.cratedCookies.getItemStack()); + + RecipeManagers.carpenterManager.addCrating(ForestryItem.cratedHoneycombs.getItemStack()); + RecipeManagers.carpenterManager.addCrating(ForestryItem.cratedBeeswax.getItemStack()); + RecipeManagers.carpenterManager.addCrating(ForestryItem.cratedPollen.getItemStack()); + RecipeManagers.carpenterManager.addCrating(ForestryItem.cratedPropolis.getItemStack()); + RecipeManagers.carpenterManager.addCrating(ForestryItem.cratedHoneydew.getItemStack()); + RecipeManagers.carpenterManager.addCrating(ForestryItem.cratedRoyalJelly.getItemStack()); + RecipeManagers.carpenterManager.addCrating(ForestryItem.cratedCocoaComb.getItemStack()); + RecipeManagers.carpenterManager.addCrating(ForestryItem.cratedRedstone.getItemStack()); + RecipeManagers.carpenterManager.addCrating(ForestryItem.cratedLapis.getItemStack()); + RecipeManagers.carpenterManager.addCrating(ForestryItem.cratedReeds.getItemStack()); + RecipeManagers.carpenterManager.addCrating(ForestryItem.cratedClay.getItemStack()); + RecipeManagers.carpenterManager.addCrating(ForestryItem.cratedGlowstone.getItemStack()); + RecipeManagers.carpenterManager.addCrating(ForestryItem.cratedApples.getItemStack()); + RecipeManagers.carpenterManager.addCrating(ForestryItem.cratedNetherwart.getItemStack()); + + RecipeManagers.carpenterManager.addCrating(ForestryItem.cratedSimmeringCombs.getItemStack()); + RecipeManagers.carpenterManager.addCrating(ForestryItem.cratedStringyCombs.getItemStack()); + RecipeManagers.carpenterManager.addCrating(ForestryItem.cratedFrozenCombs.getItemStack()); + RecipeManagers.carpenterManager.addCrating(ForestryItem.cratedDrippingCombs.getItemStack()); + RecipeManagers.carpenterManager.addCrating(ForestryItem.cratedRefractoryWax.getItemStack()); + RecipeManagers.carpenterManager.addCrating(ForestryItem.cratedPhosphor.getItemStack()); + RecipeManagers.carpenterManager.addCrating(ForestryItem.cratedAsh.getItemStack()); + RecipeManagers.carpenterManager.addCrating(ForestryItem.cratedCharcoal.getItemStack()); + RecipeManagers.carpenterManager.addCrating(ForestryItem.cratedGravel.getItemStack()); + RecipeManagers.carpenterManager.addCrating(ForestryItem.cratedCoal.getItemStack()); + RecipeManagers.carpenterManager.addCrating(ForestryItem.cratedSeeds.getItemStack()); + RecipeManagers.carpenterManager.addCrating(ForestryItem.cratedSaplings.getItemStack()); + + } + + @Override + protected void registerCrates() { + // TODO Auto-generated method stub + } + + @Override + public IGuiHandler getGuiHandler() { + return new GuiHandlerFactory(); + } + + @Override + public ISaveEventHandler getSaveEventHandler() { + return null; + } + + @Override + public IOreDictionaryHandler getDictionaryHandler() { + return null; + } +} diff --git a/forestry_common/farming/forestry/farming/EventHandlerFarming.java b/forestry_common/farming/forestry/farming/EventHandlerFarming.java new file mode 100755 index 000000000..3b0237849 --- /dev/null +++ b/forestry_common/farming/forestry/farming/EventHandlerFarming.java @@ -0,0 +1,36 @@ +/******************************************************************************* + * Copyright 2011-2014 by SirSengir + * + * This work is licensed under a Creative Commons Attribution-NonCommercial-NoDerivs 3.0 Unported License. + * + * To view a copy of this license, visit http://creativecommons.org/licenses/by-nc-nd/3.0/. + ******************************************************************************/ +package forestry.farming; + +import net.minecraft.block.Block; + +import cpw.mods.fml.common.eventhandler.Event.Result; +import cpw.mods.fml.common.eventhandler.SubscribeEvent; + +import net.minecraftforge.event.entity.player.BonemealEvent; + +import forestry.core.config.ForestryBlock; +import forestry.core.proxy.Proxies; +import forestry.farming.gadgets.BlockMushroom; + +public class EventHandlerFarming { + + @SubscribeEvent + public void handleBonemeal(BonemealEvent event) { + + if (!Proxies.common.isSimulating(event.world)) + return; + + Block block = event.world.getBlock(event.x, event.y, event.z); + if (block != ForestryBlock.mushroom) + return; + + ((BlockMushroom) ForestryBlock.mushroom).func_149878_d(event.world, event.x, event.y, event.z, event.world.rand); + event.setResult(Result.ALLOW); + } +} diff --git a/forestry_common/farming/forestry/farming/FarmHelper.java b/forestry_common/farming/forestry/farming/FarmHelper.java new file mode 100755 index 000000000..c90fd712b --- /dev/null +++ b/forestry_common/farming/forestry/farming/FarmHelper.java @@ -0,0 +1,22 @@ +/******************************************************************************* + * Copyright 2011-2014 by SirSengir + * + * This work is licensed under a Creative Commons Attribution-NonCommercial-NoDerivs 3.0 Unported License. + * + * To view a copy of this license, visit http://creativecommons.org/licenses/by-nc-nd/3.0/. + ******************************************************************************/ +package forestry.farming; + +import forestry.api.core.IStructureLogic; +import forestry.api.farming.IFarmComponent; +import forestry.api.farming.IFarmInterface; +import forestry.farming.gadgets.StructureLogicFarm; + +public class FarmHelper implements IFarmInterface { + + @Override + public IStructureLogic createFarmStructureLogic(IFarmComponent structure) { + return new StructureLogicFarm(structure); + } + +} diff --git a/forestry_common/farming/forestry/farming/FarmTarget.java b/forestry_common/farming/forestry/farming/FarmTarget.java new file mode 100755 index 000000000..1eda2b1cd --- /dev/null +++ b/forestry_common/farming/forestry/farming/FarmTarget.java @@ -0,0 +1,50 @@ +/******************************************************************************* + * Copyright 2011-2014 by SirSengir + * + * This work is licensed under a Creative Commons Attribution-NonCommercial-NoDerivs 3.0 Unported License. + * + * To view a copy of this license, visit http://creativecommons.org/licenses/by-nc-nd/3.0/. + ******************************************************************************/ +package forestry.farming; + +import forestry.core.utils.Vect; + +public class FarmTarget { + + private Vect start; + private int yOffset; + private int extent; + private int limit; + + public FarmTarget(Vect start) { + this.start = start; + } + + public void setYOffset(int yOffset) { + this.yOffset = yOffset; + } + + public void setLimit(int limit) { + this.limit = limit; + } + + public void setExtent(int extent) { + this.extent = extent; + } + + public Vect getStart() { + return start; + } + + public int getYOffset() { + return this.yOffset; + } + + public int getLimit() { + return limit; + } + + public int getExtent() { + return extent; + } +} diff --git a/forestry_common/farming/forestry/farming/GuiHandlerFarming.java b/forestry_common/farming/forestry/farming/GuiHandlerFarming.java new file mode 100755 index 000000000..aa533ae3c --- /dev/null +++ b/forestry_common/farming/forestry/farming/GuiHandlerFarming.java @@ -0,0 +1,55 @@ +/******************************************************************************* + * Copyright 2011-2014 by SirSengir + * + * This work is licensed under a Creative Commons Attribution-NonCommercial-NoDerivs 3.0 Unported License. + * + * To view a copy of this license, visit http://creativecommons.org/licenses/by-nc-nd/3.0/. + ******************************************************************************/ +package forestry.farming; + +import net.minecraft.entity.player.EntityPlayer; +import net.minecraft.world.World; + +import forestry.core.GuiHandlerBase; +import forestry.core.network.GuiId; +import forestry.core.network.PacketIds; +import forestry.core.network.PacketSocketUpdate; +import forestry.core.proxy.Proxies; +import forestry.farming.gadgets.TileFarmPlain; +import forestry.farming.gui.ContainerFarm; +import forestry.farming.gui.GuiFarm; + +public class GuiHandlerFarming extends GuiHandlerBase { + + @Override + public Object getServerGuiElement(int id, EntityPlayer player, World world, int x, int y, int z) { + + if (id >= GuiId.values().length) + return null; + + switch (GuiId.values()[id]) { + case MultiFarmGUI: + TileFarmPlain tile = (TileFarmPlain) getTileForestry(world, x, y, z); + Proxies.net.sendToPlayer(new PacketSocketUpdate(PacketIds.SOCKET_UPDATE, x, y, z, tile), player); + return new ContainerFarm(player.inventory, tile); + default: + return null; + + } + } + + @Override + public Object getClientGuiElement(int id, EntityPlayer player, World world, int x, int y, int z) { + if (id >= GuiId.values().length) + return null; + + switch (GuiId.values()[id]) { + case MultiFarmGUI: + return new GuiFarm(player, (TileFarmPlain) getTileForestry(world, x, y, z)); + default: + return null; + + } + } + +} diff --git a/forestry_common/farming/forestry/farming/circuits/CircuitFarmLogic.java b/forestry_common/farming/forestry/farming/circuits/CircuitFarmLogic.java new file mode 100755 index 000000000..0d646cacf --- /dev/null +++ b/forestry_common/farming/forestry/farming/circuits/CircuitFarmLogic.java @@ -0,0 +1,74 @@ +/******************************************************************************* + * Copyright 2011-2014 by SirSengir + * + * This work is licensed under a Creative Commons Attribution-NonCommercial-NoDerivs 3.0 Unported License. + * + * To view a copy of this license, visit http://creativecommons.org/licenses/by-nc-nd/3.0/. + ******************************************************************************/ +package forestry.farming.circuits; + +import net.minecraft.tileentity.TileEntity; + +import net.minecraftforge.common.util.ForgeDirection; + +import forestry.api.farming.IFarmHousing; +import forestry.core.circuits.Circuit; +import forestry.farming.logic.FarmLogic; + +public class CircuitFarmLogic extends Circuit { + + private Class logicClass; + private boolean isManual = false; + + public CircuitFarmLogic(String uid, Class logicClass, String[] descriptions) { + super(uid, false, uid, descriptions); + this.logicClass = logicClass; + setLimit(4); + } + + public CircuitFarmLogic setManual() { + isManual = true; + return this; + } + + @Override + public boolean isCircuitable(TileEntity tile) { + return tile instanceof IFarmHousing; + } + + @Override + public void onInsertion(int slot, TileEntity tile) { + if (!isCircuitable(tile)) + return; + + FarmLogic logic = null; + try { + logic = logicClass.getConstructor(new Class[] { IFarmHousing.class }).newInstance(new Object[] { (IFarmHousing) tile }); + } catch (Exception ex) { + throw new RuntimeException("Failed to instantiate logic of class " + logicClass.getName() + ": " + ex.getMessage()); + } + + if (logic != null) { + logic.setManual(isManual); + ((IFarmHousing) tile).setFarmLogic(ForgeDirection.values()[slot + 2], logic); + } + } + + @Override + public void onLoad(int slot, TileEntity tile) { + onInsertion(slot, tile); + } + + @Override + public void onRemoval(int slot, TileEntity tile) { + if (!isCircuitable(tile)) + return; + + ((IFarmHousing) tile).resetFarmLogic(ForgeDirection.values()[slot + 2]); + } + + @Override + public void onTick(int slot, TileEntity tile) { + } + +} diff --git a/forestry_common/farming/forestry/farming/gadgets/BlockFarm.java b/forestry_common/farming/forestry/farming/gadgets/BlockFarm.java new file mode 100755 index 000000000..8c89973e1 --- /dev/null +++ b/forestry_common/farming/forestry/farming/gadgets/BlockFarm.java @@ -0,0 +1,202 @@ +/******************************************************************************* + * Copyright 2011-2014 by SirSengir + * + * This work is licensed under a Creative Commons Attribution-NonCommercial-NoDerivs 3.0 Unported License. + * + * To view a copy of this license, visit http://creativecommons.org/licenses/by-nc-nd/3.0/. + ******************************************************************************/ +package forestry.farming.gadgets; + +import java.util.ArrayList; +import java.util.List; + +import net.minecraft.block.material.Material; +import net.minecraft.client.renderer.texture.IIconRegister; +import net.minecraft.creativetab.CreativeTabs; +import net.minecraft.entity.EntityLivingBase; +import net.minecraft.entity.player.EntityPlayer; +import net.minecraft.item.Item; +import net.minecraft.item.ItemStack; +import net.minecraft.nbt.NBTTagCompound; +import net.minecraft.tileentity.TileEntity; +import net.minecraft.util.IIcon; +import net.minecraft.util.MovingObjectPosition; +import net.minecraft.world.IBlockAccess; +import net.minecraft.world.World; + +import cpw.mods.fml.relauncher.Side; +import cpw.mods.fml.relauncher.SideOnly; + +import forestry.core.gadgets.BlockStructure; +import forestry.core.proxy.Proxies; +import forestry.core.utils.StackUtils; +import forestry.farming.gadgets.TileFarm.EnumFarmBlock; +import forestry.plugins.PluginFarming; + +public class BlockFarm extends BlockStructure { + + public BlockFarm() { + super(Material.rock); + setHardness(1.0f); + } + + @Override + @SuppressWarnings({ "rawtypes", "unchecked" }) + @SideOnly(Side.CLIENT) + public void getSubBlocks(Item item, CreativeTabs tab, List list) { + for (int i = 0; i < 6; i++) { + if (i == 1) + continue; + + for (EnumFarmBlock block : EnumFarmBlock.values()) { + ItemStack stack = new ItemStack(item, 1, i); + NBTTagCompound compound = new NBTTagCompound(); + block.saveToCompound(compound); + stack.setTagCompound(compound); + list.add(stack); + } + } + } + + @Override + public ItemStack getPickBlock(MovingObjectPosition target, World world, int x, int y, int z) { + ArrayList drops = getDrops(world, x, y, z, 0, 0); + if (drops.isEmpty()) + return super.getPickBlock(target, world, x, y, z); + return drops.get(0); + } + + @Override + public void onBlockPlacedBy(World world, int x, int y, int z, EntityLivingBase entityliving, ItemStack stack) { + super.onBlockPlacedBy(world, x, y, z, entityliving, stack); + if (!stack.hasTagCompound()) + return; + + TileFarm tile = (TileFarm) world.getTileEntity(x, y, z); + tile.setFarmBlock(EnumFarmBlock.getFromCompound(stack.getTagCompound())); + } + + @Override + public boolean removedByPlayer(World world, EntityPlayer player, int x, int y, int z) { + int meta = world.getBlockMetadata(x, y, z); + if (Proxies.common.isSimulating(world) && canHarvestBlock(player, meta)) { + List drops = getDrops(world, x, y, z, 0, 0); + for (ItemStack drop : drops) { + StackUtils.dropItemStackAsEntity(drop, world, x, y, z); + } + } + return world.setBlockToAir(x, y, z); + } + + @Override + public ArrayList getDrops(World world, int x, int y, int z, int metadata, int fortune) { + ArrayList drops = new ArrayList(); + int meta = world.getBlockMetadata(x, y, z); + TileEntity tile = world.getTileEntity(x, y, z); + if (tile instanceof TileFarm) { + TileFarm farm = (TileFarm) tile; + + ItemStack stack = new ItemStack(this, 1, meta != 1 ? meta : 0); + NBTTagCompound compound = new NBTTagCompound(); + farm.getFarmBlock().saveToCompound(compound); + stack.setTagCompound(compound); + drops.add(stack); + } + return drops; + } + + @Override + public int getDamageValue(World world, int x, int y, int z) { + int meta = world.getBlockMetadata(x, y, z); + return meta != 1 ? meta : 0; + } + + @Override + public TileEntity createTileEntity(World world, int metadata) { + switch (metadata) { + case 2: + return new TileGearbox(); + case 3: + return new TileHatch(); + case 4: + return new TileValve(); + case 5: + return new TileControl(); + default: + return new TileFarmPlain(); + } + } + + @Override + public TileEntity createNewTileEntity(World world, int meta) { + return createTileEntity(world, meta); + } + + /* ICONS */ + @Override + public int getRenderType() { + return PluginFarming.modelIdFarmBlock; + } + + @SideOnly(Side.CLIENT) + @Override + public void registerBlockIcons(IIconRegister register) { + EnumFarmBlock.registerIcons(register); + } + + @SideOnly(Side.CLIENT) + @Override + public IIcon getIcon(int side, int metadata) { + return getBlockTextureFromSideAndMetadata(EnumFarmBlock.BRICK, side, metadata); + } + + @SideOnly(Side.CLIENT) + public IIcon getBlockTextureFromSideAndMetadata(EnumFarmBlock type, int side, int metadata) { + return StackUtils.getBlock(type.base).getIcon(side, type.base.getItemDamage()); + } + + @SideOnly(Side.CLIENT) + public IIcon getOverlayTextureForBlock(int side, int metadata) { + + EnumFarmBlock type = EnumFarmBlock.BRICK_STONE; + if (metadata == 0 && side == 2) + return type.getIcon(TileFarm.TYPE_REVERSE); + else if (metadata == 0 && (side == 0 || side == 1)) + return type.getIcon(TileFarm.TYPE_TOP); + + switch (metadata) { + case 1: + return type.getIcon(TileFarm.TYPE_BAND); + case 2: + return type.getIcon(TileFarm.TYPE_GEARS); + case 3: + return type.getIcon(TileFarm.TYPE_HATCH); + case 4: + return type.getIcon(TileFarm.TYPE_VALVE); + case 5: + return type.getIcon(TileFarm.TYPE_CONTROL); + default: + return type.getIcon(TileFarm.TYPE_PLAIN); + } + } + + @Override + public boolean canConnectRedstone(IBlockAccess world, int x, int y, int z, int side) { + if (world.getBlockMetadata(x, y, z) == 5) + return true; + else + return false; + } + + @Override + @SideOnly(Side.CLIENT) + public IIcon getIcon(IBlockAccess world, int x, int y, int z, int side) { + TileEntity tile = world.getTileEntity(x, y, z); + ItemStack base = EnumFarmBlock.BRICK_STONE.base; + + if (tile instanceof TileFarm) + base = ((TileFarm) tile).farmBlock.base; + + return StackUtils.getBlock(base).getIcon(side, base.getItemDamage()); + } +} diff --git a/forestry_common/farming/forestry/farming/gadgets/BlockMushroom.java b/forestry_common/farming/forestry/farming/gadgets/BlockMushroom.java new file mode 100755 index 000000000..13d787850 --- /dev/null +++ b/forestry_common/farming/forestry/farming/gadgets/BlockMushroom.java @@ -0,0 +1,121 @@ +/******************************************************************************* + * Copyright 2011-2014 by SirSengir + * + * This work is licensed under a Creative Commons Attribution-NonCommercial-NoDerivs 3.0 Unported License. + * + * To view a copy of this license, visit http://creativecommons.org/licenses/by-nc-nd/3.0/. + ******************************************************************************/ +package forestry.farming.gadgets; + +import java.util.ArrayList; +import java.util.Random; + +import net.minecraft.block.Block; +import net.minecraft.block.BlockSapling; +import net.minecraft.client.renderer.texture.IIconRegister; +import net.minecraft.init.Blocks; +import net.minecraft.item.ItemStack; +import net.minecraft.util.IIcon; +import net.minecraft.world.World; +import net.minecraft.world.gen.feature.WorldGenerator; + +import cpw.mods.fml.relauncher.Side; +import cpw.mods.fml.relauncher.SideOnly; + +import forestry.core.config.Defaults; +import forestry.core.proxy.Proxies; +import forestry.farming.worldgen.WorldGenBigMushroom; + +public class BlockMushroom extends BlockSapling { + + private final WorldGenerator[] generators; + private final ItemStack[] drops; + + public BlockMushroom() { + super(); + setHardness(0.0f); + this.generators = new WorldGenerator[] { new WorldGenBigMushroom(Blocks.brown_mushroom_block), new WorldGenBigMushroom(Blocks.red_mushroom_block) }; + this.drops = new ItemStack[] { new ItemStack(Blocks.brown_mushroom), new ItemStack(Blocks.red_mushroom) }; + setCreativeTab(null); + setTickRandomly(true); + } + + @Override + public boolean getTickRandomly() { + return true; + } + + // / DROPS + @Override + public ArrayList getDrops(World world, int X, int Y, int Z, int metadata, int fortune) { + ArrayList ret = new ArrayList(); + + int type = metadata & 0x03; + ret.add(drops[type]); + + return ret; + } + + @Override + protected boolean canPlaceBlockOn(Block block) { + return block == Blocks.mycelium; + } + + @Override + public void updateTick(World world, int i, int j, int k, Random random) { + + if (!Proxies.common.isSimulating(world)) + return; + + int meta = world.getBlockMetadata(i, j, k); + int type = meta & 0x03; + int maturity = meta >> 2; + + tickGermling(world, i, j, k, random, type, maturity); + } + + private void tickGermling(World world, int i, int j, int k, Random random, int type, int maturity) { + + int lightvalue = world.getBlockLightValue(i, j + 1, k); + + if (random.nextInt(2) != 0) + return; + + if (maturity != 3) { + maturity = 3; + int matX = maturity << 2; + int meta = (matX | type); + world.setBlockMetadataWithNotify(i, j, k, meta, Defaults.FLAG_BLOCK_SYNCH); + } else if (lightvalue <= 7) + func_149878_d(world, i, j, k, random); + } + + @Override + public void func_149878_d(World world, int i, int j, int k, Random random) { + int type = world.getBlockMetadata(i, j, k) & 0x03; + + if(type >= generators.length) + return; + + world.setBlockToAir(i, j, k); + if (!generators[type].generate(world, random, i, j, k)) + world.setBlock(i, j, k, this, type, 0); + } + + /* ICONS */ + @SideOnly(Side.CLIENT) + @Override + public void registerBlockIcons(IIconRegister register) { + } + + @SideOnly(Side.CLIENT) + @Override + public IIcon getIcon(int side, int meta) { + int type = meta & 0x03; + if (type > 0) + return Blocks.red_mushroom.getIcon(side, meta); + else + return Blocks.brown_mushroom.getIcon(side, meta); + } + +} diff --git a/forestry_common/farming/forestry/farming/gadgets/StructureLogicFarm.java b/forestry_common/farming/forestry/farming/gadgets/StructureLogicFarm.java new file mode 100755 index 000000000..81add36b1 --- /dev/null +++ b/forestry_common/farming/forestry/farming/gadgets/StructureLogicFarm.java @@ -0,0 +1,144 @@ +/******************************************************************************* + * Copyright 2011-2014 by SirSengir + * + * This work is licensed under a Creative Commons Attribution-NonCommercial-NoDerivs 3.0 Unported License. + * + * To view a copy of this license, visit http://creativecommons.org/licenses/by-nc-nd/3.0/. + ******************************************************************************/ +package forestry.farming.gadgets; + +import java.util.HashSet; + +import net.minecraft.block.Block; +import net.minecraft.init.Blocks; +import net.minecraft.tileentity.TileEntity; + +import forestry.api.core.ITileStructure; +import forestry.api.farming.IFarmComponent; +import forestry.core.gadgets.BlockStructure.EnumStructureState; +import forestry.core.gadgets.StructureLogic; +import forestry.core.utils.Schemata; +import forestry.core.utils.Schemata.EnumStructureBlock; +import forestry.core.utils.Vect; + +public class StructureLogicFarm extends StructureLogic { + + /* CONSTANTS */ + public static final String UID_FARM = "farm"; + public static final Schemata SCHEMATA_FARM_3x3 = new Schemata("farm3x3", 5, 6, 5, + "FFFFF", "FFFFF", "FFFFF", "FFFFF", "FFFFF", "FFFFF", + "FFFFF", "FAAAF", "FAAAF", "FBBBF", "FAAAF", "FFFFF", + "FFFFF", "FAAAF", "FAAAF", "FBMBF", "FAAAF", "FFFFF", + "FFFFF", "FAAAF", "FAAAF", "FBBBF", "FAAAF", "FFFFF", + "FFFFF", "FFFFF", "FFFFF", "FFFFF", "FFFFF", "FFFFF").setOffsets(-2, -3, -2); + public static final Schemata SCHEMATA_FARM_4x3 = new Schemata("farm3x4", 6, 6, 5, + "FFFFF", "FFFFF", "FFFFF", "FFFFF", "FFFFF", "FFFFF", + "FFFFF", "FAAAF", "FAAAF", "FBBBF", "FAAAF", "FFFFF", + "FFFFF", "FAAAF", "FAAAF", "FBMBF", "FAAAF", "FFFFF", + "FFFFF", "FAAAF", "FAAAF", "FBBBF", "FAAAF", "FFFFF", + "FFFFF", "FAAAF", "FAAAF", "FBBBF", "FAAAF", "FFFFF", + "FFFFF", "FFFFF", "FFFFF", "FFFFF", "FFFFF", "FFFFF").setOffsets(-2, -3, -3); + public static final Schemata SCHEMATA_FARM_4x4 = new Schemata("farm4x4", 6, 6, 6, + "FFFFFF", "FFFFFF", "FFFFFF", "FFFFFF", "FFFFFF", "FFFFFF", + "FFFFFF", "FAAAAF", "FAAAAF", "FBBBBF", "FAAAAF", "FFFFFF", + "FFFFFF", "FAAAAF", "FAAAAF", "FBBMBF", "FAAAAF", "FFFFFF", + "FFFFFF", "FAAAAF", "FAAAAF", "FBBBBF", "FAAAAF", "FFFFFF", + "FFFFFF", "FAAAAF", "FAAAAF", "FBBBBF", "FAAAAF", "FFFFFF", + "FFFFFF", "FFFFFF", "FFFFFF", "FFFFFF", "FFFFFF", "FFFFFF").setOffsets(-3, -3, -3); + public static final Schemata SCHEMATA_FARM_5x3 = new Schemata("farm3x5", 7, 6, 5, + "FFFFF", "FFFFF", "FFFFF", "FFFFF", "FFFFF", "FFFFF", + "FFFFF", "FAAAF", "FAAAF", "FBBBF", "FAAAF", "FFFFF", + "FFFFF", "FAAAF", "FAAAF", "FBBBF", "FAAAF", "FFFFF", + "FFFFF", "FAAAF", "FAAAF", "FBMBF", "FAAAF", "FFFFF", + "FFFFF", "FAAAF", "FAAAF", "FBBBF", "FAAAF", "FFFFF", + "FFFFF", "FAAAF", "FAAAF", "FBBBF", "FAAAF", "FFFFF", + "FFFFF", "FFFFF", "FFFFF", "FFFFF", "FFFFF", "FFFFF").setOffsets(-3, -3, -2); + public static final Schemata SCHEMATA_FARM_5x5 = new Schemata("farm5x5", 7, 6, 7, + "FFFFFFF", "FFFFFFF", "FFFFFFF", "FFFFFFF", "FFFFFFF", "FFFFFFF", + "FFFFFFF", "FAAAAAF", "FAAAAAF", "FBBBBBF", "FAAAAAF", "FFFFFFF", + "FFFFFFF", "FAAAAAF", "FAAAAAF", "FBBBBBF", "FAAAAAF", "FFFFFFF", + "FFFFFFF", "FAAAAAF", "FAAAAAF", "FBBMBBF", "FAAAAAF", "FFFFFFF", + "FFFFFFF", "FAAAAAF", "FAAAAAF", "FBBBBBF", "FAAAAAF", "FFFFFFF", + "FFFFFFF", "FAAAAAF", "FAAAAAF", "FBBBBBF", "FAAAAAF", "FFFFFFF", + "FFFFFFF", "FFFFFFF", "FFFFFFF", "FFFFFFF", "FFFFFFF", "FFFFFFF").setOffsets(-3, -3, -3); + + public static HashSet bricks = new HashSet(); + static { + bricks.add(Blocks.brick_block); + bricks.add(Blocks.stonebrick); + bricks.add(Blocks.sandstone); + bricks.add(Blocks.nether_brick); + bricks.add(Blocks.quartz_block); + } + + public StructureLogicFarm(ITileStructure structure) { + super(UID_FARM, structure); + schematas = new Schemata[] { SCHEMATA_FARM_3x3, SCHEMATA_FARM_4x3, SCHEMATA_FARM_5x3, SCHEMATA_FARM_5x5, SCHEMATA_FARM_4x4 }; + metaOnValid.put(EnumStructureBlock.BLOCK_B, 1); + } + + @Override + protected EnumStructureState determineMasterState(Schemata schemata, boolean rotate) { + + Vect dimensions = schemata.getDimensions(rotate); + int offsetX = schemata.getxOffset(); + int offsetZ = schemata.getzOffset(); + if (rotate) { + offsetX = schemata.getzOffset(); + offsetZ = schemata.getxOffset(); + } + + for (int i = 0; i < dimensions.x; i++) + for (int j = 0; j < schemata.getHeight(); j++) + for (int k = 0; k < dimensions.z; k++) { + + int x = structureTile.xCoord + i + offsetX; + int y = structureTile.yCoord + j + schemata.getyOffset(); + int z = structureTile.zCoord + k + offsetZ; + + if (!structureTile.getWorldObj().blockExists(x, y, z)) + return EnumStructureState.INDETERMINATE; + + EnumStructureBlock required = schemata.getAt(i, j, k, rotate); + + if (required == EnumStructureBlock.ANY) + continue; + + TileEntity tile = structureTile.getWorldObj().getTileEntity(x, y, z); + Block block = structureTile.getWorldObj().getBlock(x, y, z); + + switch (required) { + case AIR: + if (!block.isAir(structureTile.getWorldObj(), x, y, z)) + return EnumStructureState.INVALID; + break; + case BLOCK_A: + if (tile == null || !(tile instanceof IFarmComponent)) + return EnumStructureState.INVALID; + if (!((ITileStructure) tile).getTypeUID().equals(UID_FARM)) + return EnumStructureState.INVALID; + break; + case BLOCK_B: + case MASTER: + if (tile == null || !(tile instanceof TileFarm)) + return EnumStructureState.INVALID; + if (((TileFarm) tile).hasFunction()) + return EnumStructureState.INVALID; + break; + case BLOCK_C: + if (!bricks.contains(block)) + return EnumStructureState.INVALID; + break; + case FOREIGN: + if (tile instanceof ITileStructure) + return EnumStructureState.INVALID; + break; + default: + return EnumStructureState.INDETERMINATE; + } + } + + return EnumStructureState.VALID; + } + +} diff --git a/forestry_common/farming/forestry/farming/gadgets/TileControl.java b/forestry_common/farming/forestry/farming/gadgets/TileControl.java new file mode 100755 index 000000000..41563f3e6 --- /dev/null +++ b/forestry_common/farming/forestry/farming/gadgets/TileControl.java @@ -0,0 +1,101 @@ +/******************************************************************************* + * Copyright 2011-2014 by SirSengir + * + * This work is licensed under a Creative Commons Attribution-NonCommercial-NoDerivs 3.0 Unported License. + * + * To view a copy of this license, visit http://creativecommons.org/licenses/by-nc-nd/3.0/. + ******************************************************************************/ +package forestry.farming.gadgets; + +import java.util.Collection; + +import net.minecraft.item.ItemStack; +import net.minecraft.tileentity.TileEntity; + +import net.minecraftforge.common.util.ForgeDirection; + +import forestry.api.core.ITileStructure; +import forestry.api.farming.ICrop; +import forestry.api.farming.IFarmComponent; +import forestry.api.farming.IFarmListener; +import forestry.api.farming.IFarmLogic; +import forestry.core.utils.Vect; + +public class TileControl extends TileFarm implements IFarmListener { + + public TileControl() { + fixedType = TYPE_CONTROL; + } + + @Override + protected void updateServerSide() { + if (!isInited) + registerWithMaster(); + } + + @Override + public void setCentralTE(TileEntity tile) { + super.setCentralTE(tile); + registerWithMaster(); + } + + private boolean isInited = false; + + private void registerWithMaster() { + + isInited = true; + if (!hasMaster()) + return; + + ITileStructure central = getCentralTE(); + if (!(central instanceof IFarmComponent)) + return; + + ((IFarmComponent) central).registerListener(this); + } + + @Override + public boolean hasFunction() { + return true; + } + + @Override + protected void createInventory() { + } + + /* IFARMLISTENER */ + @Override + public boolean cancelTask(IFarmLogic logic, ForgeDirection direction) { + return hasRedstoneSignal(direction) || hasRedstoneSignal(ForgeDirection.UP) || hasRedstoneSignal(ForgeDirection.DOWN); + } + + private boolean hasRedstoneSignal(ForgeDirection direction) { + Vect side = new Vect(xCoord + direction.offsetX, yCoord + direction.offsetY, zCoord + direction.offsetZ); + + ForgeDirection opp = direction.getOpposite(); + int dir = opp.offsetZ < 0 ? 2 : opp.offsetZ > 0 ? 3 : opp.offsetX < 0 ? 4 : opp.offsetX > 0 ? 5 : 0; + return worldObj.getIndirectPowerLevelTo(side.x, side.y, side.z, dir) > 0 || worldObj.isBlockProvidingPowerTo(side.x, side.y, side.z, dir) > 0; + } + + @Override + public boolean beforeCropHarvest(ICrop crop) { + return false; + } + + @Override + public void afterCropHarvest(Collection harvested, ICrop crop) { + } + + @Override + public void hasCollected(Collection collected, IFarmLogic logic) { + } + + @Override + public void hasCultivated(IFarmLogic logic, int x, int y, int z, ForgeDirection direction, int extent) { + } + + @Override + public void hasScheduledHarvest(Collection harvested, IFarmLogic logic, int x, int y, int z, ForgeDirection direction, int extent) { + } + +} diff --git a/forestry_common/farming/forestry/farming/gadgets/TileFarm.java b/forestry_common/farming/forestry/farming/gadgets/TileFarm.java new file mode 100755 index 000000000..4e3552b21 --- /dev/null +++ b/forestry_common/farming/forestry/farming/gadgets/TileFarm.java @@ -0,0 +1,359 @@ +/******************************************************************************* + * Copyright 2011-2014 by SirSengir + * + * This work is licensed under a Creative Commons Attribution-NonCommercial-NoDerivs 3.0 Unported License. + * + * To view a copy of this license, visit http://creativecommons.org/licenses/by-nc-nd/3.0/. + ******************************************************************************/ +package forestry.farming.gadgets; + +import net.minecraft.client.renderer.texture.IIconRegister; +import net.minecraft.entity.player.EntityPlayer; +import net.minecraft.init.Blocks; +import net.minecraft.inventory.IInventory; +import net.minecraft.item.ItemStack; +import net.minecraft.nbt.NBTTagCompound; +import net.minecraft.tileentity.TileEntity; +import net.minecraft.util.IIcon; + +import cpw.mods.fml.relauncher.Side; +import cpw.mods.fml.relauncher.SideOnly; + +import forestry.api.core.ForestryAPI; +import forestry.api.core.IStructureLogic; +import forestry.api.core.ITileStructure; +import forestry.api.farming.Farmables; +import forestry.api.farming.IFarmComponent; +import forestry.api.farming.IFarmListener; +import forestry.core.gadgets.TileForestry; +import forestry.core.network.GuiId; +import forestry.core.network.PacketPayload; +import forestry.core.proxy.Proxies; +import forestry.core.render.TextureManager; +import forestry.core.utils.TileInventoryAdapter; +import forestry.core.utils.Utils; + +public abstract class TileFarm extends TileForestry implements IFarmComponent { + + public static final int TYPE_PLAIN = 0; + public static final int TYPE_REVERSE = 1; + public static final int TYPE_TOP = 2; + public static final int TYPE_BAND = 3; + public static final int TYPE_GEARS = 4; + public static final int TYPE_HATCH = 5; + public static final int TYPE_VALVE = 6; + public static final int TYPE_CONTROL = 7; + + public enum EnumFarmBlock { + + BRICK_STONE(new ItemStack(Blocks.stonebrick, 1, 0)), + BRICK_MOSSY(new ItemStack(Blocks.stonebrick, 1, 1)), + BRICK_CRACKED(new ItemStack(Blocks.stonebrick, 1, 2)), + BRICK(new ItemStack(Blocks.brick_block)), + SANDSTONE_SMOOTH(new ItemStack(Blocks.sandstone, 1, 2)), + SANDSTONE_CHISELED(new ItemStack(Blocks.sandstone, 1, 1)), + BRICK_NETHER(new ItemStack(Blocks.nether_brick)), + BRICK_CHISELED(new ItemStack(Blocks.stonebrick, 1, 3)), + QUARTZ(new ItemStack(Blocks.quartz_block, 1, 0)), + QUARTZ_CHISELED(new ItemStack(Blocks.quartz_block, 1, 1)), + QUARTZ_LINES(new ItemStack(Blocks.quartz_block, 1, 2)); + public final ItemStack base; + + private EnumFarmBlock(ItemStack base) { + this.base = base; + } + @SideOnly(Side.CLIENT) + private static IIcon[] icons; + + @SideOnly(Side.CLIENT) + public static void registerIcons(IIconRegister register) { + + icons = new IIcon[8]; + // for(int i = 0; i < values().length; i++) { + // generateTexturesIfNeeded(values()[i]); + + icons[0] = TextureManager.getInstance().registerTex(register, "farm/plain"); + icons[1] = TextureManager.getInstance().registerTex(register, "farm/reverse"); + icons[2] = TextureManager.getInstance().registerTex(register, "farm/top"); + icons[3] = TextureManager.getInstance().registerTex(register, "farm/band"); + icons[4] = TextureManager.getInstance().registerTex(register, "farm/gears"); + icons[5] = TextureManager.getInstance().registerTex(register, "farm/hatch"); + icons[6] = TextureManager.getInstance().registerTex(register, "farm/valve"); + icons[7] = TextureManager.getInstance().registerTex(register, "farm/control"); + // } + } + + @SideOnly(Side.CLIENT) + public IIcon getIcon(int type) { + return icons[type]; + } + + public void saveToCompound(NBTTagCompound compound) { + compound.setInteger("FarmBlock", this.ordinal()); + } + + public String getName() { + return base.getItem().getItemStackDisplayName(base); + } + + public ItemStack getCraftingIngredient() { + return base; + } + + public static EnumFarmBlock getFromCompound(NBTTagCompound compound) { + + if (compound != null) { + int farmBlockOrdinal = compound.getInteger("FarmBlock"); + if (farmBlockOrdinal < EnumFarmBlock.values().length) + return EnumFarmBlock.values()[farmBlockOrdinal]; + } + + return EnumFarmBlock.BRICK_STONE; + } + } + + public TileFarm() { + this.structureLogic = Farmables.farmInterface.createFarmStructureLogic(this); + } + + /* GUI */ + @Override + public void openGui(EntityPlayer player) { + if (this.isMaster()) + player.openGui(ForestryAPI.instance, GuiId.MultiFarmGUI.ordinal(), worldObj, xCoord, yCoord, zCoord); + else if (this.hasMaster()) + player.openGui(ForestryAPI.instance, GuiId.MultiFarmGUI.ordinal(), worldObj, masterX, masterY, masterZ); + } + + /* SAVING & LOADING */ + @Override + public void readFromNBT(NBTTagCompound nbttagcompound) { + super.readFromNBT(nbttagcompound); + + this.isMaster = nbttagcompound.getBoolean("IsMaster"); + this.masterX = nbttagcompound.getInteger("MasterX"); + this.masterY = nbttagcompound.getInteger("MasterY"); + this.masterZ = nbttagcompound.getInteger("MasterZ"); + + farmBlock = EnumFarmBlock.getFromCompound(nbttagcompound); + + // Init for master state + if (isMaster) + makeMaster(); + + if (inventory != null) + inventory.readFromNBT(nbttagcompound); + + structureLogic.readFromNBT(nbttagcompound); + } + + @Override + public void writeToNBT(NBTTagCompound nbttagcompound) { + super.writeToNBT(nbttagcompound); + + nbttagcompound.setBoolean("IsMaster", isMaster); + nbttagcompound.setInteger("MasterX", masterX); + nbttagcompound.setInteger("MasterY", masterY); + nbttagcompound.setInteger("MasterZ", masterZ); + + farmBlock.saveToCompound(nbttagcompound); + + if (inventory != null) + inventory.writeToNBT(nbttagcompound); + + structureLogic.writeToNBT(nbttagcompound); + } + + /* UPDATING */ + @Override + public void initialize() { + } + + @Override + public void updateEntity() { + + if (!Proxies.common.isSimulating(worldObj)) + updateClientSide(); + else { + + if (!isInited) { + initialize(); + isInited = true; + } + + // Periodic validation if needed + if (worldObj.getTotalWorldTime() % 200 == 0 && (!isIntegratedIntoStructure() || isMaster())) + validateStructure(); + + updateServerSide(); + } + } + + protected void updateServerSide() { + } + + protected void updateClientSide() { + } + + /* CONSTRUCTION MATERIAL */ + EnumFarmBlock farmBlock = EnumFarmBlock.BRICK_STONE; + protected int fixedType = -1; + + public void setFarmBlock(EnumFarmBlock block) { + farmBlock = block; + sendNetworkUpdate(); + } + + public EnumFarmBlock getFarmBlock() { + return farmBlock; + } + + @SideOnly(Side.CLIENT) + public IIcon getIcon(int side, int meta) { + /* + * if(fixedType >= 0) return farmBlock.getIcon(fixedType); + * + * int type = 0; if (meta == 1) type = TYPE_BAND; + * + * if (meta == 0 && side == 2) type = TYPE_REVERSE; else if (meta == 0 && (side == 0 || side == 1)) type = TYPE_TOP; + * + * return farmBlock.getIcon(type); + */ + return null; + } + + /* INVENTORY MANAGMENT */ + protected TileInventoryAdapter inventory; + + protected abstract void createInventory(); + + /* TILEFORESTRY */ + @Override + public PacketPayload getPacketPayload() { + PacketPayload payload = new PacketPayload(0, 1); + payload.shortPayload[0] = (short) farmBlock.ordinal(); + return payload; + } + + @Override + public void fromPacketPayload(PacketPayload payload) { + EnumFarmBlock farmType = EnumFarmBlock.values()[payload.shortPayload[0]]; + if (this.farmBlock != farmType) { + this.farmBlock = farmType; + worldObj.func_147479_m(xCoord, yCoord, zCoord); + } + } + + /* ITILESTRUCTURE */ + IStructureLogic structureLogic; + private boolean isMaster; + private int masterX, masterZ; + private int masterY = -99; + + @Override + public String getTypeUID() { + return structureLogic.getTypeUID(); + } + + @Override + public void validateStructure() { + structureLogic.validateStructure(); + } + + @Override + public void makeMaster() { + setCentralTE(null); + this.isMaster = true; + + if (inventory == null) + createInventory(); + } + + @Override + public void onStructureReset() { + setCentralTE(null); + if (worldObj.getBlockMetadata(xCoord, yCoord, zCoord) == 1) + worldObj.setBlockMetadataWithNotify(xCoord, yCoord, zCoord, 0, 0); + isMaster = false; + worldObj.markBlockForUpdate(xCoord, yCoord, zCoord); + } + + @Override + public ITileStructure getCentralTE() { + + if (!isIntegratedIntoStructure()) + return null; + + if (!isMaster) { + TileEntity tile = worldObj.getTileEntity(masterX, masterY, masterZ); + if (tile instanceof ITileStructure) { + ITileStructure master = (ITileStructure) worldObj.getTileEntity(masterX, masterY, masterZ); + if (master.isMaster()) + return master; + else + return null; + } else + return null; + } else + return this; + + } + + private boolean isSameTile(TileEntity tile) { + return tile.xCoord == xCoord && tile.yCoord == yCoord && tile.zCoord == zCoord; + } + + @Override + public void setCentralTE(TileEntity tile) { + if (tile == null || tile == this || isSameTile(tile)) { + this.masterX = this.masterZ = 0; + this.masterY = -99; + return; + } + + this.isMaster = false; + this.masterX = tile.xCoord; + this.masterY = tile.yCoord; + this.masterZ = tile.zCoord; + + worldObj.markBlockForUpdate(xCoord, yCoord, zCoord); + } + + @Override + public boolean isMaster() { + return isMaster; + } + + protected boolean hasMaster() { + return this.masterY >= 0; + } + + @Override + public IInventory getInventory() { + return inventory; + } + + @Override + public boolean isIntegratedIntoStructure() { + return isMaster || this.masterY >= 0; + } + + @Override + public void registerListener(IFarmListener listener) { + } + + @Override + public void removeListener(IFarmListener listener) { + } + + @Override + public String getInventoryName() { + return "Farm"; + } + + /* INTERACTION */ + @Override + public boolean isUseableByPlayer(EntityPlayer player) { + return Utils.isUseableByPlayer(player, this, worldObj, xCoord, yCoord, zCoord); + } +} diff --git a/forestry_common/farming/forestry/farming/gadgets/TileFarmPlain.java b/forestry_common/farming/forestry/farming/gadgets/TileFarmPlain.java new file mode 100755 index 000000000..60c2c876d --- /dev/null +++ b/forestry_common/farming/forestry/farming/gadgets/TileFarmPlain.java @@ -0,0 +1,965 @@ +/******************************************************************************* + * Copyright 2011-2014 by SirSengir + * + * This work is licensed under a Creative Commons Attribution-NonCommercial-NoDerivs 3.0 Unported License. + * + * To view a copy of this license, visit http://creativecommons.org/licenses/by-nc-nd/3.0/. + ******************************************************************************/ +package forestry.farming.gadgets; + +import java.util.ArrayList; +import java.util.Arrays; +import java.util.Collection; +import java.util.LinkedHashSet; +import java.util.Map; +import java.util.Set; +import java.util.Stack; +import java.util.TreeMap; + +import net.minecraft.inventory.Container; +import net.minecraft.inventory.ICrafting; +import net.minecraft.item.ItemStack; +import net.minecraft.nbt.NBTTagCompound; +import net.minecraft.tileentity.TileEntity; +import net.minecraft.world.World; +import net.minecraft.world.biome.BiomeGenBase; + +import net.minecraftforge.common.util.ForgeDirection; +import net.minecraftforge.fluids.FluidContainerRegistry.FluidContainerData; +import net.minecraftforge.fluids.FluidStack; + +import forestry.api.circuits.ChipsetManager; +import forestry.api.circuits.ICircuitBoard; +import forestry.api.core.EnumHumidity; +import forestry.api.core.EnumTemperature; +import forestry.api.farming.ICrop; +import forestry.api.farming.IFarmComponent; +import forestry.api.farming.IFarmHousing; +import forestry.api.farming.IFarmListener; +import forestry.api.farming.IFarmLogic; +import forestry.api.farming.IFarmable; +import forestry.core.EnumErrorCode; +import forestry.core.GameMode; +import forestry.core.config.Config; +import forestry.core.config.Defaults; +import forestry.core.interfaces.IClimatised; +import forestry.core.interfaces.IHintSource; +import forestry.core.interfaces.ISocketable; +import forestry.core.proxy.Proxies; +import forestry.core.utils.DelayTimer; +import forestry.core.utils.ForestryTank; +import forestry.core.utils.InventoryAdapter; +import forestry.core.utils.LiquidHelper; +import forestry.core.utils.StackUtils; +import forestry.core.utils.TileInventoryAdapter; +import forestry.core.utils.Vect; +import forestry.farming.FarmTarget; +import forestry.farming.logic.FarmLogicArboreal; +import forestry.plugins.PluginFarming; + +public class TileFarmPlain extends TileFarm implements IFarmHousing, ISocketable, IClimatised, IHintSource { + + public static final int SLOT_RESOURCES_1 = 0; + public static final int SLOT_GERMLINGS_1 = 6; + public static final int SLOT_PRODUCTION_1 = 12; + public static final int SLOT_COUNT_RESERVOIRS = 6; + public static final int SLOT_COUNT_PRODUCTION = 8; + + public static final int SLOT_FERTILIZER = 20; + public static final int SLOT_CAN = 21; + + public static final int SLOT_COUNT = 22; + + public static final FluidStack STACK_WATER = LiquidHelper.getLiquid(Defaults.LIQUID_WATER, 1); + + public static final int DELAY_HYDRATION = 100; + public static final float RAINFALL_MODIFIER_CAP = 15f; + public static final int BUFFER_FERTILIZER = 200; + + private IFarmLogic[] farmLogics = new IFarmLogic[4]; + + private TreeMap targets; + private int allowedExtent = 0; + private final DelayTimer checkTimer = new DelayTimer(); + + private final InventoryAdapter sockets = new InventoryAdapter(1, "sockets"); + + private ForestryTank liquidTank = new ForestryTank(Defaults.PROCESSOR_TANK_CAPACITY); + + private IFarmLogic harvestProvider; // The farm logic which supplied the pending crops. + private final Stack pendingCrops = new Stack(); + private final Stack pendingProduce = new Stack(); + private int storedFertilizer; + private int fertilizerValue = 2000; + + private boolean stage = false; + + private int biomeId; + private float temperature; + private float humidity; + + private int hydrationDelay = 0; + private int ticksSinceRainfall = 0; + + public TileFarmPlain() { + fertilizerValue = GameMode.getGameMode().getIntegerSetting("farms.fertilizer.value"); + } + + /* SAVING & LOADING */ + @Override + public void readFromNBT(NBTTagCompound nbttagcompound) { + super.readFromNBT(nbttagcompound); + + storedFertilizer = nbttagcompound.getInteger("StoredFertilizer"); + hydrationDelay = nbttagcompound.getInteger("HydrationDelay"); + ticksSinceRainfall = nbttagcompound.getInteger("TicksSinceRainfall"); + sockets.readFromNBT(nbttagcompound); + + refreshFarmLogics(); + + liquidTank = new ForestryTank(Defaults.PROCESSOR_TANK_CAPACITY); + if (nbttagcompound.hasKey("LiquidTank")) + liquidTank.readFromNBT(nbttagcompound.getCompoundTag("LiquidTank")); + } + + @Override + public void writeToNBT(NBTTagCompound nbttagcompound) { + super.writeToNBT(nbttagcompound); + + sockets.writeToNBT(nbttagcompound); + nbttagcompound.setInteger("StoredFertilizer", storedFertilizer); + nbttagcompound.setInteger("HydrationDelay", hydrationDelay); + nbttagcompound.setInteger("TicksSinceRainfall", ticksSinceRainfall); + + NBTTagCompound NBTresourceSlot = new NBTTagCompound(); + liquidTank.writeToNBT(NBTresourceSlot); + nbttagcompound.setTag("LiquidTank", NBTresourceSlot); + + } + + /* UPDATING */ + @Override + public void initialize() { + setBiomeInformation(); + } + + @Override + protected void updateServerSide() { + super.updateServerSide(); + + if (!isMaster()) + return; + + if (worldObj.isRaining()) { + if (hydrationDelay > 0) + hydrationDelay--; + else + ticksSinceRainfall = 0; + } else { + hydrationDelay = DELAY_HYDRATION; + if (ticksSinceRainfall < Integer.MAX_VALUE) + ticksSinceRainfall++; + } + + if (worldObj.getTotalWorldTime() % 20 * 10 != 0) + return; + + // Check if we have suitable items waiting in the item slot + if (inventory.getStackInSlot(SLOT_CAN) != null) { + FluidContainerData container = LiquidHelper.getLiquidContainer(inventory.getStackInSlot(SLOT_CAN)); + if (container != null && LiquidHelper.isLiquid(Defaults.LIQUID_WATER, container.fluid)) { + + inventory.setInventorySlotContents(SLOT_CAN, StackUtils.replenishByContainer(this, inventory.getStackInSlot(SLOT_CAN), container, liquidTank)); + if (inventory.getStackInSlot(SLOT_CAN).stackSize <= 0) + inventory.setInventorySlotContents(SLOT_CAN, null); + } + } + + } + + private void setBiomeInformation() { + BiomeGenBase biome = worldObj.getBiomeGenForCoords(xCoord, zCoord); + this.biomeId = biome.biomeID; + this.temperature = biome.temperature; + this.humidity = biome.rainfall; + setErrorState(EnumErrorCode.OK); + } + + private void createTargets() { + + targets = new TreeMap(); + + int groundY = yCoord - 1; + allowedExtent = 0; + + for (ForgeDirection direction : ForgeDirection.VALID_DIRECTIONS) { + if (direction == ForgeDirection.UP || direction == ForgeDirection.DOWN) + continue; + // System.out.println(String.format("Master at %s/%s/%s:%s", xCoord, yCoord, zCoord, groundY)); + ArrayList potential = new ArrayList(); + + int xDistance = 0; + int zDistance = 0; + Vect candidate = new Vect(xCoord, groundY, zCoord); + + // Determine distance from master TE + while (true) { + xDistance += direction.offsetX; + zDistance += direction.offsetZ; + // System.out.println(String.format("New offset for %s: x:%s z:%s", direction, xDistance, zDistance)); + // System.out.println(String.format("Validating for %s: x:%s y:%s z:%s", direction, xCoord + xDistance, groundY, zCoord + zDistance)); + + TileEntity tile = worldObj.getTileEntity(xCoord + xDistance, groundY, zCoord + zDistance); + if (tile == null) + // System.out.println("NUll TE"); + break; + if (!(tile instanceof IFarmComponent)) + // System.out.println("Not instaceof of farm component"); + break; + + candidate = new Vect(xCoord + xDistance, groundY, zCoord + zDistance); + } + // System.out.println(String.format("Determined distance for %s at %s.", direction, candidate)); + + // Determine block to start search from + ForgeDirection search; + if (direction.offsetX != 0) + search = ForgeDirection.SOUTH; + else + search = ForgeDirection.EAST; + + int xOffset = 0; + int zOffset = 0; + Vect start = candidate; + while (true) { + xOffset += search.offsetX; + zOffset += search.offsetZ; + + TileEntity tile = worldObj.getTileEntity(candidate.x + xOffset, candidate.y, candidate.z + zOffset); + if (tile == null) + break; + if (!(tile instanceof IFarmComponent)) + break; + + start = new Vect(candidate.x + xOffset, candidate.y, candidate.z + zOffset); + } + // System.out.println(String.format("Determined start block for %s at %s.", direction, candidate)); + + ForgeDirection reverse = search.getOpposite(); + ForgeDirection tocenter = direction.getOpposite(); + Vect last = new Vect(start.x + direction.offsetX, start.y, start.z + direction.offsetZ); + potential.add(new FarmTarget(last)); + while (true) { + // Switch to next potential block in the farm. + last = new Vect(last.x + reverse.offsetX, last.y, last.z + reverse.offsetZ); + // Check validity. + TileEntity tile = worldObj.getTileEntity(last.x + tocenter.offsetX, last.y, last.z + tocenter.offsetZ); + + // break if we have reached the end of the farm's length. + if (tile == null) + break; + if (!(tile instanceof IFarmComponent)) + break; + + potential.add(new FarmTarget(last)); + } + + // System.out.println(String.format("Adding %s to %s", potential.size(), direction)); + + // Set the maximum allowed extent. + if (potential.size() + 1 > allowedExtent) + allowedExtent = potential.size() + 1; + targets.put(direction, potential.toArray(new FarmTarget[0])); + } + + // Fill out the corners + // System.out.println("Trying to round corners"); + TreeMap cache = new TreeMap(); + + for (Map.Entry entry : targets.entrySet()) { + ForgeDirection direction = entry.getKey(); + // If the count of possible targets does matches the allowedExtent, we are on the long side and will not process + if (direction == ForgeDirection.SOUTH || direction == ForgeDirection.NORTH) { + cache.put(entry.getKey(), entry.getValue()); + continue; + } + + // Set start and direction to search + ArrayList targ = new ArrayList(Arrays.asList(entry.getValue())); + int sidecount = targ.size(); + + FarmTarget start = entry.getValue()[0]; + ForgeDirection search = ForgeDirection.SOUTH; + int cornerShift = 0; + if (!Config.squareFarms) + cornerShift = 1; + // System.out.println(String.format("Processing start at %s for direction %s.", start.getStart(), direction)); + + for (int i = cornerShift; i < allowedExtent + 1; i++) { + FarmTarget corner = new FarmTarget(new Vect(start.getStart().x + search.offsetX * i, start.getStart().y, start.getStart().z + search.offsetZ + * i)); + if (!Config.squareFarms) { + corner.setLimit(allowedExtent - i); + // System.out.println(String.format("Setting %s at extent %s", corner.getStart().toString(), corner.getExtent())); + if (corner.getLimit() > 0) + targ.add(0, corner); + } else + targ.add(0, corner); + } + + search = search.getOpposite(); + for (int i = sidecount; i < sidecount + allowedExtent - cornerShift; i++) { + FarmTarget corner = new FarmTarget(new Vect(start.getStart().x + search.offsetX * i, start.getStart().y, start.getStart().z + search.offsetZ + * i)); + if (!Config.squareFarms) + corner.setLimit(sidecount + allowedExtent - 1 - i); + // System.out.println(String.format("Setting %s at extent %s", corner.getStart().toString(), corner.getExtent())); + targ.add(corner); + } + + cache.put(entry.getKey(), targ.toArray(new FarmTarget[0])); + } + + targets = cache; + } + + private void setExtents() { + + for (Map.Entry entry : targets.entrySet()) { + ForgeDirection direction = entry.getKey(); + for (FarmTarget target : entry.getValue()) { + + int yOffset = 0; + for (yOffset = 2; yOffset > -3; yOffset--) { + Vect position = new Vect(target.getStart().x, target.getStart().y + yOffset, target.getStart().z); + if (StructureLogicFarm.bricks.contains(worldObj.getBlock(position.x, position.y, position.z))) + break; + } + target.setYOffset(yOffset + 1); + + int extent = 0; + // Determine extent limit + int limit = allowedExtent; + if (target.getLimit() > 0) + limit = target.getLimit(); + + // Determine extent + for (extent = 0; extent < limit; extent++) { + Vect position = new Vect(target.getStart().x + direction.offsetX * extent, target.getStart().y + yOffset, target.getStart().z + + direction.offsetZ * extent); + if (!StructureLogicFarm.bricks.contains(worldObj.getBlock(position.x, position.y, position.z))) + break; + } + + target.setExtent(extent); + } + } + } + + @Override + protected void createInventory() { + inventory = new TileInventoryAdapter(this, SLOT_COUNT, "Items"); + } + + @Override + public boolean doWork() { + + setBiomeInformation(); + + // System.out.println("Starting doWork()"); + if (targets == null) { + createTargets(); + setExtents(); + } else if (checkTimer.delayPassed(worldObj, 400)) + setExtents(); + + if (inventory == null) + createInventory(); + + // System.out.println("Targets set"); + if (tryAddPending()) + return true; + + // System.out.println("Nothing pending added."); + // Abort if we still have produce waiting. + if (!pendingProduce.isEmpty()) { + setErrorState(EnumErrorCode.NOSPACE); + return false; + } + + // System.out.println("Product queue empty."); + if (storedFertilizer <= BUFFER_FERTILIZER) { + replenishFertilizer(); + if (storedFertilizer <= 0) { + setErrorState(EnumErrorCode.NOFERTILIZER); + return false; + } + } + + // Cull queued crops. + if (!pendingCrops.isEmpty()) + if (cullCrop(pendingCrops.peek(), harvestProvider)) { + pendingCrops.pop(); + return true; + } else + return false; + + // Cultivation and collection + boolean consumedEnergy = false; + boolean hasFarmland = false; + boolean hasFertilizer = false; + boolean hasLiquid = false; + + cycle: for (Map.Entry entry : targets.entrySet()) { + if (farmLogics.length <= entry.getKey().ordinal() - 2 || farmLogics[entry.getKey().ordinal() - 2] == null) + continue; + + boolean didWork = false; + + IFarmLogic logic = farmLogics[entry.getKey().ordinal() - 2]; + + // Allow listeners to cancel this cycle. + for (IFarmListener listener : eventHandlers) + if (listener.cancelTask(logic, entry.getKey())) + continue cycle; + + // Always try to collect windfall first. + if (doCollection(logic)) + didWork = true; + else + for (int i = 0; i < entry.getValue().length; i++) { + + FarmTarget target = entry.getValue()[i]; + if (target.getExtent() <= 0) + continue; + else + hasFarmland = true; + + if (!stage) { + + // Check fertilizer and water + if (!hasFertilizer(logic.getFertilizerConsumption())) + continue; + else + hasFertilizer = true; + + FluidStack liquid = LiquidHelper.getLiquid(Defaults.LIQUID_WATER, logic.getWaterConsumption(getHydrationModifier())); + if (liquid.amount > 0 && !hasLiquid(liquid)) + continue; + else + hasLiquid = true; + + if (doCultivationPhase(logic, target, entry.getKey())) { + // Remove fertilizer and water + removeFertilizer(logic.getFertilizerConsumption()); + removeLiquid(liquid); + + didWork = true; + } + + } else { + hasFertilizer = true; + hasLiquid = true; + didWork = doHarvestPhase(logic, target, entry.getKey()); + } + + if (didWork) + break; + } + + if (didWork) { + consumedEnergy = true; + break; + } + } + + if (consumedEnergy) + setErrorState(EnumErrorCode.OK); + else if (!hasFarmland) + setErrorState(EnumErrorCode.NOFARMLAND); + else if (!hasFertilizer) + setErrorState(EnumErrorCode.NOFERTILIZER); + else if (!hasLiquid) + setErrorState(EnumErrorCode.NOLIQUID); + else + setErrorState(EnumErrorCode.OK); + // Farms alternate between cultivation and harvest. + stage = !stage; + return consumedEnergy; + } + + private boolean doCultivationPhase(IFarmLogic logic, FarmTarget target, ForgeDirection direction) { + + if (logic.cultivate(target.getStart().x, target.getStart().y + target.getYOffset(), target.getStart().z, direction, target.getExtent())) { + for (IFarmListener listener : eventHandlers) + listener.hasCultivated(logic, target.getStart().x, target.getStart().y, target.getStart().z, direction, target.getExtent()); + return true; + } + + return false; + } + + private boolean doHarvestPhase(IFarmLogic logic, FarmTarget target, ForgeDirection direction) { + + Collection next = logic.harvest(target.getStart().x, target.getStart().y + target.getYOffset(), target.getStart().z, direction, + target.getExtent()); + if (next == null || next.size() <= 0) + return false; + + // Let event handlers know. + for (IFarmListener listener : eventHandlers) + listener.hasScheduledHarvest(next, logic, target.getStart().x, target.getStart().y + target.getYOffset(), target.getStart().z, direction, + target.getExtent()); + + pendingCrops.addAll(next); + harvestProvider = logic; + return true; + } + + private boolean doCollection(IFarmLogic logic) { + + Collection collected = logic.collect(); + if (collected == null || collected.size() <= 0) + return false; + + // Let event handlers know. + for (IFarmListener listener : eventHandlers) + listener.hasCollected(collected, logic); + + for (ItemStack produce : collected) { + + // Germlings try to go into germling slots first. + if (logic.isAcceptedGermling(produce)) + produce.stackSize -= inventory.addStack(produce, SLOT_GERMLINGS_1, SLOT_COUNT_RESERVOIRS, false, true); + + if (produce.stackSize <= 0) + continue; + produce.stackSize -= inventory.addStack(produce, SLOT_PRODUCTION_1, SLOT_COUNT_PRODUCTION, false, true); + if (produce.stackSize <= 0) + continue; + + pendingProduce.push(produce); + } + + return true; + } + + private boolean cullCrop(ICrop crop, IFarmLogic provider) { + + // Let event handlers handle the harvest first. + for (IFarmListener listener : eventHandlers) + if (listener.beforeCropHarvest(crop)) + return true; + + // Check fertilizer + if (!hasFertilizer(provider.getFertilizerConsumption())) { + setErrorState(EnumErrorCode.NOFERTILIZER); + return false; + } + + // Check water + FluidStack liquid = LiquidHelper.getLiquid(Defaults.LIQUID_WATER, provider.getWaterConsumption(getHydrationModifier())); + if (liquid.amount > 0 && !hasLiquid(liquid)) { + setErrorState(EnumErrorCode.NOLIQUID); + return false; + } + + Collection harvested = crop.harvest(); + if (harvested == null) { + Proxies.log.fine("Failed to harvest crop: " + crop.toString()); + return true; + } + + // Remove fertilizer and water + removeFertilizer(provider.getFertilizerConsumption()); + removeLiquid(liquid); + + // Let event handlers handle the harvest first. + for (IFarmListener listener : eventHandlers) + listener.afterCropHarvest(harvested, crop); + + // Stow harvest. + for (ItemStack harvest : harvested) { + + // Special case germlings + for (IFarmLogic logic : farmLogics) + if (logic.isAcceptedGermling(harvest)) { + harvest.stackSize -= inventory.addStack(harvest, SLOT_GERMLINGS_1, SLOT_COUNT_RESERVOIRS, false, true); + break; + } + + // Handle the rest + if (harvest.stackSize <= 0) + continue; + + harvest.stackSize -= inventory.addStack(harvest, SLOT_PRODUCTION_1, SLOT_COUNT_PRODUCTION, false, true); + if (harvest.stackSize <= 0) + continue; + + pendingProduce.push(harvest); + } + + return true; + } + + private boolean tryAddPending() { + if (pendingProduce.isEmpty()) + return false; + + ItemStack next = pendingProduce.peek(); + if (inventory.tryAddStack(next, SLOT_PRODUCTION_1, SLOT_COUNT_PRODUCTION, true, true)) { + pendingProduce.pop(); + return true; + } + + setErrorState(EnumErrorCode.NOSPACE); + return false; + } + + /* FERTILIZER HANDLING */ + private void replenishFertilizer() { + if(fertilizerValue < 0) { + storedFertilizer += 2000; + return; + } + + ItemStack fertilizer = inventory.getStackInSlot(SLOT_FERTILIZER); + if (fertilizer == null || fertilizer.stackSize <= 0) + return; + + if (!acceptsAsFertilizer(fertilizer)) + return; + + inventory.decrStackSize(SLOT_FERTILIZER, 1); + storedFertilizer += fertilizerValue; + } + + private boolean hasFertilizer(int amount) { + if(fertilizerValue < 0) + return true; + + return storedFertilizer >= amount; + } + + private void removeFertilizer(int amount) { + + if(fertilizerValue < 0) + return; + + storedFertilizer -= amount; + if (storedFertilizer < 0) + storedFertilizer = 0; + } + + public int getStoredFertilizerScaled(int scale) { + if (storedFertilizer == 0) + return 0; + + return (storedFertilizer * scale) / (fertilizerValue + BUFFER_FERTILIZER); + } + + /* STRUCTURE HANDLING */ + @Override + public void makeMaster() { + super.makeMaster(); + if (liquidTank == null) + liquidTank = new ForestryTank(Defaults.PROCESSOR_TANK_CAPACITY); + refreshFarmLogics(); + } + + @Override + public void onStructureReset() { + super.onStructureReset(); + } + + public ForestryTank getTank() { + return liquidTank; + } + + @Override + public void setFarmLogic(ForgeDirection direction, IFarmLogic logic) { + farmLogics[direction.ordinal() - 2] = logic; + } + + @Override + public void resetFarmLogic(ForgeDirection direction) { + farmLogics[direction.ordinal() - 2] = new FarmLogicArboreal(this); + } + + public IFarmLogic[] getFarmLogics() { + return farmLogics; + } + + private void refreshFarmLogics() { + + farmLogics = new IFarmLogic[] { new FarmLogicArboreal(this), new FarmLogicArboreal(this), new FarmLogicArboreal(this), new FarmLogicArboreal(this) }; + + // See whether we have socketed stuff. + ItemStack chip = sockets.getStackInSlot(0); + if (chip != null) { + ICircuitBoard chipset = ChipsetManager.circuitRegistry.getCircuitboard(chip); + if (chipset != null) + chipset.onLoad(this); + } + } + + /* ISOCKETABLE */ + @Override + public int getSocketCount() { + return sockets.getSizeInventory(); + } + + @Override + public ItemStack getSocket(int slot) { + return sockets.getStackInSlot(slot); + } + + @Override + public void setSocket(int slot, ItemStack stack) { + + if (stack != null && !ChipsetManager.circuitRegistry.isChipset(stack)) + return; + + // Dispose correctly of old chipsets + if (sockets.getStackInSlot(slot) != null) + if (ChipsetManager.circuitRegistry.isChipset(sockets.getStackInSlot(slot))) { + ICircuitBoard chipset = ChipsetManager.circuitRegistry.getCircuitboard(sockets.getStackInSlot(slot)); + if (chipset != null) + chipset.onRemoval(this); + } + + if (stack == null) { + sockets.setInventorySlotContents(slot, stack); + refreshFarmLogics(); + return; + } + + sockets.setInventorySlotContents(slot, stack); + + ICircuitBoard chipset = ChipsetManager.circuitRegistry.getCircuitboard(stack); + if (chipset != null) + chipset.onInsertion(this); + } + + /* IFARMHOUSING */ + @Override + public World getWorld() { + return worldObj; + } + + @Override + public boolean hasResources(ItemStack[] resources) { + return inventory.contains(resources, SLOT_RESOURCES_1, SLOT_COUNT_RESERVOIRS); + } + + @Override + public void removeResources(ItemStack[] resources) { + inventory.removeResources(resources, SLOT_RESOURCES_1, SLOT_COUNT_RESERVOIRS); + } + + @Override + public boolean hasLiquid(FluidStack liquid) { + return liquidTank.getFluidAmount() >= liquid.amount && liquidTank.getFluid().isFluidEqual(liquid); + } + + @Override + public void removeLiquid(FluidStack liquid) { + liquidTank.drain(liquid.amount, true); + } + + public boolean hasGermlings(ItemStack[] germlings) { + return inventory.contains(germlings, SLOT_GERMLINGS_1, SLOT_COUNT_RESERVOIRS); + } + + @Override + public boolean plantGermling(IFarmable germling, World world, int x, int y, int z) { + + for (int i = SLOT_GERMLINGS_1; i < SLOT_GERMLINGS_1 + SLOT_COUNT_RESERVOIRS; i++) { + if (inventory.getStackInSlot(i) == null) + continue; + if (!germling.isGermling(inventory.getStackInSlot(i))) + continue; + + if (!germling.plantSaplingAt(inventory.getStackInSlot(i), world, x, y, z)) + continue; + + inventory.decrStackSize(i, 1); + return true; + } + return false; + } + + /* IFARMCOMPONENT */ + private final Set eventHandlers = new LinkedHashSet(); + + @Override + public boolean hasFunction() { + return false; + } + + @Override + public void registerListener(IFarmListener listener) { + eventHandlers.add(listener); + } + + @Override + public void removeListener(IFarmListener listener) { + eventHandlers.remove(listener); + } + + @Override + public boolean acceptsAsGermling(ItemStack itemstack) { + if (itemstack == null) + return false; + if (farmLogics == null) + return false; + + for (IFarmLogic logic : farmLogics) + if (logic.isAcceptedGermling(itemstack)) + return true; + + return false; + } + + @Override + public boolean acceptsAsResource(ItemStack itemstack) { + if (itemstack == null) + return false; + if (farmLogics == null) + return false; + + for (IFarmLogic logic : farmLogics) + if (logic.isAcceptedResource(itemstack)) + return true; + + return false; + } + + @Override + public boolean acceptsAsFertilizer(ItemStack itemstack) { + if (itemstack == null) + return false; + + return StackUtils.isIdenticalItem(PluginFarming.farmFertilizer, itemstack); + } + + int[] coords; + int[] offset; + int[] area; + + @Override + public int[] getCoords() { + if (coords == null) + coords = new int[] { xCoord, yCoord, zCoord }; + return coords; + } + + @Override + public int[] getOffset() { + if (offset == null) + offset = new int[] { -10, -2, -10 }; + return offset; + } + + @Override + public int[] getArea() { + if (area == null) + area = new int[] { 21, 13, 21 }; + return area; + } + + /* NETWORK GUI */ + public void getGUINetworkData(int i, int j) { + + switch (i) { + case 0: + storedFertilizer = j; + break; + case 3: + this.temperature = (float) j / 100; + break; + case 4: + this.humidity = (float) j / 100; + break; + case 5: + ticksSinceRainfall = j; + break; + } + } + + public void sendGUINetworkData(Container container, ICrafting iCrafting) { + iCrafting.sendProgressBarUpdate(container, 0, storedFertilizer); + iCrafting.sendProgressBarUpdate(container, 3, Math.round(temperature * 100)); + iCrafting.sendProgressBarUpdate(container, 4, Math.round(humidity * 100)); + iCrafting.sendProgressBarUpdate(container, 5, ticksSinceRainfall); + } + + /* ICLIMATISED */ + public float getHydrationModifier() { + return getHydrationTempModifier() * getHydrationHumidModifier() * getHydrationRainfallModifier(); + } + + public float getHydrationTempModifier() { + return temperature > 0.8f ? temperature : 0.8f; + } + + public float getHydrationHumidModifier() { + float mod = 1 / humidity; + return mod < 2.0f ? mod : 2.0f; + } + + public float getHydrationRainfallModifier() { + float mod = (float) ticksSinceRainfall / 24000; + return mod > 0.5f ? mod < RAINFALL_MODIFIER_CAP ? mod : RAINFALL_MODIFIER_CAP : 0.5f; + } + + public double getDrought() { + return Math.round(((double) ticksSinceRainfall / 24000) * 10) / 10.; + } + + @Override + public boolean isClimatized() { + return true; + } + + @Override + public EnumTemperature getTemperature() { + if (EnumTemperature.isBiomeHellish(biomeId)) + return EnumTemperature.HELLISH; + + return EnumTemperature.getFromValue(getExactTemperature()); + } + + @Override + public EnumHumidity getHumidity() { + return EnumHumidity.getFromValue(getExactHumidity()); + } + + @Override + public float getExactTemperature() { + return temperature; + } + + @Override + public float getExactHumidity() { + return humidity; + } + + /* IHINTSOURCE */ + @Override + public boolean hasHints() { + return Config.hints.get("farm").length > 0; + } + + @Override + public String[] getHints() { + return Config.hints.get("farm"); + } + + /* IOWNABLE */ + @Override + public boolean isOwnable() { + return true; + } + +} diff --git a/forestry_common/farming/forestry/farming/gadgets/TileGearbox.java b/forestry_common/farming/forestry/farming/gadgets/TileGearbox.java new file mode 100755 index 000000000..cfbd5e618 --- /dev/null +++ b/forestry_common/farming/forestry/farming/gadgets/TileGearbox.java @@ -0,0 +1,119 @@ +/******************************************************************************* + * Copyright 2011-2014 by SirSengir + * + * This work is licensed under a Creative Commons Attribution-NonCommercial-NoDerivs 3.0 Unported License. + * + * To view a copy of this license, visit http://creativecommons.org/licenses/by-nc-nd/3.0/. + ******************************************************************************/ +package forestry.farming.gadgets; + +import net.minecraft.nbt.NBTTagCompound; + +import net.minecraftforge.common.util.ForgeDirection; + +import buildcraft.api.power.PowerHandler; +import buildcraft.api.power.PowerHandler.PowerReceiver; +import buildcraft.api.power.PowerHandler.Type; + +import forestry.api.core.ITileStructure; +import forestry.api.farming.IFarmHousing; +import forestry.core.GameMode; +import forestry.core.interfaces.IPowerHandler; + +public class TileGearbox extends TileFarm implements IPowerHandler { + + public static int WORK_CYCLES = 4; + public static int MIN_ENERGY_RECEIVED = 5; + public static int MAX_ENERGY_RECEIVED = 20; + public static int MIN_ACTIVATION_ENERGY = 5; + public static int MAX_ENERGY = 1000; + private int activationDelay = 0; + private int previousDelays = 0; + private int workCounter; + + public TileGearbox() { + powerProvider = new PowerHandler(this, Type.MACHINE); + powerProvider.configurePowerPerdition(0, 100); + powerProvider.configure(MIN_ENERGY_RECEIVED, + Math.round(MAX_ENERGY_RECEIVED * GameMode.getGameMode().getFloatSetting("energy.demand.modifier")), + Math.round(MIN_ACTIVATION_ENERGY * GameMode.getGameMode().getFloatSetting("energy.demand.modifier")), + Math.round(MAX_ENERGY * GameMode.getGameMode().getFloatSetting("energy.demand.modifier"))); + + fixedType = TYPE_GEARS; + } + + @Override + protected void createInventory() { + } + + @Override + public boolean hasFunction() { + return true; + } + + /* SAVING & LOADING */ + @Override + public void readFromNBT(NBTTagCompound nbttagcompound) { + super.readFromNBT(nbttagcompound); + powerProvider.readFromNBT(nbttagcompound); + + activationDelay = nbttagcompound.getInteger("ActivationDelay"); + previousDelays = nbttagcompound.getInteger("PrevDelays"); + } + + @Override + public void writeToNBT(NBTTagCompound nbttagcompound) { + super.writeToNBT(nbttagcompound); + powerProvider.writeToNBT(nbttagcompound); + + nbttagcompound.setInteger("ActivationDelay", activationDelay); + nbttagcompound.setInteger("PrevDelays", previousDelays); + } + + /* IPOWERRECEPTOR */ + PowerHandler powerProvider; + + @Override + public PowerReceiver getPowerReceiver(ForgeDirection side) { + return powerProvider.getPowerReceiver(); + } + + @Override + public PowerHandler getPowerHandler() { + return powerProvider; + } + + @Override + protected void updateServerSide() { + super.updateServerSide(); + + if (activationDelay > 0) { + activationDelay--; + return; + } + + if (workCounter >= WORK_CYCLES && worldObj.getTotalWorldTime() % 5 == 0) { + ITileStructure central = getCentralTE(); + if (!(central instanceof IFarmHousing)) + return; + + if (((IFarmHousing) central).doWork()) { + workCounter = 0; + previousDelays = 0; + } else { + // If the central TE doesn't have work, we add to the activation delay to throttle the CPU usage. + activationDelay = 10 * previousDelays < 120 ? 10 * previousDelays : 120; + previousDelays++; // First delay is free! + } + } + } + + @Override + public void doWork(PowerHandler workProvider) { + // Hard limit to 4 cycles / second. + if (workCounter < WORK_CYCLES) { + powerProvider.useEnergy(MIN_ACTIVATION_ENERGY, MIN_ACTIVATION_ENERGY, true); + workCounter++; + } + } +} diff --git a/forestry_common/farming/forestry/farming/gadgets/TileHatch.java b/forestry_common/farming/forestry/farming/gadgets/TileHatch.java new file mode 100755 index 000000000..00cbe06a9 --- /dev/null +++ b/forestry_common/farming/forestry/farming/gadgets/TileHatch.java @@ -0,0 +1,339 @@ +/******************************************************************************* + * Copyright 2011-2014 by SirSengir + * + * This work is licensed under a Creative Commons Attribution-NonCommercial-NoDerivs 3.0 Unported License. + * + * To view a copy of this license, visit http://creativecommons.org/licenses/by-nc-nd/3.0/. + ******************************************************************************/ +package forestry.farming.gadgets; + +import java.util.ArrayList; +import java.util.LinkedList; + +import net.minecraft.entity.player.EntityPlayer; +import net.minecraft.inventory.IInventory; +import net.minecraft.inventory.ISidedInventory; +import net.minecraft.item.ItemStack; + +import net.minecraftforge.common.util.ForgeDirection; +import net.minecraftforge.fluids.FluidContainerRegistry; + +import buildcraft.api.gates.ITrigger; + +import forestry.api.core.ITileStructure; +import forestry.core.utils.BlockUtil; +import forestry.core.utils.InventoryAdapter; +import forestry.core.utils.StackUtils; +import forestry.core.utils.Utils; +import forestry.plugins.PluginFarming; + +public class TileHatch extends TileFarm implements ISidedInventory { + + public TileHatch() { + fixedType = TYPE_HATCH; + } + + @Override + public boolean hasFunction() { + return true; + } + + @Override + protected void createInventory() { + } + + @Override + protected void updateServerSide() { + if (worldObj.getTotalWorldTime() % 40 == 0) + dumpStash(); + } + + /* AUTO-EJECTING */ + protected void dumpStash() { + + if (!hasMaster()) + return; + + ArrayList pipes = new ArrayList(); + ForgeDirection[] tmp = BlockUtil.getPipeDirections(worldObj, Coords(), ForgeDirection.UP); + for (int i = 0; i < tmp.length; ++i) { + pipes.add(tmp[i]); + } + + if (pipes.size() > 0) + dumpToPipe(pipes); + else { + IInventory[] inventories = BlockUtil.getAdjacentInventories(worldObj, Coords(), ForgeDirection.UP); + dumpToInventory(inventories); + } + } + + private void dumpToPipe(ArrayList pipes) { + + ItemStack[] products = extractItem(true, ForgeDirection.DOWN, 1); + for (int i = 0; i < products.length; i++) + while (products[i].stackSize > 0) + BlockUtil.putFromStackIntoPipe(this, pipes, products[i]); + + } + + private void dumpToInventory(IInventory[] inventories) { + + ITileStructure central = getCentralTE(); + if (central == null) + return; + IInventory inv = central.getInventory(); + + for (int i = TileFarmPlain.SLOT_PRODUCTION_1; i < TileFarmPlain.SLOT_PRODUCTION_1 + TileFarmPlain.SLOT_COUNT_PRODUCTION; i++) { + if (inv.getStackInSlot(i) == null) + continue; + + ItemStack stack = inv.getStackInSlot(i); + + if (stack.stackSize <= 0) + continue; + + for (int j = 0; j < inventories.length; j++) { + + // Don't dump in arboretums! + if (inventories[j].getSizeInventory() < 4) + continue; + + // Get complete inventory (for double chests) + IInventory inventory = Utils.getChest(inventories[j]); + if (inventory instanceof ISidedInventory) { + ISidedInventory sidedInventory = (ISidedInventory)inventory; + int[] slots = sidedInventory.getAccessibleSlotsFromSide(ForgeDirection.UP.ordinal()); + for (int sl = 0; sl < slots.length; ++sl) { + StackUtils.stowInInventory(stack, sidedInventory, true, sl, 1); + } + } + else { + StackUtils.stowInInventory(stack, inventory, true); + if (stack.stackSize <= 0) { + inv.setInventorySlotContents(i, null); + break; + } + } + } + } + + } + + /* IINVENTORY */ + @Override + public InventoryAdapter getInternalInventory() { + return (InventoryAdapter)getStructureInventory(); + } + + private IInventory getStructureInventory() { + + if (hasMaster()) { + ITileStructure central = getCentralTE(); + if (central != null) + return central.getInventory(); + } + + return null; + } + + @Override + public int getSizeInventory() { + IInventory inv = getStructureInventory(); + if (inv != null) + return inv.getSizeInventory(); + else + return 0; + } + + @Override + public ItemStack getStackInSlot(int slotIndex) { + IInventory inv = getStructureInventory(); + if (inv != null) + return inv.getStackInSlot(slotIndex); + else + return null; + } + + @Override + public ItemStack decrStackSize(int slotIndex, int amount) { + IInventory inv = getStructureInventory(); + if (inv != null) + return inv.decrStackSize(slotIndex, amount); + else + return null; + } + + @Override + public ItemStack getStackInSlotOnClosing(int slotIndex) { + IInventory inv = getStructureInventory(); + if (inv != null) + return inv.getStackInSlotOnClosing(slotIndex); + else + return null; + } + + @Override + public void setInventorySlotContents(int slotIndex, ItemStack itemstack) { + IInventory inv = getStructureInventory(); + if (inv != null) + inv.setInventorySlotContents(slotIndex, itemstack); + } + + @Override + public int getInventoryStackLimit() { + IInventory inv = getStructureInventory(); + if (inv != null) + return inv.getInventoryStackLimit(); + else + return 0; + } + + @Override + protected boolean canTakeStackFromSide(int slotIndex, ItemStack itemstack, int side) { + + if(!super.canTakeStackFromSide(slotIndex, itemstack, side)) + return false; + + if(slotIndex >= TileFarmPlain.SLOT_PRODUCTION_1 && slotIndex < TileFarmPlain.SLOT_PRODUCTION_1 + TileFarmPlain.SLOT_COUNT_PRODUCTION) + return true; + + return false; + } + + @Override + protected boolean canPutStackFromSide(int slotIndex, ItemStack itemstack, int side) { + + if (!hasMaster()) + return false; + + ITileStructure struct = getCentralTE(); + if (!(struct instanceof TileFarmPlain)) + return false; + + if(!super.canPutStackFromSide(slotIndex, itemstack, side)) + return false; + + TileFarmPlain housing = (TileFarmPlain) struct; + if (slotIndex == TileFarmPlain.SLOT_FERTILIZER && housing.acceptsAsFertilizer(itemstack)) + return true; + if (slotIndex >= TileFarmPlain.SLOT_RESOURCES_1 && slotIndex < TileFarmPlain.SLOT_RESOURCES_1 + TileFarmPlain.SLOT_COUNT_RESERVOIRS + && housing.acceptsAsResource(itemstack)) + return true; + if (slotIndex >= TileFarmPlain.SLOT_GERMLINGS_1 && slotIndex < TileFarmPlain.SLOT_GERMLINGS_1 + TileFarmPlain.SLOT_COUNT_RESERVOIRS + && housing.acceptsAsGermling(itemstack)) + return true; + if(slotIndex == TileFarmPlain.SLOT_CAN) + return FluidContainerRegistry.isFilledContainer(itemstack); + + return false; + } + + @Override + public void openInventory() { + } + + @Override + public void closeInventory() { + } + + /** + * TODO: just a specialsource workaround + */ + @Override + public boolean isUseableByPlayer(EntityPlayer player) { + return super.isUseableByPlayer(player); + } + + /** + * TODO: just a specialsource workaround + */ + @Override + public boolean hasCustomInventoryName() { + return super.hasCustomInventoryName(); + } + + /** + * TODO: just a specialsource workaround + */ + @Override + public boolean isItemValidForSlot(int slotIndex, ItemStack itemstack) { + return super.isItemValidForSlot(slotIndex, itemstack); + } + + /** + * TODO: just a specialsource workaround + */ + @Override + public boolean canInsertItem(int i, ItemStack itemstack, int j) { + return super.canInsertItem(i, itemstack, j); + } + + /** + * TODO: just a specialsource workaround + */ + @Override + public boolean canExtractItem(int i, ItemStack itemstack, int j) { + return super.canExtractItem(i, itemstack, j); + } + + /** + * TODO: just a specialsource workaround + */ + @Override + public int[] getAccessibleSlotsFromSide(int side) { + return super.getAccessibleSlotsFromSide(side); + } + + public ItemStack[] extractItem(boolean doRemove, ForgeDirection from, int maxItemCount) { + + IInventory inv; + if (hasMaster()) { + ITileStructure central = getCentralTE(); + if (central == null) + return new ItemStack[0]; + inv = getCentralTE().getInventory(); + } else + return StackUtils.EMPTY_STACK_ARRAY; + + ItemStack product = null; + + for (int i = TileFarmPlain.SLOT_PRODUCTION_1; i < TileFarmPlain.SLOT_PRODUCTION_1 + TileFarmPlain.SLOT_COUNT_PRODUCTION; i++) { + if (inv.getStackInSlot(i) == null) + continue; + + ItemStack stack = inv.getStackInSlot(i); + + if (doRemove) + product = inv.decrStackSize(i, 1); + else { + product = stack.copy(); + product.stackSize = 1; + } + break; + } + + if (product != null) + return new ItemStack[] { product }; + else + return StackUtils.EMPTY_STACK_ARRAY; + } + + /* ITRIGGERPROVIDER */ + @Override + public LinkedList getCustomTriggers() { + if (!hasMaster()) + return null; + + LinkedList list = new LinkedList(); + list.add(PluginFarming.lowResourceLiquid50); + list.add(PluginFarming.lowResourceLiquid25); + list.add(PluginFarming.lowSoil128); + list.add(PluginFarming.lowSoil64); + list.add(PluginFarming.lowSoil32); + list.add(PluginFarming.lowFertilizer50); + list.add(PluginFarming.lowFertilizer25); + return list; + } + +} diff --git a/forestry_common/farming/forestry/farming/gadgets/TileValve.java b/forestry_common/farming/forestry/farming/gadgets/TileValve.java new file mode 100755 index 000000000..50e9494a1 --- /dev/null +++ b/forestry_common/farming/forestry/farming/gadgets/TileValve.java @@ -0,0 +1,71 @@ +/******************************************************************************* + * Copyright 2011-2014 by SirSengir + * + * This work is licensed under a Creative Commons Attribution-NonCommercial-NoDerivs 3.0 Unported License. + * + * To view a copy of this license, visit http://creativecommons.org/licenses/by-nc-nd/3.0/. + ******************************************************************************/ +package forestry.farming.gadgets; + +import net.minecraftforge.common.util.ForgeDirection; +import net.minecraftforge.fluids.FluidStack; + +import forestry.core.interfaces.ILiquidTankContainer; +import forestry.core.utils.ForestryTank; + +public class TileValve extends TileFarm implements ILiquidTankContainer { + + public TileValve() { + fixedType = TYPE_VALVE; + } + + /* TILEFARM */ + @Override + public boolean hasFunction() { + return true; + } + + @Override + protected void createInventory() { + } + + /* ILIQUIDTANKCONTAINER */ + private ForestryTank getMasterTank() { + if (!isIntegratedIntoStructure() || !hasMaster()) + return null; + + TileFarmPlain central = (TileFarmPlain) getCentralTE(); + if (central == null) + return null; + + return central.getTank(); + } + + @Override + public int fill(ForgeDirection from, FluidStack resource, boolean doFill) { + ForestryTank tank = getMasterTank(); + if (tank == null) + return 0; + + return tank.fill(resource, doFill); + } + + @Override + public FluidStack drain(ForgeDirection from, int maxDrain, boolean doDrain) { + ForestryTank tank = getMasterTank(); + if (tank == null) + return null; + + return tank.drain(maxDrain, doDrain); + } + + @Override + public ForestryTank[] getTanks() { + ForestryTank tank = getMasterTank(); + if (tank == null) + return ForestryTank.FAKETANK_ARRAY; + + return new ForestryTank[] { tank }; + } + +} diff --git a/forestry_common/farming/forestry/farming/gui/ContainerFarm.java b/forestry_common/farming/forestry/farming/gui/ContainerFarm.java new file mode 100755 index 000000000..ea36e3f17 --- /dev/null +++ b/forestry_common/farming/forestry/farming/gui/ContainerFarm.java @@ -0,0 +1,177 @@ +/******************************************************************************* + * Copyright 2011-2014 by SirSengir + * + * This work is licensed under a Creative Commons Attribution-NonCommercial-NoDerivs 3.0 Unported License. + * + * To view a copy of this license, visit http://creativecommons.org/licenses/by-nc-nd/3.0/. + ******************************************************************************/ +package forestry.farming.gui; + + +import java.util.HashMap; +import java.util.Map; + +import net.minecraft.entity.player.EntityPlayerMP; +import net.minecraft.entity.player.InventoryPlayer; +import net.minecraft.inventory.ICrafting; +import net.minecraft.inventory.IInventory; +import net.minecraft.inventory.Slot; +import net.minecraft.item.ItemStack; +import net.minecraft.nbt.NBTTagCompound; + +import forestry.api.farming.IFarmLogic; +import forestry.core.gui.ContainerSocketed; +import forestry.core.gui.slots.SlotCustom; +import forestry.core.gui.slots.SlotForestry; +import forestry.core.gui.slots.SlotLiquidContainer; +import forestry.core.gui.slots.SlotOutput; +import forestry.core.network.PacketTankUpdate; +import forestry.core.proxy.Proxies; +import forestry.core.utils.ForestryTank; +import forestry.core.utils.TileInventoryAdapter; +import forestry.farming.gadgets.TileFarmPlain; +import forestry.plugins.PluginFarming; + +public class ContainerFarm extends ContainerSocketed { + + private class SlotResources extends SlotForestry { + + private final IFarmLogic[] logics; + + public SlotResources(IInventory inventory, IFarmLogic[] logics, int slotIndex, int xPos, int yPos) { + super(inventory, slotIndex, xPos, yPos); + this.logics = logics; + } + + @Override + public boolean isItemValid(ItemStack stack) { + for (IFarmLogic logic : logics) { + if (logic != null && logic.isAcceptedResource(stack)) + return true; + } + return false; + } + } + + private class SlotGermlings extends SlotForestry { + + private final IFarmLogic[] logics; + + public SlotGermlings(IInventory inventory, IFarmLogic[] logics, int slotIndex, int xPos, int yPos) { + super(inventory, slotIndex, xPos, yPos); + this.logics = logics; + } + + @Override + public boolean isItemValid(ItemStack stack) { + for (IFarmLogic logic : logics) { + if (logic != null && logic.isAcceptedGermling(stack)) + return true; + } + return false; + } + } + TileFarmPlain tile; + + public ContainerFarm(InventoryPlayer playerinventory, TileFarmPlain tile) { + super(playerinventory, tile); + + this.tile = tile; + + IInventory inventory = tile.getInventory(); + // Tile will not have an inventory client side. + if (inventory == null) + inventory = new TileInventoryAdapter(tile, TileFarmPlain.SLOT_COUNT, "Items"); + + // Resources + for (int i = 0; i < 3; i++) { + for (int j = 0; j < 2; j++) { + addSlot(new SlotResources(inventory, tile.getFarmLogics(), TileFarmPlain.SLOT_RESOURCES_1 + j + i * 2, 123 + j * 18, 22 + i * 18)); + } + } + + // Germlings + for (int i = 0; i < 3; i++) { + for (int j = 0; j < 2; j++) { + addSlot(new SlotGermlings(inventory, tile.getFarmLogics(), TileFarmPlain.SLOT_GERMLINGS_1 + j + i * 2, 164 + j * 18, 22 + i * 18)); + } + } + + // Production 1 + for (int i = 0; i < 2; i++) { + for (int j = 0; j < 2; j++) { + addSlot(new SlotOutput(inventory, TileFarmPlain.SLOT_PRODUCTION_1 + j + i * 2, 123 + j * 18, 86 + i * 18)); + } + } + + // Production 2 + for (int i = 0; i < 2; i++) { + for (int j = 0; j < 2; j++) { + addSlot(new SlotOutput(inventory, TileFarmPlain.SLOT_PRODUCTION_1 + 4 + j + i * 2, 164 + j * 18, 86 + i * 18)); + } + } + + // Fertilizer + addSlot(new SlotCustom(inventory, TileFarmPlain.SLOT_FERTILIZER, 63, 95, PluginFarming.farmFertilizer)); + // Can Slot + addSlot(new SlotLiquidContainer(inventory, TileFarmPlain.SLOT_CAN, 15, 95)); + + // Player inventory + for (int i = 0; i < 3; i++) { + for (int j = 0; j < 9; j++) { + addSlot(new Slot(playerinventory, j + i * 9 + 9, 28 + j * 18, 138 + i * 18)); + } + } + // Player hotbar + for (int i = 0; i < 9; i++) { + addSlot(new Slot(playerinventory, i, 28 + i * 18, 196)); + } + } + + @Override + public void updateProgressBar(int i, int j) { + tile.getGUINetworkData(i, j); + } + private Map syncedFluids = new HashMap(); + + @Override + public void detectAndSendChanges() { + super.detectAndSendChanges(); + + for (int i = 0; i < crafters.size(); i++) { + tile.sendGUINetworkData(this, (ICrafting) crafters.get(i)); + } + + ForestryTank tank = tile.getTank(); + + // If null has been synced + if (tank.getFluid() == null && getTank(0).getFluidAmount() <= 0) + return; + // If fluid has been synced + if (tank.getFluid() != null && tank.getFluid().isFluidStackIdentical(getTank(0).getFluid())) + return; + + for (int j = 0; j < this.crafters.size(); ++j) { + if (this.crafters.get(j) instanceof EntityPlayerMP) { + EntityPlayerMP player = (EntityPlayerMP) this.crafters.get(j); + Proxies.net.sendToPlayer(new PacketTankUpdate(0, tank), player); + } + } + syncedFluids.put(0, new ForestryTank(tank.getFluid() == null ? null : tank.getFluid().copy(), tank.getCapacity())); + + } + + @Override + public void onTankUpdate(NBTTagCompound nbt) { + int tankID = nbt.getByte("tank"); + int capacity = nbt.getShort("capacity"); + ForestryTank tank = new ForestryTank(capacity); + tank.readFromNBT(nbt); + syncedFluids.put(tankID, tank); + } + + @Override + public ForestryTank getTank(int slot) { + return syncedFluids.get(slot) == null ? ForestryTank.FAKETANK : syncedFluids.get(slot); + } +} diff --git a/forestry_common/farming/forestry/farming/gui/GuiFarm.java b/forestry_common/farming/forestry/farming/gui/GuiFarm.java new file mode 100755 index 000000000..2b688f69c --- /dev/null +++ b/forestry_common/farming/forestry/farming/gui/GuiFarm.java @@ -0,0 +1,162 @@ +/******************************************************************************* + * Copyright 2011-2014 by SirSengir + * + * This work is licensed under a Creative Commons Attribution-NonCommercial-NoDerivs 3.0 Unported License. + * + * To view a copy of this license, visit http://creativecommons.org/licenses/by-nc-nd/3.0/. + ******************************************************************************/ +package forestry.farming.gui; + +import net.minecraft.entity.player.EntityPlayer; +import net.minecraft.init.Items; +import net.minecraft.util.IIcon; + +import org.lwjgl.opengl.GL11; + +import forestry.api.farming.IFarmLogic; +import forestry.core.config.Defaults; +import forestry.core.gui.GuiForestry; +import forestry.core.gui.Ledger; +import forestry.core.gui.WidgetManager; +import forestry.core.gui.tooltips.ToolTip; +import forestry.core.gui.widgets.SocketWidget; +import forestry.core.gui.widgets.TankWidget; +import forestry.core.gui.widgets.Widget; +import forestry.core.proxy.Proxies; +import forestry.core.utils.StringUtil; +import forestry.farming.gadgets.TileFarmPlain; + +public class GuiFarm extends GuiForestry { + + protected class FarmLedger extends Ledger { + + public FarmLedger() { + super(ledgerManager); + maxHeight = 118; + overlayColor = fontColor.get("ledger.farm.background"); + } + + @Override + public void draw(int x, int y) { + + // Draw background + drawBackground(x, y); + + // Draw icon + drawIcon(Items.water_bucket.getIconFromDamage(0), x + 3, y + 4); + + if (!isFullyOpened()) + return; + + fontRendererObj.drawStringWithShadow(StringUtil.localize("gui.hydration"), x + 22, y + 8, fontColor.get("ledger.power.header")); + fontRendererObj.drawStringWithShadow(StringUtil.localize("gui.hydr.heat") + ":", x + 22, y + 20, fontColor.get("ledger.power.subheader")); + fontRendererObj.drawString(StringUtil.floatAsPercent(farm.getHydrationTempModifier()), x + 22, y + 32, fontColor.get("ledger.power.text")); + fontRendererObj.drawStringWithShadow(StringUtil.localize("gui.hydr.humid") + ":", x + 22, y + 44, fontColor.get("ledger.power.subheader")); + fontRendererObj.drawString(StringUtil.floatAsPercent(farm.getHydrationHumidModifier()), x + 22, y + 56, fontColor.get("ledger.power.text")); + fontRendererObj.drawStringWithShadow(StringUtil.localize("gui.hydr.rainfall") + ":", x + 22, y + 68, fontColor.get("ledger.power.subheader")); + fontRendererObj.drawString(StringUtil.floatAsPercent(farm.getHydrationRainfallModifier()) + " (" + farm.getDrought() + " d)", x + 22, y + 80, + fontColor.get("ledger.power.text")); + fontRendererObj.drawStringWithShadow(StringUtil.localize("gui.hydr.overall") + ":", x + 22, y + 92, fontColor.get("ledger.power.subheader")); + fontRendererObj.drawString(StringUtil.floatAsPercent(farm.getHydrationModifier()), x + 22, y + 104, fontColor.get("ledger.power.text")); + + } + + @Override + public String getTooltip() { + return StringUtil.floatAsPercent(farm.getHydrationModifier()) + " " + StringUtil.localize("gui.hydration"); + } + } + + private class FarmLogicSlot extends Widget { + + private final int slot; + + public FarmLogicSlot(WidgetManager manager, int xPos, int yPos, int slot) { + super(manager, xPos, yPos); + this.slot = slot; + } + + private IFarmLogic getLogic() { + return farm.getFarmLogics()[slot]; + } + + private IIcon getIconIndex() { + if (getLogic() == null) + return null; + return getLogic().getIcon(); + } + + @Override + public void draw(int startX, int startY) { + if (getLogic() == null) + return; + + if (getIconIndex() != null) { + GL11.glDisable(GL11.GL_LIGHTING); + Proxies.common.bindTexture(getLogic().getSpriteSheet()); + manager.gui.drawTexturedModelRectFromIcon(startX + xPos, startY + yPos, getIconIndex(), 16, 16); + GL11.glEnable(GL11.GL_LIGHTING); + } + + } + + @Override + public ToolTip getToolTip() { + return toolTip; + } + protected final ToolTip toolTip = new ToolTip(250) { + @Override + public void refresh() { + toolTip.clear(); + if (getLogic() == null) + return; + toolTip.add(getLogic().getName()); + toolTip.add("Fertilizer: " + getLogic().getFertilizerConsumption()); + toolTip.add("Water: " + getLogic().getWaterConsumption(farm.getHydrationModifier())); + } + }; + } + private final TileFarmPlain farm; + + public GuiFarm(EntityPlayer player, TileFarmPlain tile) { + super(Defaults.TEXTURE_PATH_GUI + "/mfarm.png", new ContainerFarm(player.inventory, tile), tile); + + widgetManager.add(new TankWidget(widgetManager, 15, 19, 0).setOverlayOrigin(216, 18)); + + widgetManager.add(new SocketWidget(widgetManager, 69, 40, tile, 0)); + + widgetManager.add(new FarmLogicSlot(widgetManager, 69, 22, 0)); + widgetManager.add(new FarmLogicSlot(widgetManager, 69, 58, 1)); + widgetManager.add(new FarmLogicSlot(widgetManager, 51, 40, 2)); + widgetManager.add(new FarmLogicSlot(widgetManager, 87, 40, 3)); + + this.xSize = 216; + this.ySize = 220; + this.tile = tile; + this.farm = tile; + } + + @Override + protected void initLedgers(Object inventory) { + super.initLedgers(inventory); + ledgerManager.insert(new FarmLedger()); + } + + @Override + protected void drawGuiContainerForegroundLayer(int mouseX, int mouseY) { + super.drawGuiContainerForegroundLayer(mouseX, mouseY); + String title = StringUtil.localize("Farm"); + this.fontRendererObj.drawString(title, getCenteredOffset(title), 6, fontColor.get("gui.title")); + } + + @Override + protected void drawGuiContainerBackgroundLayer(float var1, int mouseX, int mouseY) { + super.drawGuiContainerBackgroundLayer(var1, mouseX, mouseY); + + // Fuel remaining + int fertilizerRemain = tile.getStoredFertilizerScaled(16); + if (fertilizerRemain > 0) + drawTexturedModalRect(guiLeft + 81, guiTop + 94 + 17 - fertilizerRemain, xSize, 17 - fertilizerRemain, 4, fertilizerRemain); + + } +} diff --git a/forestry_common/farming/forestry/farming/items/ItemFarmBlock.java b/forestry_common/farming/forestry/farming/items/ItemFarmBlock.java new file mode 100755 index 000000000..1c9d0e271 --- /dev/null +++ b/forestry_common/farming/forestry/farming/items/ItemFarmBlock.java @@ -0,0 +1,50 @@ +/******************************************************************************* + * Copyright 2011-2014 by SirSengir + * + * This work is licensed under a Creative Commons Attribution-NonCommercial-NoDerivs 3.0 Unported License. + * + * To view a copy of this license, visit http://creativecommons.org/licenses/by-nc-nd/3.0/. + ******************************************************************************/ +package forestry.farming.items; + +import java.util.List; + +import net.minecraft.block.Block; +import net.minecraft.entity.player.EntityPlayer; +import net.minecraft.item.ItemBlock; +import net.minecraft.item.ItemStack; + +import forestry.core.gadgets.IStructureBlockItem; +import forestry.core.utils.StringUtil; +import forestry.farming.gadgets.TileFarm.EnumFarmBlock; + +public class ItemFarmBlock extends ItemBlock implements IStructureBlockItem { + public ItemFarmBlock(Block block) { + super(block); + setHasSubtypes(true); + } + + @Override + public int getMetadata(int i) { + return i; + } + + @SuppressWarnings({ "rawtypes", "unchecked" }) + @Override + public void addInformation(ItemStack itemstack, EntityPlayer player, List info, boolean par4) { + if (!itemstack.hasTagCompound()) + return; + + info.add(EnumFarmBlock.getFromCompound(itemstack.getTagCompound()).getName()); + } + + @Override + public String getItemStackDisplayName(ItemStack itemstack) { + return StringUtil.localize(getUnlocalizedName(itemstack)); + } + + @Override + public String getUnlocalizedName(ItemStack itemstack) { + return "tile.ffarm." + itemstack.getItemDamage(); + } +} diff --git a/forestry_common/farming/forestry/farming/logic/Crop.java b/forestry_common/farming/forestry/farming/logic/Crop.java new file mode 100755 index 000000000..460711a08 --- /dev/null +++ b/forestry_common/farming/forestry/farming/logic/Crop.java @@ -0,0 +1,64 @@ +/******************************************************************************* + * Copyright 2011-2014 by SirSengir + * + * This work is licensed under a Creative Commons Attribution-NonCommercial-NoDerivs 3.0 Unported License. + * + * To view a copy of this license, visit http://creativecommons.org/licenses/by-nc-nd/3.0/. + ******************************************************************************/ +package forestry.farming.logic; + +import java.util.Collection; + +import net.minecraft.block.Block; +import net.minecraft.item.ItemStack; +import net.minecraft.world.World; + +import forestry.api.farming.ICrop; +import forestry.core.config.Defaults; +import forestry.core.utils.Vect; + +public abstract class Crop implements ICrop { + + protected World world; + protected Vect position; + + public Crop(World world, Vect position) { + this.world = world; + this.position = position; + } + + protected final void setBlock(Vect position, Block block, int meta) { + world.setBlock(position.x, position.y, position.z, block, meta, Defaults.FLAG_BLOCK_SYNCH); + } + + protected final void clearBlock(Vect position) { + world.setBlockToAir(position.x, position.y, position.z); + if (world.getTileEntity(position.x, position.y, position.z) != null) + world.setTileEntity(position.x, position.y, position.z, null); + } + + protected final Block getBlock(Vect position) { + return world.getBlock(position.x, position.y, position.z); + } + + protected final int getBlockMeta(Vect position) { + return world.getBlockMetadata(position.x, position.y, position.z); + } + + protected final ItemStack getAsItemStack(Vect position) { + return new ItemStack(getBlock(position), 1, getBlockMeta(position)); + } + + protected abstract boolean isCrop(Vect pos); + + protected abstract Collection harvestBlock(Vect pos); + + @Override + public Collection harvest() { + if (!isCrop(position)) + return null; + + return harvestBlock(position); + } + +} diff --git a/forestry_common/farming/forestry/farming/logic/CropBlock.java b/forestry_common/farming/forestry/farming/logic/CropBlock.java new file mode 100755 index 000000000..7339374f1 --- /dev/null +++ b/forestry_common/farming/forestry/farming/logic/CropBlock.java @@ -0,0 +1,48 @@ +/******************************************************************************* + * Copyright 2011-2014 by SirSengir + * + * This work is licensed under a Creative Commons Attribution-NonCommercial-NoDerivs 3.0 Unported License. + * + * To view a copy of this license, visit http://creativecommons.org/licenses/by-nc-nd/3.0/. + ******************************************************************************/ +package forestry.farming.logic; + +import java.util.Collection; + +import net.minecraft.block.Block; +import net.minecraft.item.ItemStack; +import net.minecraft.world.World; + +import forestry.core.proxy.Proxies; +import forestry.core.utils.Vect; + +public class CropBlock extends Crop { + + Block block; + int meta; + + public CropBlock(World world, Block block, int meta, Vect position) { + super(world, position); + this.block = block; + this.meta = meta; + } + + @Override + protected boolean isCrop(Vect pos) { + return getBlock(pos) == block && getBlockMeta(pos) == meta; + } + + @Override + protected Collection harvestBlock(Vect pos) { + Collection harvested = block.getDrops(world, pos.x, pos.y, pos.z, meta, 0); + Proxies.common.addBlockDestroyEffects(world, pos.x, pos.y, pos.z, block, 0); + // Block.breakBlock() is called by vanilla itself, removing TEs. + world.setBlockToAir(pos.x, pos.y, pos.z); + return harvested; + } + + @Override + public String toString() { + return String.format("CropBlock [ position: [ %s ]; block: %s; meta: %s ]", position.toString(), block.getUnlocalizedName(), meta); + } +} diff --git a/forestry_common/farming/forestry/farming/logic/CropFruit.java b/forestry_common/farming/forestry/farming/logic/CropFruit.java new file mode 100755 index 000000000..b328dbcc5 --- /dev/null +++ b/forestry_common/farming/forestry/farming/logic/CropFruit.java @@ -0,0 +1,57 @@ +/******************************************************************************* + * Copyright 2011-2014 by SirSengir + * + * This work is licensed under a Creative Commons Attribution-NonCommercial-NoDerivs 3.0 Unported License. + * + * To view a copy of this license, visit http://creativecommons.org/licenses/by-nc-nd/3.0/. + ******************************************************************************/ +package forestry.farming.logic; + +import java.util.ArrayList; +import java.util.Collection; + +import net.minecraft.item.ItemStack; +import net.minecraft.tileentity.TileEntity; +import net.minecraft.world.World; + +import forestry.api.genetics.IFruitBearer; +import forestry.api.genetics.IFruitFamily; +import forestry.core.network.PacketFXSignal; +import forestry.core.proxy.Proxies; +import forestry.core.utils.Vect; + +public class CropFruit extends Crop { + + IFruitFamily family; + + public CropFruit(World world, Vect position, IFruitFamily family) { + super(world, position); + this.family = family; + } + + @Override + protected boolean isCrop(Vect pos) { + TileEntity tile = world.getTileEntity(pos.x, pos.y, pos.z); + if (!(tile instanceof IFruitBearer)) + return false; + IFruitBearer bearer = (IFruitBearer) tile; + if (!bearer.hasFruit()) + return false; + if (bearer.getRipeness() < 0.9f) + return false; + + return true; + } + + @Override + protected Collection harvestBlock(Vect pos) { + TileEntity tile = world.getTileEntity(pos.x, pos.y, pos.z); + if (!(tile instanceof IFruitBearer)) + return new ArrayList(); + + Proxies.common.sendFXSignal(PacketFXSignal.VisualFXType.BLOCK_DESTROY, PacketFXSignal.SoundFXType.LEAF, world, pos.x, pos.y, pos.z, + world.getBlock(pos.x, pos.y, pos.z), 0); + return ((IFruitBearer) tile).pickFruit(null); + } + +} diff --git a/forestry_common/farming/forestry/farming/logic/CropPeat.java b/forestry_common/farming/forestry/farming/logic/CropPeat.java new file mode 100755 index 000000000..c88dc1ab3 --- /dev/null +++ b/forestry_common/farming/forestry/farming/logic/CropPeat.java @@ -0,0 +1,43 @@ +/******************************************************************************* + * Copyright 2011-2014 by SirSengir + * + * This work is licensed under a Creative Commons Attribution-NonCommercial-NoDerivs 3.0 Unported License. + * + * To view a copy of this license, visit http://creativecommons.org/licenses/by-nc-nd/3.0/. + ******************************************************************************/ +package forestry.farming.logic; + +import java.util.ArrayList; +import java.util.Collection; + +import net.minecraft.init.Blocks; +import net.minecraft.item.ItemStack; +import net.minecraft.world.World; + +import forestry.core.config.ForestryBlock; +import forestry.core.config.ForestryItem; +import forestry.core.proxy.Proxies; +import forestry.core.utils.Vect; + +public class CropPeat extends Crop { + + public CropPeat(World world, Vect position) { + super(world, position); + } + + @Override + protected boolean isCrop(Vect pos) { + return getBlock(pos) == ForestryBlock.soil && (getBlockMeta(pos) & 0x03) == 1; + } + + @Override + protected Collection harvestBlock(Vect pos) { + ArrayList list = new ArrayList(); + list.add(ForestryItem.peat.getItemStack()); + + Proxies.common.addBlockDestroyEffects(world, pos.x, pos.y, pos.z, world.getBlock(pos.x, pos.y, pos.z), 0); + setBlock(pos, Blocks.dirt, 0); + return list; + } + +} diff --git a/forestry_common/farming/forestry/farming/logic/CropRubber.java b/forestry_common/farming/forestry/farming/logic/CropRubber.java new file mode 100755 index 000000000..4e4c635d0 --- /dev/null +++ b/forestry_common/farming/forestry/farming/logic/CropRubber.java @@ -0,0 +1,37 @@ +/******************************************************************************* + * Copyright 2011-2014 by SirSengir + * + * This work is licensed under a Creative Commons Attribution-NonCommercial-NoDerivs 3.0 Unported License. + * + * To view a copy of this license, visit http://creativecommons.org/licenses/by-nc-nd/3.0/. + ******************************************************************************/ +package forestry.farming.logic; + +import java.util.ArrayList; +import java.util.Collection; + +import net.minecraft.block.Block; +import net.minecraft.item.ItemStack; +import net.minecraft.world.World; + +import forestry.core.config.Defaults; +import forestry.core.proxy.Proxies; +import forestry.core.utils.Vect; +import forestry.plugins.PluginIC2; + +public class CropRubber extends CropBlock { + + public CropRubber(World world, Block block, int meta, Vect position) { + super(world, block, meta, position); + } + + @Override + protected Collection harvestBlock(Vect pos) { + Collection harvested = new ArrayList(); + harvested.add(PluginIC2.resin.copy()); + Proxies.common.addBlockDestroyEffects(world, pos.x, pos.y, pos.z, block, 0); + world.setBlock(pos.x, pos.y, pos.z, block, meta + 6, Defaults.FLAG_BLOCK_SYNCH); + return harvested; + } + +} diff --git a/forestry_common/farming/forestry/farming/logic/FarmLogic.java b/forestry_common/farming/forestry/farming/logic/FarmLogic.java new file mode 100755 index 000000000..12c35c862 --- /dev/null +++ b/forestry_common/farming/forestry/farming/logic/FarmLogic.java @@ -0,0 +1,78 @@ +/******************************************************************************* + * Copyright 2011-2014 by SirSengir + * + * This work is licensed under a Creative Commons Attribution-NonCommercial-NoDerivs 3.0 Unported License. + * + * To view a copy of this license, visit http://creativecommons.org/licenses/by-nc-nd/3.0/. + ******************************************************************************/ +package forestry.farming.logic; + +import net.minecraft.block.Block; +import net.minecraft.init.Blocks; +import net.minecraft.item.ItemStack; +import net.minecraft.util.ResourceLocation; +import net.minecraft.world.World; + +import net.minecraftforge.common.util.ForgeDirection; + +import forestry.api.farming.IFarmHousing; +import forestry.api.farming.IFarmLogic; +import forestry.core.config.Defaults; +import forestry.core.render.SpriteSheet; +import forestry.core.utils.Vect; + +public abstract class FarmLogic implements IFarmLogic { + + World world; + IFarmHousing housing; + + boolean isManual; + + public FarmLogic(IFarmHousing housing) { + this.housing = housing; + } + + public FarmLogic setManual(boolean flag) { + isManual = flag; + return this; + } + + @Override + public ResourceLocation getSpriteSheet() { + return SpriteSheet.ITEMS.getLocation(); + } + + protected final boolean isAirBlock(Vect position) { + return world.isAirBlock(position.x, position.y, position.z); + } + + protected final boolean isWaterBlock(Vect position) { + return world.getBlock(position.x, position.y, position.z) == Blocks.water; + } + + protected final boolean isWoodBlock(Vect position) { + Block block = getBlock(position); + return block.isWood(world, position.x, position.y, position.z); + } + + protected final Block getBlock(Vect position) { + return world.getBlock(position.x, position.y, position.z); + } + + protected final int getBlockMeta(Vect position) { + return world.getBlockMetadata(position.x, position.y, position.z); + } + + protected final ItemStack getAsItemStack(Vect position) { + return new ItemStack(getBlock(position), 1, getBlockMeta(position)); + } + + protected final Vect translateWithOffset(int x, int y, int z, ForgeDirection direction, int step) { + return new Vect(x + direction.offsetX * step, y + direction.offsetY * step, z + direction.offsetZ * step); + } + + protected final void setBlock(Vect position, Block block, int meta) { + world.setBlock(position.x, position.y, position.z, block, meta, Defaults.FLAG_BLOCK_SYNCH); + } + +} diff --git a/forestry_common/farming/forestry/farming/logic/FarmLogicArboreal.java b/forestry_common/farming/forestry/farming/logic/FarmLogicArboreal.java new file mode 100755 index 000000000..2a4f14ddf --- /dev/null +++ b/forestry_common/farming/forestry/farming/logic/FarmLogicArboreal.java @@ -0,0 +1,246 @@ +/******************************************************************************* + * Copyright 2011-2014 by SirSengir + * + * This work is licensed under a Creative Commons Attribution-NonCommercial-NoDerivs 3.0 Unported License. + * + * To view a copy of this license, visit http://creativecommons.org/licenses/by-nc-nd/3.0/. + ******************************************************************************/ +package forestry.farming.logic; + +import java.util.ArrayList; +import java.util.Collection; +import java.util.HashMap; +import java.util.List; +import java.util.Stack; + +import net.minecraft.entity.Entity; +import net.minecraft.entity.item.EntityItem; +import net.minecraft.init.Blocks; +import net.minecraft.item.ItemStack; +import net.minecraft.util.AxisAlignedBB; +import net.minecraft.util.IIcon; +import net.minecraft.util.ResourceLocation; + +import cpw.mods.fml.relauncher.Side; +import cpw.mods.fml.relauncher.SideOnly; + +import net.minecraftforge.common.util.ForgeDirection; + +import forestry.api.farming.Farmables; +import forestry.api.farming.ICrop; +import forestry.api.farming.IFarmHousing; +import forestry.api.farming.IFarmable; +import forestry.core.config.Defaults; +import forestry.core.config.ForestryBlock; +import forestry.core.render.SpriteSheet; +import forestry.core.utils.StackUtils; +import forestry.core.utils.Vect; + +public class FarmLogicArboreal extends FarmLogicHomogenous { + + public FarmLogicArboreal(IFarmHousing housing, ItemStack[] resource, ItemStack[] ground, ItemStack[] waste, IFarmable[] germlings) { + super(housing, resource, ground, waste, germlings); + } + + public FarmLogicArboreal(IFarmHousing housing) { + super(housing, new ItemStack[] { new ItemStack(Blocks.dirt) }, new ItemStack[] { new ItemStack(ForestryBlock.soil, 1, 0), + new ItemStack(ForestryBlock.soil, 1, Defaults.WILDCARD) }, new ItemStack[] { new ItemStack(Blocks.sand) }, Farmables.farmables.get( + "farmArboreal").toArray(new IFarmable[0])); + } + + @Override + public String getName() { + return "Managed Arboretum"; + } + + @Override + @SideOnly(Side.CLIENT) + public IIcon getIcon() { + return Blocks.sapling.getBlockTextureFromSide(0); + } + + @Override + public ResourceLocation getSpriteSheet() { + return SpriteSheet.BLOCKS.getLocation(); + } + + @Override + public int getFertilizerConsumption() { + return 10; + } + + @Override + public int getWaterConsumption(float hydrationModifier) { + return (int) (10 * hydrationModifier); + } + + @SuppressWarnings("unchecked") + @Override + public Collection collect() { + + Collection products = produce; + produce = new ArrayList(); + + Vect coords = new Vect(housing.getCoords()); + Vect area = new Vect(housing.getArea()); + Vect offset = new Vect(housing.getOffset()); + + Vect min = coords.add(offset); + Vect max = coords.add(offset).add(area); + + AxisAlignedBB harvestBox = AxisAlignedBB.getBoundingBox(min.x, min.y, min.z, max.x, max.y, max.z); + List list = housing.getWorld().getEntitiesWithinAABB(Entity.class, harvestBox); + + int i; + for (i = 0; i < list.size(); i++) { + Entity entity = list.get(i); + + if (entity instanceof EntityItem) { + EntityItem item = (EntityItem) entity; + if (!item.isDead) { + ItemStack contained = item.getEntityItem(); + if (isAcceptedGermling(contained) || isWindfall(contained)) { + produce.add(contained.copy()); + item.setDead(); + } + } + } + } + + return products; + } + + private final HashMap lastExtentsHarvest = new HashMap(); + + @Override + public Collection harvest(int x, int y, int z, ForgeDirection direction, int extent) { + + world = housing.getWorld(); + + Collection crops = null; + + Vect start = new Vect(x, y, z); + if (!lastExtentsHarvest.containsKey(start)) + lastExtentsHarvest.put(start, 0); + + int lastExtent = lastExtentsHarvest.get(start); + if (lastExtent > extent) + lastExtent = 0; + + Vect position = translateWithOffset(x, y + 1, z, direction, lastExtent); + crops = getHarvestBlocks(position); + lastExtent++; + lastExtentsHarvest.put(start, lastExtent); + + return crops; + } + + private Collection getHarvestBlocks(Vect position) { + + ArrayList seen = new ArrayList(); + Stack crops = new Stack(); + + // Determine what type we want to harvest. + IFarmable germling = null; + for (IFarmable germl : germlings) { + ICrop crop = germl.getCropAt(world, position.x, position.y, position.z); + if (crop == null) + continue; + + crops.push(crop); + seen.add(position); + germling = germl; + break; + } + + if (germling == null) + return crops; + + ArrayList candidates = processHarvestBlock(germling, crops, seen, position, position); + ArrayList temp = new ArrayList(); + while (!candidates.isEmpty()) { + for (Vect candidate : candidates) + temp.addAll(processHarvestBlock(germling, crops, seen, position, candidate)); + candidates.clear(); + candidates.addAll(temp); + temp.clear(); + } + + return crops; + } + + protected int yOffset = 0; + + private ArrayList processHarvestBlock(IFarmable germling, Stack crops, Collection seen, Vect start, Vect position) { + + ArrayList candidates = new ArrayList(); + + // Get additional candidates to return + for (int i = -1; i < 2; i++) + for (int j = yOffset; j < 2; j++) + for (int k = -1; k < 2; k++) { + Vect candidate = new Vect(position.x + i, position.y + j, position.z + k); + if (candidate.equals(position)) + continue; + if (Math.abs(candidate.x - start.x) > 5) + continue; + if (Math.abs(candidate.z - start.z) > 5) + continue; + + // See whether the given position has already been processed + boolean skip = false; + for (Vect prcs : seen) + if (candidate.equals(prcs)) { + skip = true; + break; + } + + if (skip) + continue; + + ICrop crop = germling.getCropAt(world, candidate.x, candidate.y, candidate.z); + if (crop != null) { + crops.push(crop); + candidates.add(candidate); + seen.add(candidate); + } + } + + return candidates; + } + + @Override + protected boolean maintainGermlings(int x, int ySaplings, int z, ForgeDirection direction, int extent) { + + for (int i = 0; i < extent; i++) { + Vect position = translateWithOffset(x, ySaplings, z, direction, i); + + if (isAirBlock(position)) { + //ForgeDirection reverse = direction.getOpposite(); + Vect soilBelow = new Vect(position.x, position.y - 1, position.z); + //Vect soilPrevious = new Vect(position.x * reverse.offsetX, position.y - 1, position.z * reverse.offsetZ); + for (ItemStack grnd : ground) { + if(StackUtils.isIdenticalItem(grnd, getAsItemStack(soilBelow))) + return plantSapling(position); + } + //if (!ground[0].itemID == getAsItemStack(soilPrevious).itemID && ground[0].itemID == getAsItemStack(soilBelow).itemID) + + //if (ground[0].isItemEqual(getAsItemStack(soilBelow))) + // return plantSapling(position); + } + + } + + return false; + } + + private boolean plantSapling(Vect position) { + + for (IFarmable candidate : germlings) + if (housing.plantGermling(candidate, world, position.x, position.y, position.z)) + return true; + + return false; + } + +} diff --git a/forestry_common/farming/forestry/farming/logic/FarmLogicCereal.java b/forestry_common/farming/forestry/farming/logic/FarmLogicCereal.java new file mode 100755 index 000000000..fc40135d8 --- /dev/null +++ b/forestry_common/farming/forestry/farming/logic/FarmLogicCereal.java @@ -0,0 +1,40 @@ +/******************************************************************************* + * Copyright 2011-2014 by SirSengir + * + * This work is licensed under a Creative Commons Attribution-NonCommercial-NoDerivs 3.0 Unported License. + * + * To view a copy of this license, visit http://creativecommons.org/licenses/by-nc-nd/3.0/. + ******************************************************************************/ +package forestry.farming.logic; + +import net.minecraft.init.Items; +import net.minecraft.util.IIcon; + +import cpw.mods.fml.relauncher.Side; +import cpw.mods.fml.relauncher.SideOnly; + +import forestry.api.farming.Farmables; +import forestry.api.farming.IFarmHousing; +import forestry.api.farming.IFarmable; + +public class FarmLogicCereal extends FarmLogicCrops { + + public FarmLogicCereal(IFarmHousing housing) { + super(housing, Farmables.farmables.get("farmWheat").toArray(new IFarmable[0])); + } + + @Override + public String getName() { + if (isManual) + return "Manual Farm"; + else + return "Managed Farm"; + } + + @Override + @SideOnly(Side.CLIENT) + public IIcon getIcon() { + return Items.wheat.getIconFromDamage(0); + } + +} diff --git a/forestry_common/farming/forestry/farming/logic/FarmLogicCocoa.java b/forestry_common/farming/forestry/farming/logic/FarmLogicCocoa.java new file mode 100755 index 000000000..a9eac6c82 --- /dev/null +++ b/forestry_common/farming/forestry/farming/logic/FarmLogicCocoa.java @@ -0,0 +1,219 @@ +/******************************************************************************* + * Copyright 2011-2014 by SirSengir + * + * This work is licensed under a Creative Commons Attribution-NonCommercial-NoDerivs 3.0 Unported License. + * + * To view a copy of this license, visit http://creativecommons.org/licenses/by-nc-nd/3.0/. + ******************************************************************************/ +package forestry.farming.logic; + +import java.util.ArrayList; +import java.util.Collection; +import java.util.HashMap; +import java.util.Stack; + +import net.minecraft.block.Block; +import net.minecraft.block.BlockLog; +import net.minecraft.init.Items; +import net.minecraft.item.ItemStack; +import net.minecraft.util.IIcon; + +import cpw.mods.fml.relauncher.Side; +import cpw.mods.fml.relauncher.SideOnly; + +import net.minecraftforge.common.util.ForgeDirection; + +import forestry.api.farming.ICrop; +import forestry.api.farming.IFarmHousing; +import forestry.api.farming.IFarmable; +import forestry.core.utils.Vect; + +public class FarmLogicCocoa extends FarmLogic { + + private final IFarmable cocoa = new FarmableCocoa(); + + public FarmLogicCocoa(IFarmHousing housing) { + super(housing); + } + + @Override + @SideOnly(Side.CLIENT) + public IIcon getIcon() { + return Items.dye.getIconFromDamage(3); + } + + @Override + public String getName() { + return "Cocoa Plantation"; + } + + @Override + public int getFertilizerConsumption() { + return 120; + } + + @Override + public int getWaterConsumption(float hydrationModifier) { + return (int) (20 * hydrationModifier); + } + + @Override + public boolean isAcceptedResource(ItemStack itemstack) { + return false; + } + + @Override + public boolean isAcceptedGermling(ItemStack itemstack) { + return cocoa.isGermling(itemstack); + } + + @Override + public Collection collect() { + return null; + } + + private final HashMap lastExtentsCultivation = new HashMap(); + + @Override + public boolean cultivate(int x, int y, int z, ForgeDirection direction, int extent) { + + world = housing.getWorld(); + + Vect start = new Vect(x, y, z); + if (!lastExtentsCultivation.containsKey(start)) + lastExtentsCultivation.put(start, 0); + + int lastExtent = lastExtentsCultivation.get(start); + if (lastExtent > extent) + lastExtent = 0; + + Vect position = translateWithOffset(x, y + 1, z, direction, lastExtent); + boolean result = tryPlantingCocoa(position); + + lastExtent++; + lastExtentsCultivation.put(start, lastExtent); + + return result; + } + + private final HashMap lastExtentsHarvest = new HashMap(); + + @Override + public Collection harvest(int x, int y, int z, ForgeDirection direction, int extent) { + + world = housing.getWorld(); + + Collection crops = null; + + Vect start = new Vect(x, y, z); + if (!lastExtentsHarvest.containsKey(start)) + lastExtentsHarvest.put(start, 0); + + int lastExtent = lastExtentsHarvest.get(start); + if (lastExtent > extent) + lastExtent = 0; + + Vect position = translateWithOffset(x, y + 1, z, direction, lastExtent); + crops = getHarvestBlocks(position); + lastExtent++; + lastExtentsHarvest.put(start, lastExtent); + + return crops; + } + + private boolean tryPlantingCocoa(Vect position) { + + Vect current = position; + while (isWoodBlock(current) && BlockLog.func_150165_c(getBlockMeta(current)) == 3) { + + for (ForgeDirection direction : ForgeDirection.VALID_DIRECTIONS) { + if (direction == ForgeDirection.UP || direction == ForgeDirection.DOWN) + continue; + + Vect candidate = new Vect(current.x + direction.offsetX, current.y, current.z + direction.offsetZ); + if (isAirBlock(candidate)) + return housing.plantGermling(cocoa, world, candidate.x, candidate.y, candidate.z); + } + + current = current.add(new Vect(0, 1, 0)); + if (current.y - position.y > 1) + break; + } + + return false; + } + + private Collection getHarvestBlocks(Vect position) { + + ArrayList seen = new ArrayList(); + Stack crops = new Stack(); + + // Determine what type we want to harvest. + Block block = getBlock(position); + + ICrop crop = null; + if (!block.isWood(world, position.x, position.y, position.z)) { + crop = cocoa.getCropAt(world, position.x, position.y, position.z); + if (crop == null) + return crops; + } + + if (crop != null) + crops.add(crop); + + ArrayList candidates = processHarvestBlock(crops, seen, position, position); + ArrayList temp = new ArrayList(); + while (!candidates.isEmpty() && crops.size() < 20) { + for (Vect candidate : candidates) + temp.addAll(processHarvestBlock(crops, seen, position, candidate)); + candidates.clear(); + candidates.addAll(temp); + temp.clear(); + } + // Proxies.log.finest("Logic %s at %s/%s/%s has seen %s blocks.", getClass().getName(), position.x, position.y, position.z, seen.size()); + + return crops; + } + + private ArrayList processHarvestBlock(Stack crops, Collection seen, Vect start, Vect position) { + + ArrayList candidates = new ArrayList(); + + // Get additional candidates to return + for (int i = -1; i < 2; i++) + for (int j = 0; j < 2; j++) + for (int k = -1; k < 2; k++) { + Vect candidate = new Vect(position.x + i, position.y + j, position.z + k); + if (candidate.equals(position)) + continue; + if (Math.abs(candidate.x - start.x) > 5) + continue; + if (Math.abs(candidate.z - start.z) > 5) + continue; + + // See whether the given position has already been processed + boolean skip = false; + for (Vect prcs : seen) + if (candidate.equals(prcs)) { + skip = true; + break; + } + + if (skip) + continue; + + ICrop crop = cocoa.getCropAt(world, candidate.x, candidate.y, candidate.z); + if (crop != null) { + crops.push(crop); + candidates.add(candidate); + seen.add(candidate); + } else if (isWoodBlock(candidate)) { + candidates.add(candidate); + seen.add(candidate); + } + } + + return candidates; + } + +} diff --git a/forestry_common/farming/forestry/farming/logic/FarmLogicCrops.java b/forestry_common/farming/forestry/farming/logic/FarmLogicCrops.java new file mode 100755 index 000000000..50f872b39 --- /dev/null +++ b/forestry_common/farming/forestry/farming/logic/FarmLogicCrops.java @@ -0,0 +1,137 @@ +/******************************************************************************* + * Copyright 2011-2014 by SirSengir + * + * This work is licensed under a Creative Commons Attribution-NonCommercial-NoDerivs 3.0 Unported License. + * + * To view a copy of this license, visit http://creativecommons.org/licenses/by-nc-nd/3.0/. + ******************************************************************************/ +package forestry.farming.logic; + +import java.util.ArrayList; +import java.util.Collection; +import java.util.List; +import java.util.Stack; + +import net.minecraft.entity.Entity; +import net.minecraft.entity.item.EntityItem; +import net.minecraft.init.Blocks; +import net.minecraft.item.ItemStack; +import net.minecraft.util.AxisAlignedBB; + +import net.minecraftforge.common.util.ForgeDirection; + +import forestry.api.farming.ICrop; +import forestry.api.farming.IFarmHousing; +import forestry.api.farming.IFarmable; +import forestry.core.utils.Utils; +import forestry.core.utils.Vect; + +public abstract class FarmLogicCrops extends FarmLogicWatered { + + private final IFarmable[] seeds; + + public FarmLogicCrops(IFarmHousing housing, IFarmable[] seeds) { + super(housing, new ItemStack[] { new ItemStack(Blocks.dirt) }, new ItemStack[] { new ItemStack(Blocks.farmland) }, new ItemStack[] { + new ItemStack(Blocks.dirt), new ItemStack(Blocks.grass) }); + + this.seeds = seeds; + } + + @Override + public boolean isAcceptedGermling(ItemStack itemstack) { + for (IFarmable germling : seeds) + if (germling.isGermling(itemstack)) + return true; + return false; + } + + public boolean isWindfall(ItemStack itemstack) { + for (IFarmable germling : seeds) + if (germling.isWindfall(itemstack)) + return true; + return false; + } + + @SuppressWarnings("unchecked") + @Override + public Collection collect() { + + Collection products = produce; + produce = new ArrayList(); + + Vect coords = new Vect(housing.getCoords()); + Vect area = new Vect(housing.getArea()); + Vect offset = new Vect(housing.getOffset()); + + Vect min = coords.add(offset); + Vect max = coords.add(offset).add(area); + + AxisAlignedBB harvestBox = AxisAlignedBB.getBoundingBox(min.x, min.y, min.z, max.x, max.y, max.z); + List list = housing.getWorld().getEntitiesWithinAABB(Entity.class, harvestBox); + + int i; + for (i = 0; i < list.size(); i++) { + Entity entity = list.get(i); + + if (entity instanceof EntityItem) { + EntityItem item = (EntityItem) entity; + if (!item.isDead) { + ItemStack contained = item.getEntityItem(); + if (isAcceptedGermling(contained) || isWindfall(contained)) { + produce.add(contained.copy()); + item.setDead(); + } + } + } + } + + return products; + } + + @Override + protected boolean maintainCrops(int x, int y, int z, ForgeDirection direction, int extent) { + + for (int i = 0; i < extent; i++) { + Vect position = translateWithOffset(x, y, z, direction, i); + if (!isAirBlock(position) && !Utils.isReplaceableBlock(world, position.x, position.y, position.z)) + continue; + + ItemStack below = getAsItemStack(position.add(new Vect(0, -1, 0))); + if (ground[0].getItem() != below.getItem()) + continue; + if (below.getItemDamage() <= 0) + continue; + + return trySetCrop(position); + } + + return false; + } + + private boolean trySetCrop(Vect position) { + + for (IFarmable candidate : seeds) + if (housing.plantGermling(candidate, world, position.x, position.y, position.z)) + return true; + + return false; + } + + @Override + public Collection harvest(int x, int y, int z, ForgeDirection direction, int extent) { + + world = housing.getWorld(); + + Stack crops = new Stack(); + for (int i = 0; i < extent; i++) { + Vect position = translateWithOffset(x, y + 1, z, direction, i); + for (IFarmable seed : seeds) { + ICrop crop = seed.getCropAt(world, position.x, position.y, position.z); + if (crop != null) + crops.push(crop); + } + } + return crops; + } + +} diff --git a/forestry_common/farming/forestry/farming/logic/FarmLogicGourd.java b/forestry_common/farming/forestry/farming/logic/FarmLogicGourd.java new file mode 100755 index 000000000..8d8a6f5b1 --- /dev/null +++ b/forestry_common/farming/forestry/farming/logic/FarmLogicGourd.java @@ -0,0 +1,95 @@ +/******************************************************************************* + * Copyright 2011-2014 by SirSengir + * + * This work is licensed under a Creative Commons Attribution-NonCommercial-NoDerivs 3.0 Unported License. + * + * To view a copy of this license, visit http://creativecommons.org/licenses/by-nc-nd/3.0/. + ******************************************************************************/ +package forestry.farming.logic; + +import java.util.Collection; +import java.util.Stack; + +import net.minecraft.init.Items; +import net.minecraft.item.ItemStack; +import net.minecraft.util.IIcon; + +import cpw.mods.fml.relauncher.Side; +import cpw.mods.fml.relauncher.SideOnly; + +import net.minecraftforge.common.util.ForgeDirection; + +import forestry.api.farming.Farmables; +import forestry.api.farming.ICrop; +import forestry.api.farming.IFarmHousing; +import forestry.api.farming.IFarmable; +import forestry.core.utils.Vect; + +public class FarmLogicGourd extends FarmLogic { + + private final IFarmable[] seeds; + + public FarmLogicGourd(IFarmHousing housing) { + super(housing); + seeds = Farmables.farmables.get("farmGourd").toArray(new IFarmable[0]); + } + + @Override + @SideOnly(Side.CLIENT) + public IIcon getIcon() { + return Items.melon.getIconFromDamage(0); + } + + @Override + public String getName() { + return "Gourd Farm"; + } + + @Override + public int getFertilizerConsumption() { + return 10; + } + + @Override + public int getWaterConsumption(float hydrationModifier) { + return (int) (40 * hydrationModifier); + } + + @Override + public boolean isAcceptedResource(ItemStack itemstack) { + return false; + } + + @Override + public boolean isAcceptedGermling(ItemStack itemstack) { + return false; + } + + @Override + public Collection collect() { + return null; + } + + @Override + public boolean cultivate(int x, int y, int z, ForgeDirection direction, int extent) { + return false; + } + + @Override + public Collection harvest(int x, int y, int z, ForgeDirection direction, int extent) { + + world = housing.getWorld(); + + Stack crops = new Stack(); + for (int i = 0; i < extent; i++) { + Vect position = translateWithOffset(x, y + 1, z, direction, i); + for (IFarmable seed : seeds) { + ICrop crop = seed.getCropAt(world, position.x, position.y, position.z); + if (crop != null) + crops.push(crop); + } + } + return crops; + } + +} diff --git a/forestry_common/farming/forestry/farming/logic/FarmLogicHomogenous.java b/forestry_common/farming/forestry/farming/logic/FarmLogicHomogenous.java new file mode 100755 index 000000000..f97e0d210 --- /dev/null +++ b/forestry_common/farming/forestry/farming/logic/FarmLogicHomogenous.java @@ -0,0 +1,112 @@ +/******************************************************************************* + * Copyright 2011-2014 by SirSengir + * + * This work is licensed under a Creative Commons Attribution-NonCommercial-NoDerivs 3.0 Unported License. + * + * To view a copy of this license, visit http://creativecommons.org/licenses/by-nc-nd/3.0/. + ******************************************************************************/ +package forestry.farming.logic; + +import java.util.ArrayList; + +import net.minecraft.item.ItemStack; + +import net.minecraftforge.common.util.ForgeDirection; + +import forestry.api.farming.IFarmHousing; +import forestry.api.farming.IFarmable; +import forestry.core.utils.StackUtils; +import forestry.core.utils.Utils; +import forestry.core.utils.Vect; + +public abstract class FarmLogicHomogenous extends FarmLogic { + + protected final ItemStack[] resource; + protected final ItemStack[] ground; + protected final ItemStack[] waste; + protected final IFarmable[] germlings; + + ArrayList produce = new ArrayList(); + + public FarmLogicHomogenous(IFarmHousing housing, ItemStack[] resource, ItemStack[] ground, ItemStack[] waste, IFarmable[] germlings) { + super(housing); + this.resource = resource; + this.ground = ground; + this.waste = waste; + this.germlings = germlings; + } + + @Override + public boolean isAcceptedResource(ItemStack itemstack) { + return resource[0].isItemEqual(itemstack); + } + + @Override + public boolean isAcceptedGermling(ItemStack itemstack) { + for (IFarmable germling : germlings) + if (germling.isGermling(itemstack)) + return true; + return false; + } + + public boolean isWindfall(ItemStack itemstack) { + for (IFarmable germling : germlings) + if (germling.isWindfall(itemstack)) + return true; + return false; + } + + @Override + public boolean cultivate(int x, int y, int z, ForgeDirection direction, int extent) { + world = housing.getWorld(); + + if (maintainSoil(x, y, z, direction, extent)) + return true; + + if (maintainGermlings(x, y + 1, z, direction, extent)) + return true; + + return false; + } + + private boolean maintainSoil(int x, int yGround, int z, ForgeDirection direction, int extent) { + + if (!housing.hasResources(resource)) + return false; + + cycle: for (int i = 0; i < extent; i++) { + Vect position = translateWithOffset(x, yGround, z, direction, i); + + if (!isAirBlock(position) && !Utils.isReplaceableBlock(world, position.x, position.y, position.z)) { + + ItemStack block = getAsItemStack(position); + + for (ItemStack grnd : ground) + if (StackUtils.isIdenticalItem(grnd, block)) + continue cycle; + + boolean removedWaste = false; + if (waste.length > 0) { + for(ItemStack wste : waste) { + if(!wste.isItemEqual(block)) + continue; + produce.add(wste.copy()); + removedWaste = true; + break; + } + } + if(!removedWaste) + return false; + } + + setBlock(position, StackUtils.getBlock(ground[0]), ground[0].getItemDamage()); + housing.removeResources(resource); + return true; + + } + + return false; + } + + protected abstract boolean maintainGermlings(int x, int ySaplings, int z, ForgeDirection direction, int extent); +} diff --git a/forestry_common/farming/forestry/farming/logic/FarmLogicInfernal.java b/forestry_common/farming/forestry/farming/logic/FarmLogicInfernal.java new file mode 100755 index 000000000..0dd3770b4 --- /dev/null +++ b/forestry_common/farming/forestry/farming/logic/FarmLogicInfernal.java @@ -0,0 +1,109 @@ +/******************************************************************************* + * Copyright 2011-2014 by SirSengir + * + * This work is licensed under a Creative Commons Attribution-NonCommercial-NoDerivs 3.0 Unported License. + * + * To view a copy of this license, visit http://creativecommons.org/licenses/by-nc-nd/3.0/. + ******************************************************************************/ +package forestry.farming.logic; + +import java.util.Collection; +import java.util.Stack; + +import net.minecraft.init.Blocks; +import net.minecraft.init.Items; +import net.minecraft.item.ItemStack; +import net.minecraft.util.IIcon; + +import cpw.mods.fml.relauncher.Side; +import cpw.mods.fml.relauncher.SideOnly; + +import net.minecraftforge.common.util.ForgeDirection; + +import forestry.api.farming.Farmables; +import forestry.api.farming.ICrop; +import forestry.api.farming.IFarmHousing; +import forestry.api.farming.IFarmable; +import forestry.core.utils.Utils; +import forestry.core.utils.Vect; + +public class FarmLogicInfernal extends FarmLogicHomogenous { + + public FarmLogicInfernal(IFarmHousing housing) { + super(housing, new ItemStack[] { new ItemStack(Blocks.soul_sand) }, new ItemStack[] { new ItemStack(Blocks.soul_sand) }, new ItemStack[0], + Farmables.farmables.get("farmInfernal").toArray(new IFarmable[0])); + } + + @Override + public String getName() { + return "Managed Infernal Farm"; + } + + @Override + @SideOnly(Side.CLIENT) + public IIcon getIcon() { + return Items.nether_wart.getIconFromDamage(0); + } + + @Override + public int getFertilizerConsumption() { + return 20; + } + + @Override + public int getWaterConsumption(float hydrationModifier) { + return 0; + } + + @Override + public Collection collect() { + return null; + } + + @Override + public Collection harvest(int x, int y, int z, ForgeDirection direction, int extent) { + + world = housing.getWorld(); + + Stack crops = new Stack(); + for (int i = 0; i < extent; i++) { + Vect position = translateWithOffset(x, y + 1, z, direction, i); + for (IFarmable farmable : germlings) { + ICrop crop = farmable.getCropAt(world, position.x, position.y, position.z); + if (crop != null) + crops.push(crop); + } + + } + return crops; + + } + + @Override + protected boolean maintainGermlings(int x, int y, int z, ForgeDirection direction, int extent) { + + for (int i = 0; i < extent; i++) { + Vect position = translateWithOffset(x, y, z, direction, i); + if (!isAirBlock(position) && !Utils.isReplaceableBlock(world, position.x, position.y, position.z)) + continue; + + ItemStack below = getAsItemStack(position.add(new Vect(0, -1, 0))); + if (ground[0].getItem() != below.getItem()) + continue; + + return trySetCrop(position); + } + + return false; + } + + private boolean trySetCrop(Vect position) { + + for (IFarmable candidate : germlings) + if (housing.plantGermling(candidate, world, position.x, position.y, position.z)) + return true; + + return false; + } + +} diff --git a/forestry_common/farming/forestry/farming/logic/FarmLogicOrchard.java b/forestry_common/farming/forestry/farming/logic/FarmLogicOrchard.java new file mode 100755 index 000000000..dff3be4b9 --- /dev/null +++ b/forestry_common/farming/forestry/farming/logic/FarmLogicOrchard.java @@ -0,0 +1,180 @@ +/******************************************************************************* + * Copyright 2011-2014 by SirSengir + * + * This work is licensed under a Creative Commons Attribution-NonCommercial-NoDerivs 3.0 Unported License. + * + * To view a copy of this license, visit http://creativecommons.org/licenses/by-nc-nd/3.0/. + ******************************************************************************/ +package forestry.farming.logic; + +import java.util.ArrayList; +import java.util.Collection; +import java.util.HashMap; +import java.util.Stack; + +import net.minecraft.block.Block; +import net.minecraft.item.ItemStack; +import net.minecraft.tileentity.TileEntity; +import net.minecraft.util.IIcon; + +import cpw.mods.fml.relauncher.Side; +import cpw.mods.fml.relauncher.SideOnly; + +import net.minecraftforge.common.util.ForgeDirection; + +import forestry.api.farming.ICrop; +import forestry.api.farming.IFarmHousing; +import forestry.api.genetics.IFruitBearer; +import forestry.core.config.ForestryItem; +import forestry.core.utils.Vect; + +public class FarmLogicOrchard extends FarmLogic { + + public FarmLogicOrchard(IFarmHousing housing) { + super(housing); + } + + @Override + @SideOnly(Side.CLIENT) + public IIcon getIcon() { + return ForestryItem.fruits.item().getIconFromDamage(0); + } + + @Override + public String getName() { + return "Orchard"; + } + + @Override + public int getFertilizerConsumption() { + return 10; + } + + @Override + public int getWaterConsumption(float hydrationModifier) { + return (int) (40 * hydrationModifier); + } + + @Override + public boolean isAcceptedResource(ItemStack itemstack) { + return false; + } + + @Override + public boolean isAcceptedGermling(ItemStack itemstack) { + return false; + } + + @Override + public Collection collect() { + return null; + } + + @Override + public boolean cultivate(int x, int y, int z, ForgeDirection direction, int extent) { + return false; + } + + private final HashMap lastExtents = new HashMap(); + + @Override + public Collection harvest(int x, int y, int z, ForgeDirection direction, int extent) { + + world = housing.getWorld(); + + Collection crops = null; + + Vect start = new Vect(x, y, z); + if (!lastExtents.containsKey(start)) + lastExtents.put(start, 0); + + int lastExtent = lastExtents.get(start); + if (lastExtent > extent) + lastExtent = 0; + + // Proxies.log.finest("Logic %s is searching in direction %s at %s/%s/%s with extension %s.", getClass(), direction, x, y, z, lastExtent); + + Vect position = translateWithOffset(x, y + 1, z, direction, lastExtent); + crops = getHarvestBlocks(position); + lastExtent++; + lastExtents.put(start, lastExtent); + + return crops; + } + + private Collection getHarvestBlocks(Vect position) { + + ArrayList seen = new ArrayList(); + Stack crops = new Stack(); + + // Determine what type we want to harvest. + IFruitBearer bearer = getFruitBlock(position); + Block block = getBlock(position); + if ((!block.isWood(world, position.x, position.y, position.z)) && bearer == null) + return crops; + + ArrayList candidates = processHarvestBlock(crops, seen, position, position); + ArrayList temp = new ArrayList(); + while (!candidates.isEmpty() && crops.size() < 20) { + for (Vect candidate : candidates) + temp.addAll(processHarvestBlock(crops, seen, position, candidate)); + candidates.clear(); + candidates.addAll(temp); + temp.clear(); + } + // Proxies.log.finest("Logic at %s/%s/%s has seen %s blocks.", position.x, position.y, position.z, seen.size()); + + return crops; + } + + private ArrayList processHarvestBlock(Stack crops, Collection seen, Vect start, Vect position) { + + ArrayList candidates = new ArrayList(); + + // Get additional candidates to return + for (int i = -1; i < 2; i++) + for (int j = 0; j < 2; j++) + for (int k = -1; k < 2; k++) { + Vect candidate = new Vect(position.x + i, position.y + j, position.z + k); + if (candidate.equals(position)) + continue; + if (Math.abs(candidate.x - start.x) > 5) + continue; + if (Math.abs(candidate.z - start.z) > 5) + continue; + + // See whether the given position has already been processed + boolean skip = false; + for (Vect prcs : seen) + if (candidate.equals(prcs)) { + skip = true; + break; + } + + if (skip) + continue; + + IFruitBearer bearer = getFruitBlock(candidate); + if (bearer != null && bearer.hasFruit()) { + if (bearer.getRipeness() >= 0.9f) + crops.push(new CropFruit(world, candidate, bearer.getFruitFamily())); + candidates.add(candidate); + seen.add(candidate); + } else if (this.isWoodBlock(candidate)) { + candidates.add(candidate); + seen.add(candidate); + } + } + + return candidates; + } + + private IFruitBearer getFruitBlock(Vect position) { + TileEntity tile = world.getTileEntity(position.x, position.y, position.z); + if (!(tile instanceof IFruitBearer)) + return null; + + return (IFruitBearer) tile; + } + +} diff --git a/forestry_common/farming/forestry/farming/logic/FarmLogicPeat.java b/forestry_common/farming/forestry/farming/logic/FarmLogicPeat.java new file mode 100755 index 000000000..3dd7b8747 --- /dev/null +++ b/forestry_common/farming/forestry/farming/logic/FarmLogicPeat.java @@ -0,0 +1,85 @@ +/******************************************************************************* + * Copyright 2011-2014 by SirSengir + * + * This work is licensed under a Creative Commons Attribution-NonCommercial-NoDerivs 3.0 Unported License. + * + * To view a copy of this license, visit http://creativecommons.org/licenses/by-nc-nd/3.0/. + ******************************************************************************/ +package forestry.farming.logic; + +import java.util.Collection; +import java.util.Stack; + +import net.minecraft.init.Blocks; +import net.minecraft.item.ItemStack; +import net.minecraft.util.IIcon; + +import cpw.mods.fml.relauncher.Side; +import cpw.mods.fml.relauncher.SideOnly; + +import net.minecraftforge.common.util.ForgeDirection; + +import forestry.api.farming.ICrop; +import forestry.api.farming.IFarmHousing; +import forestry.core.config.ForestryBlock; +import forestry.core.config.ForestryItem; +import forestry.core.utils.StackUtils; +import forestry.core.utils.Vect; + +public class FarmLogicPeat extends FarmLogicWatered { + + public FarmLogicPeat(IFarmHousing housing) { + super(housing, new ItemStack[] { new ItemStack(ForestryBlock.soil, 1, 1) }, + new ItemStack[] { new ItemStack(ForestryBlock.soil, 1, 1) }, new ItemStack[] { new ItemStack(Blocks.dirt), new ItemStack(Blocks.grass) }); + } + + @Override + public int getFertilizerConsumption() { + return 2; + } + + @Override + public String getName() { + if (isManual) + return "Manual Peat Bog"; + else + return "Managed Peat Bog"; + } + + @Override + public boolean isAcceptedGermling(ItemStack itemstack) { + return false; + } + + @Override + public Collection harvest(int x, int y, int z, ForgeDirection direction, int extent) { + + world = housing.getWorld(); + + Stack crops = new Stack(); + for (int i = 0; i < extent; i++) { + Vect position = translateWithOffset(x, y, z, direction, i); + ItemStack occupant = getAsItemStack(position); + + if (StackUtils.getBlock(occupant) != ForestryBlock.soil) + continue; + int type = occupant.getItemDamage() & 0x03; + int maturity = occupant.getItemDamage() >> 2; + + if (type != 1) + continue; + + if (maturity >= 3) + crops.push(new CropPeat(world, position)); + + } + return crops; + } + + @Override + @SideOnly(Side.CLIENT) + public IIcon getIcon() { + return ForestryItem.peat.item().getIconFromDamage(0); + } + +} diff --git a/forestry_common/farming/forestry/farming/logic/FarmLogicPoale.java b/forestry_common/farming/forestry/farming/logic/FarmLogicPoale.java new file mode 100755 index 000000000..b58906ce8 --- /dev/null +++ b/forestry_common/farming/forestry/farming/logic/FarmLogicPoale.java @@ -0,0 +1,106 @@ +/******************************************************************************* + * Copyright 2011-2014 by SirSengir + * + * This work is licensed under a Creative Commons Attribution-NonCommercial-NoDerivs 3.0 Unported License. + * + * To view a copy of this license, visit http://creativecommons.org/licenses/by-nc-nd/3.0/. + ******************************************************************************/ +package forestry.farming.logic; + +import java.util.Collection; +import java.util.Stack; + +import net.minecraft.init.Blocks; +import net.minecraft.init.Items; +import net.minecraft.item.ItemStack; +import net.minecraft.util.IIcon; + +import cpw.mods.fml.relauncher.Side; +import cpw.mods.fml.relauncher.SideOnly; + +import net.minecraftforge.common.util.ForgeDirection; + +import forestry.api.farming.Farmables; +import forestry.api.farming.ICrop; +import forestry.api.farming.IFarmHousing; +import forestry.api.farming.IFarmable; +import forestry.core.utils.StackUtils; +import forestry.core.utils.Vect; + +public class FarmLogicPoale extends FarmLogic { + + IFarmable[] germlings; + + public FarmLogicPoale(IFarmHousing housing) { + super(housing); + germlings = Farmables.farmables.get("farmPoales").toArray(new IFarmable[0]); + } + + @Override + @SideOnly(Side.CLIENT) + public IIcon getIcon() { + return Items.reeds.getIconFromDamage(0); + } + + @Override + public String getName() { + if (isManual) + return "Manual Reed Farm"; + else + return "Managed Reed Farm"; + } + + @Override + public int getFertilizerConsumption() { + return 10; + } + + @Override + public int getWaterConsumption(float hydrationModifier) { + return (int) (20 * hydrationModifier); + } + + @Override + public boolean isAcceptedResource(ItemStack itemstack) { + if (isManual) + return false; + + return StackUtils.equals(Blocks.sand, itemstack) || StackUtils.equals(Blocks.dirt, itemstack); + } + + @Override + public boolean isAcceptedGermling(ItemStack itemstack) { + if (isManual) + return false; + + return itemstack.getItem() == Items.reeds; + } + + @Override + public Collection collect() { + return null; + } + + @Override + public boolean cultivate(int x, int y, int z, ForgeDirection direction, int extent) { + return false; + } + + @Override + public Collection harvest(int x, int y, int z, ForgeDirection direction, int extent) { + + world = housing.getWorld(); + + Stack crops = new Stack(); + for (int i = 0; i < extent; i++) { + Vect position = translateWithOffset(x, y + 1, z, direction, i); + for (IFarmable seed : germlings) { + ICrop crop = seed.getCropAt(world, position.x, position.y, position.z); + if (crop != null) + crops.push(crop); + } + } + return crops; + } + +} diff --git a/forestry_common/farming/forestry/farming/logic/FarmLogicRubber.java b/forestry_common/farming/forestry/farming/logic/FarmLogicRubber.java new file mode 100755 index 000000000..e10d1d801 --- /dev/null +++ b/forestry_common/farming/forestry/farming/logic/FarmLogicRubber.java @@ -0,0 +1,175 @@ +/******************************************************************************* + * Copyright 2011-2014 by SirSengir + * + * This work is licensed under a Creative Commons Attribution-NonCommercial-NoDerivs 3.0 Unported License. + * + * To view a copy of this license, visit http://creativecommons.org/licenses/by-nc-nd/3.0/. + ******************************************************************************/ +package forestry.farming.logic; + +import java.util.ArrayList; +import java.util.Collection; +import java.util.HashMap; +import java.util.Stack; + +import net.minecraft.block.Block; +import net.minecraft.init.Items; +import net.minecraft.item.ItemStack; +import net.minecraft.util.IIcon; + +import cpw.mods.fml.relauncher.Side; +import cpw.mods.fml.relauncher.SideOnly; + +import net.minecraftforge.common.util.ForgeDirection; + +import forestry.api.farming.ICrop; +import forestry.api.farming.IFarmHousing; +import forestry.core.proxy.Proxies; +import forestry.core.utils.StackUtils; +import forestry.core.utils.Vect; +import forestry.plugins.PluginIC2; + +public class FarmLogicRubber extends FarmLogic { + + private boolean inActive; + + public FarmLogicRubber(IFarmHousing housing) { + super(housing); + if (PluginIC2.rubberwood == null || PluginIC2.resin == null) { + Proxies.log.warning("Failed to init a farm logic %s since IC2 was not found", getClass().getName()); + inActive = true; + } + } + + @Override + @SideOnly(Side.CLIENT) + public IIcon getIcon() { + if (!inActive) + return PluginIC2.resin.getIconIndex(); + else + return Items.gunpowder.getIconFromDamage(0); + } + + @Override + public String getName() { + return "Rubber Plantation"; + } + + @Override + public int getFertilizerConsumption() { + return 40; + } + + @Override + public int getWaterConsumption(float hydrationModifier) { + return (int) (5 * hydrationModifier); + } + + @Override + public boolean isAcceptedResource(ItemStack itemstack) { + return false; + } + + @Override + public boolean isAcceptedGermling(ItemStack itemstack) { + return false; + } + + @Override + public Collection collect() { + return null; + } + + @Override + public boolean cultivate(int x, int y, int z, ForgeDirection direction, int extent) { + return false; + } + + private final HashMap lastExtents = new HashMap(); + + @Override + public Collection harvest(int x, int y, int z, ForgeDirection direction, int extent) { + if (inActive) + return null; + + world = housing.getWorld(); + + Collection crops = null; + Vect start = new Vect(x, y, z); + if (!lastExtents.containsKey(start)) + lastExtents.put(start, 0); + + int lastExtent = lastExtents.get(start); + if (lastExtent > extent) + lastExtent = 0; + + Vect position = translateWithOffset(x, y + 1, z, direction, lastExtent); + crops = getHarvestBlocks(position); + lastExtent++; + lastExtents.put(start, lastExtent); + + return crops; + } + + private Collection getHarvestBlocks(Vect position) { + + ArrayList seen = new ArrayList(); + Stack crops = new Stack(); + + // Determine what type we want to harvest. + Block block = getBlock(position); + if (!StackUtils.equals(block, PluginIC2.rubberwood)) + return crops; + + int meta = this.getBlockMeta(position); + if (meta >= 2 && meta <= 5) + crops.push(new CropRubber(world, block, meta, position)); + + ArrayList candidates = processHarvestBlock(crops, seen, position); + ArrayList temp = new ArrayList(); + while (!candidates.isEmpty() && crops.size() < 100) { + for (Vect candidate : candidates) + temp.addAll(processHarvestBlock(crops, seen, candidate)); + candidates.clear(); + candidates.addAll(temp); + temp.clear(); + } + + return crops; + } + + private ArrayList processHarvestBlock(Stack crops, Collection seen, Vect position) { + + ArrayList candidates = new ArrayList(); + + // Get additional candidates to return + for (int j = 0; j < 2; j++) { + Vect candidate = new Vect(position.x, position.y + j, position.z); + if (candidate.equals(position)) + continue; + + // See whether the given position has already been processed + boolean skip = false; + for (Vect prcs : seen) + if (candidate.equals(prcs)) { + skip = true; + break; + } + + if (skip) + continue; + + Block block = getBlock(candidate); + if (StackUtils.equals(block, PluginIC2.rubberwood)) { + int meta = this.getBlockMeta(candidate); + if (meta >= 2 && meta <= 5) + crops.push(new CropRubber(world, block, meta, candidate)); + candidates.add(candidate); + seen.add(candidate); + } + } + + return candidates; + } + +} diff --git a/forestry_common/farming/forestry/farming/logic/FarmLogicShroom.java b/forestry_common/farming/forestry/farming/logic/FarmLogicShroom.java new file mode 100755 index 000000000..94e93a735 --- /dev/null +++ b/forestry_common/farming/forestry/farming/logic/FarmLogicShroom.java @@ -0,0 +1,63 @@ +/******************************************************************************* + * Copyright 2011-2014 by SirSengir + * + * This work is licensed under a Creative Commons Attribution-NonCommercial-NoDerivs 3.0 Unported License. + * + * To view a copy of this license, visit http://creativecommons.org/licenses/by-nc-nd/3.0/. + ******************************************************************************/ +package forestry.farming.logic; + +import java.util.ArrayList; +import java.util.Collection; + +import net.minecraft.init.Blocks; +import net.minecraft.item.ItemStack; +import net.minecraft.util.IIcon; + +import cpw.mods.fml.relauncher.Side; +import cpw.mods.fml.relauncher.SideOnly; + +import forestry.api.farming.Farmables; +import forestry.api.farming.IFarmHousing; +import forestry.api.farming.IFarmable; + +public class FarmLogicShroom extends FarmLogicArboreal { + + public FarmLogicShroom(IFarmHousing housing) { + super(housing, new ItemStack[] { new ItemStack(Blocks.mycelium) }, new ItemStack[] { new ItemStack(Blocks.mycelium) }, new ItemStack[] { new ItemStack( + Blocks.dirt), new ItemStack(Blocks.grass) }, Farmables.farmables.get("farmShroom").toArray(new IFarmable[0])); + yOffset = -1; + } + + @Override + public String getName() { + if (isManual) + return "Manual Shroom Farm"; + else + return "Managed Shroom Farm"; + } + + @Override + @SideOnly(Side.CLIENT) + public IIcon getIcon() { + return Blocks.red_mushroom.getBlockTextureFromSide(0); + } + + @Override + public int getFertilizerConsumption() { + return 20; + } + + @Override + public int getWaterConsumption(float hydrationModifier) { + return (int) (80 * hydrationModifier); + } + + @Override + public Collection collect() { + Collection products = produce; + produce = new ArrayList(); + return products; + } + +} diff --git a/forestry_common/farming/forestry/farming/logic/FarmLogicSucculent.java b/forestry_common/farming/forestry/farming/logic/FarmLogicSucculent.java new file mode 100755 index 000000000..5650d66ac --- /dev/null +++ b/forestry_common/farming/forestry/farming/logic/FarmLogicSucculent.java @@ -0,0 +1,106 @@ +/******************************************************************************* + * Copyright 2011-2014 by SirSengir + * + * This work is licensed under a Creative Commons Attribution-NonCommercial-NoDerivs 3.0 Unported License. + * + * To view a copy of this license, visit http://creativecommons.org/licenses/by-nc-nd/3.0/. + ******************************************************************************/ +package forestry.farming.logic; + +import java.util.Collection; +import java.util.Stack; + +import net.minecraft.init.Blocks; +import net.minecraft.init.Items; +import net.minecraft.item.ItemStack; +import net.minecraft.util.IIcon; + +import cpw.mods.fml.relauncher.Side; +import cpw.mods.fml.relauncher.SideOnly; + +import net.minecraftforge.common.util.ForgeDirection; + +import forestry.api.farming.Farmables; +import forestry.api.farming.ICrop; +import forestry.api.farming.IFarmHousing; +import forestry.api.farming.IFarmable; +import forestry.core.utils.StackUtils; +import forestry.core.utils.Vect; + +public class FarmLogicSucculent extends FarmLogic { + + IFarmable[] germlings; + + public FarmLogicSucculent(IFarmHousing housing) { + super(housing); + germlings = Farmables.farmables.get("farmSucculentes").toArray(new IFarmable[0]); + } + + @Override + @SideOnly(Side.CLIENT) + public IIcon getIcon() { + return Items.dye.getIconFromDamage(2); + } + + @Override + public String getName() { + if (isManual) + return "Manual Succulent Farm"; + else + return "Managed Succulent Farm"; + } + + @Override + public int getFertilizerConsumption() { + return 10; + } + + @Override + public int getWaterConsumption(float hydrationModifier) { + return 1; + } + + @Override + public boolean isAcceptedResource(ItemStack itemstack) { + if (isManual) + return false; + + return StackUtils.equals(Blocks.sand, itemstack); + } + + @Override + public boolean isAcceptedGermling(ItemStack itemstack) { + if (isManual) + return false; + + return StackUtils.equals(Blocks.cactus, itemstack); + } + + @Override + public Collection collect() { + return null; + } + + @Override + public boolean cultivate(int x, int y, int z, ForgeDirection direction, int extent) { + return false; + } + + @Override + public Collection harvest(int x, int y, int z, ForgeDirection direction, int extent) { + + world = housing.getWorld(); + + Stack crops = new Stack(); + for (int i = 0; i < extent; i++) { + Vect position = translateWithOffset(x, y + 1, z, direction, i); + for (IFarmable seed : germlings) { + ICrop crop = seed.getCropAt(world, position.x, position.y, position.z); + if (crop != null) + crops.push(crop); + } + } + return crops; + } + +} diff --git a/forestry_common/farming/forestry/farming/logic/FarmLogicVegetable.java b/forestry_common/farming/forestry/farming/logic/FarmLogicVegetable.java new file mode 100755 index 000000000..fc169cad1 --- /dev/null +++ b/forestry_common/farming/forestry/farming/logic/FarmLogicVegetable.java @@ -0,0 +1,40 @@ +/******************************************************************************* + * Copyright 2011-2014 by SirSengir + * + * This work is licensed under a Creative Commons Attribution-NonCommercial-NoDerivs 3.0 Unported License. + * + * To view a copy of this license, visit http://creativecommons.org/licenses/by-nc-nd/3.0/. + ******************************************************************************/ +package forestry.farming.logic; + +import net.minecraft.init.Items; +import net.minecraft.util.IIcon; + +import cpw.mods.fml.relauncher.Side; +import cpw.mods.fml.relauncher.SideOnly; + +import forestry.api.farming.Farmables; +import forestry.api.farming.IFarmHousing; +import forestry.api.farming.IFarmable; + +public class FarmLogicVegetable extends FarmLogicCrops { + + public FarmLogicVegetable(IFarmHousing housing) { + super(housing, Farmables.farmables.get("farmVegetables").toArray(new IFarmable[0])); + } + + @Override + @SideOnly(Side.CLIENT) + public IIcon getIcon() { + return Items.carrot.getIconFromDamage(0); + } + + @Override + public String getName() { + if (isManual) + return "Manual Vegetable Farm"; + else + return "Managed Vegetable Farm"; + } + +} diff --git a/forestry_common/farming/forestry/farming/logic/FarmLogicWatered.java b/forestry_common/farming/forestry/farming/logic/FarmLogicWatered.java new file mode 100755 index 000000000..a9c591dfd --- /dev/null +++ b/forestry_common/farming/forestry/farming/logic/FarmLogicWatered.java @@ -0,0 +1,182 @@ +/******************************************************************************* + * Copyright 2011-2014 by SirSengir + * + * This work is licensed under a Creative Commons Attribution-NonCommercial-NoDerivs 3.0 Unported License. + * + * To view a copy of this license, visit http://creativecommons.org/licenses/by-nc-nd/3.0/. + ******************************************************************************/ +package forestry.farming.logic; + +import java.util.ArrayList; +import java.util.Collection; + +import net.minecraft.init.Blocks; +import net.minecraft.item.ItemStack; + +import net.minecraftforge.common.util.ForgeDirection; +import net.minecraftforge.fluids.FluidStack; + +import forestry.api.farming.IFarmHousing; +import forestry.core.config.Defaults; +import forestry.core.utils.LiquidHelper; +import forestry.core.utils.StackUtils; +import forestry.core.utils.Utils; +import forestry.core.utils.Vect; + +public abstract class FarmLogicWatered extends FarmLogic { + + protected ItemStack[] ground; + private final ItemStack[] resource; + private final ItemStack[] waste; + + private static final FluidStack STACK_WATER = new FluidStack(LiquidHelper.getFluid(Defaults.LIQUID_WATER), 1000); + + ArrayList produce = new ArrayList(); + + public FarmLogicWatered(IFarmHousing housing, ItemStack[] resource, ItemStack[] ground, ItemStack[] waste) { + super(housing); + this.ground = ground; + this.resource = resource; + this.waste = waste; + } + + @Override + public int getFertilizerConsumption() { + return 5; + } + + @Override + public int getWaterConsumption(float hydrationModifier) { + return (int) (20 * hydrationModifier); + } + + @Override + public boolean isAcceptedResource(ItemStack itemstack) { + return resource[0].isItemEqual(itemstack); + } + + @Override + public Collection collect() { + Collection products = produce; + produce = new ArrayList(); + return products; + } + + @Override + public boolean cultivate(int x, int y, int z, ForgeDirection direction, int extent) { + + world = housing.getWorld(); + + if (maintainSoil(x, y, z, direction, extent)) + return true; + + if (!isManual && maintainWater(x, y, z, direction, extent)) + return true; + + if (maintainCrops(x, y + 1, z, direction, extent)) + return true; + + return false; + } + + private boolean isWaste(ItemStack stack) { + for (ItemStack block : waste) + if (block.isItemEqual(stack)) + return true; + return false; + } + + private boolean maintainSoil(int x, int y, int z, ForgeDirection direction, int extent) { + + for (int i = 0; i < extent; i++) { + Vect position = translateWithOffset(x, y, z, direction, i); + if (!isAirBlock(position) && !Utils.isReplaceableBlock(world, position.x, position.y, position.z)) { + + ItemStack block = getAsItemStack(position); + if (isWaste(block) && housing.hasResources(resource)) { + produce.addAll(StackUtils.getBlock(block).getDrops(world, x, y, z, block.getItemDamage(), 0)); + setBlock(position, Blocks.air, 0); + return trySetSoil(position); + } + + continue; + } + + if (isManual || isWaterBlock(position)) + continue; + + if (i % 2 != 0) { + ForgeDirection cclock = ForgeDirection.EAST; + if (direction == ForgeDirection.EAST) + cclock = ForgeDirection.SOUTH; + else if (direction == ForgeDirection.SOUTH) + cclock = ForgeDirection.EAST; + else if (direction == ForgeDirection.WEST) + cclock = ForgeDirection.SOUTH; + + Vect previous = translateWithOffset(position.x, position.y, position.z, cclock, 1); + ItemStack soil = getAsItemStack(previous); + if (!ground[0].isItemEqual(soil)) + trySetSoil(position); + continue; + } + + return trySetSoil(position); + } + + return false; + } + + private boolean maintainWater(int x, int y, int z, ForgeDirection direction, int extent) { + // Still not done, check water then + for (int i = 0; i < extent; i++) { + Vect position = translateWithOffset(x, y, z, direction, i); + if ((!isAirBlock(position) && !Utils.isReplaceableBlock(world, position.x, position.y, position.z)) + || isWaterBlock(position)) { + continue; + } + + boolean isEnclosed = true; + + if (world.isAirBlock(position.x + 1, position.y, position.z)) + isEnclosed = false; + else if (world.isAirBlock(position.x - 1, position.y, position.z)) + isEnclosed = false; + else if (world.isAirBlock(position.x, position.y, position.z + 1)) + isEnclosed = false; + else if (world.isAirBlock(position.x, position.y, position.z - 1)) + isEnclosed = false; + + if (isEnclosed) + return trySetWater(position); + } + + return false; + } + + protected boolean maintainCrops(int x, int y, int z, ForgeDirection direction, int extent) { + return false; + } + + private boolean trySetSoil(Vect position) { + if (!housing.hasResources(resource)) + return false; + setBlock(position, StackUtils.getBlock(ground[0]), ground[0].getItemDamage()); + housing.removeResources(resource); + return true; + } + + private boolean trySetWater(Vect position) { + System.out.println("trySetWater: at " + position.toString()); + + if (!housing.hasLiquid(STACK_WATER)) + return false; + + System.out.println("Can place water: at " + position.toString()); + + setBlock(position, Blocks.water, 0); + housing.removeLiquid(STACK_WATER); + return true; + } + +} diff --git a/forestry_common/farming/forestry/farming/logic/FarmableCocoa.java b/forestry_common/farming/forestry/farming/logic/FarmableCocoa.java new file mode 100755 index 000000000..e9a62fd20 --- /dev/null +++ b/forestry_common/farming/forestry/farming/logic/FarmableCocoa.java @@ -0,0 +1,60 @@ +/******************************************************************************* + * Copyright 2011-2014 by SirSengir + * + * This work is licensed under a Creative Commons Attribution-NonCommercial-NoDerivs 3.0 Unported License. + * + * To view a copy of this license, visit http://creativecommons.org/licenses/by-nc-nd/3.0/. + ******************************************************************************/ +package forestry.farming.logic; + +import net.minecraft.block.Block; +import net.minecraft.init.Blocks; +import net.minecraft.init.Items; +import net.minecraft.item.Item; +import net.minecraft.item.ItemStack; +import net.minecraft.world.World; + +import forestry.api.farming.ICrop; +import forestry.api.farming.IFarmable; +import forestry.core.utils.BlockUtil; +import forestry.core.utils.Vect; + +public class FarmableCocoa implements IFarmable { + + public static final Block COCOA_PLANT = Blocks.cocoa; + public static final Item COCOA_SEED = Items.dye; + public static final int COCOA_META = 3; + + @Override + public boolean isSaplingAt(World world, int x, int y, int z) { + return world.getBlock(x, y, z) == COCOA_PLANT; + } + + @Override + public ICrop getCropAt(World world, int x, int y, int z) { + Block block = world.getBlock(x, y, z); + if (block != COCOA_PLANT) + return null; + int meta = world.getBlockMetadata(x, y, z); + if (BlockUtil.getMaturityPod(meta) < 2) + return null; + + return new CropBlock(world, block, meta, new Vect(x, y, z)); + } + + @Override + public boolean isGermling(ItemStack itemstack) { + return itemstack.getItem() == COCOA_SEED && itemstack.getItemDamage() == COCOA_META; + } + + @Override + public boolean isWindfall(ItemStack itemstack) { + return false; + } + + @Override + public boolean plantSaplingAt(ItemStack germling, World world, int x, int y, int z) { + return BlockUtil.tryPlantPot(world, x, y, z, COCOA_PLANT); + } + +} diff --git a/forestry_common/farming/forestry/farming/logic/FarmableFarmCraftory.java b/forestry_common/farming/forestry/farming/logic/FarmableFarmCraftory.java new file mode 100755 index 000000000..0ca8a525c --- /dev/null +++ b/forestry_common/farming/forestry/farming/logic/FarmableFarmCraftory.java @@ -0,0 +1,84 @@ +/******************************************************************************* + * Copyright 2011-2014 by SirSengir + * + * This work is licensed under a Creative Commons Attribution-NonCommercial-NoDerivs 3.0 Unported License. + * + * To view a copy of this license, visit http://creativecommons.org/licenses/by-nc-nd/3.0/. + ******************************************************************************/ +package forestry.farming.logic; + +import java.util.Collection; + +import net.minecraft.block.Block; +import net.minecraft.item.ItemStack; +import net.minecraft.tileentity.TileEntity; +import net.minecraft.world.World; + +import forestry.api.farming.ICrop; +import forestry.api.farming.IFarmable; +import forestry.core.utils.StackUtils; +import forestry.core.utils.Utils; +import forestry.core.utils.Vect; +import forestry.plugins.PluginFarmCraftory; + +public class FarmableFarmCraftory implements IFarmable { + + Collection germlings; + Collection windfall; + + public FarmableFarmCraftory(Collection germlings, Collection windfall) { + this.germlings = germlings; + this.windfall = windfall; + } + + @Override + public boolean isSaplingAt(World world, int x, int y, int z) { + + if (world.isAirBlock(x, y, z)) + return false; + + Block block = world.getBlock(x, y, z); + if (block != PluginFarmCraftory.blockSingle && block != PluginFarmCraftory.blockMulti) + return false; + else + return true; + } + + @Override + public ICrop getCropAt(World world, int x, int y, int z) { + Block block = world.getBlock(x, y, z); + if (block != PluginFarmCraftory.blockSingle && block != PluginFarmCraftory.blockMulti) + return null; + TileEntity tile = world.getTileEntity(x, y, z); + if (tile == null) + return null; + if (PluginFarmCraftory.getGrowthStage(tile) < 2) + return null; + + return new CropBlock(world, block, world.getBlockMetadata(x, y, z), new Vect(x, y, z)); + } + + @Override + public boolean isGermling(ItemStack itemstack) { + for (ItemStack seed : germlings) + if (StackUtils.isIdenticalItem(seed, itemstack)) + return true; + + return false; + } + + @Override + public boolean plantSaplingAt(ItemStack germling, World world, int x, int y, int z) { + return germling.copy().tryPlaceItemIntoWorld(Utils.getForestryPlayer(world, x, y, z), world, x, y - 1, z, 1, 0, 0, 0); + } + + @Override + public boolean isWindfall(ItemStack itemstack) { + for (ItemStack fruit : windfall) + if (StackUtils.isIdenticalItem(fruit, itemstack)) + return true; + + return false; + } + +} diff --git a/forestry_common/farming/forestry/farming/logic/FarmableGE.java b/forestry_common/farming/forestry/farming/logic/FarmableGE.java new file mode 100755 index 000000000..0a8780683 --- /dev/null +++ b/forestry_common/farming/forestry/farming/logic/FarmableGE.java @@ -0,0 +1,59 @@ +/******************************************************************************* + * Copyright 2011-2014 by SirSengir + * + * This work is licensed under a Creative Commons Attribution-NonCommercial-NoDerivs 3.0 Unported License. + * + * To view a copy of this license, visit http://creativecommons.org/licenses/by-nc-nd/3.0/. + ******************************************************************************/ +package forestry.farming.logic; + +import net.minecraft.block.Block; +import net.minecraft.item.ItemStack; +import net.minecraft.world.World; + +import forestry.api.arboriculture.ITree; +import forestry.api.farming.ICrop; +import forestry.api.farming.IFarmable; +import forestry.core.config.ForestryBlock; +import forestry.core.utils.Utils; +import forestry.core.utils.Vect; +import forestry.plugins.PluginArboriculture; + +public class FarmableGE implements IFarmable { + + @Override + public boolean isSaplingAt(World world, int x, int y, int z) { + + if (world.isAirBlock(x, y, z)) + return false; + + return world.getBlock(x, y, z) == ForestryBlock.saplingGE; + } + + @Override + public ICrop getCropAt(World world, int x, int y, int z) { + Block block = world.getBlock(x, y, z); + + if (block.isAir(world, x, y, z) || !block.isWood(world, x, y, z)) + return null; + + return new CropBlock(world, block, world.getBlockMetadata(x, y, z), new Vect(x, y, z)); + } + + @Override + public boolean plantSaplingAt(ItemStack germling, World world, int x, int y, int z) { + return germling.copy().tryPlaceItemIntoWorld(Utils.getForestryPlayer(world, x, y, z), world, x, y - 1, z, 1, 0, 0, 0); + } + + @Override + public boolean isGermling(ItemStack itemstack) { + ITree tree = PluginArboriculture.treeInterface.getMember(itemstack); + return tree != null; + } + + @Override + public boolean isWindfall(ItemStack itemstack) { + return false; + } + +} diff --git a/forestry_common/farming/forestry/farming/logic/FarmableGenericCrop.java b/forestry_common/farming/forestry/farming/logic/FarmableGenericCrop.java new file mode 100755 index 000000000..643a0e83a --- /dev/null +++ b/forestry_common/farming/forestry/farming/logic/FarmableGenericCrop.java @@ -0,0 +1,74 @@ +/******************************************************************************* + * Copyright 2011-2014 by SirSengir + * + * This work is licensed under a Creative Commons Attribution-NonCommercial-NoDerivs 3.0 Unported License. + * + * To view a copy of this license, visit http://creativecommons.org/licenses/by-nc-nd/3.0/. + ******************************************************************************/ +package forestry.farming.logic; + +import net.minecraft.block.Block; +import net.minecraft.item.ItemStack; +import net.minecraft.world.World; + +import forestry.api.farming.ICrop; +import forestry.api.farming.IFarmable; +import forestry.core.utils.Utils; +import forestry.core.utils.Vect; + +public class FarmableGenericCrop implements IFarmable { + + private final ItemStack seed; + private final Block block; + private final int mature; + + public FarmableGenericCrop(ItemStack seed, Block block, int mature) { + this.seed = seed; + this.block = block; + this.mature = mature; + } + + @Override + public boolean isSaplingAt(World world, int x, int y, int z) { + + if (world.isAirBlock(x, y, z)) + return false; + + if (world.getBlock(x, y, z) != block) + return false; + else + return true; + } + + @Override + public ICrop getCropAt(World world, int x, int y, int z) { + if (world.getBlock(x, y, z) != block) + return null; + if (world.getBlockMetadata(x, y, z) != mature) + return null; + + return new CropBlock(world, block, mature, new Vect(x, y, z)); + } + + @Override + public boolean isGermling(ItemStack itemstack) { + if (seed.getItem() != itemstack.getItem()) + return false; + + if (seed.getItemDamage() >= 0) + return seed.getItemDamage() == itemstack.getItemDamage(); + else + return true; + } + + @Override + public boolean plantSaplingAt(ItemStack germling, World world, int x, int y, int z) { + return germling.copy().tryPlaceItemIntoWorld(Utils.getForestryPlayer(world, x, y, z), world, x, y - 1, z, 1, 0, 0, 0); + } + + @Override + public boolean isWindfall(ItemStack itemstack) { + return false; + } + +} diff --git a/forestry_common/farming/forestry/farming/logic/FarmableGenericSapling.java b/forestry_common/farming/forestry/farming/logic/FarmableGenericSapling.java new file mode 100755 index 000000000..fab00af7b --- /dev/null +++ b/forestry_common/farming/forestry/farming/logic/FarmableGenericSapling.java @@ -0,0 +1,83 @@ +/******************************************************************************* + * Copyright 2011-2014 by SirSengir + * + * This work is licensed under a Creative Commons Attribution-NonCommercial-NoDerivs 3.0 Unported License. + * + * To view a copy of this license, visit http://creativecommons.org/licenses/by-nc-nd/3.0/. + ******************************************************************************/ +package forestry.farming.logic; + +import net.minecraft.block.Block; +import net.minecraft.item.ItemStack; +import net.minecraft.world.World; + +import forestry.api.farming.ICrop; +import forestry.api.farming.IFarmable; +import forestry.core.utils.StackUtils; +import forestry.core.utils.Utils; +import forestry.core.utils.Vect; + +public class FarmableGenericSapling implements IFarmable { + + final Block sapling; + final int saplingMeta; + + ItemStack[] windfall; + + public FarmableGenericSapling(Block sapling, int saplingMeta, ItemStack... windfall) { + this.sapling = sapling; + this.saplingMeta = saplingMeta; + this.windfall = windfall; + } + + @Override + public boolean isSaplingAt(World world, int x, int y, int z) { + + if (world.isAirBlock(x, y, z)) + return false; + + if (world.getBlock(x, y, z) == sapling) + return true; + + if (saplingMeta >= 0) + return world.getBlockMetadata(x, y, z) == saplingMeta; + else + return true; + + } + + @Override + public ICrop getCropAt(World world, int x, int y, int z) { + Block block = world.getBlock(x, y, z); + if (!block.isWood(world, x, y, z)) + return null; + + return new CropBlock(world, block, world.getBlockMetadata(x, y, z), new Vect(x, y, z)); + } + + @Override + public boolean isGermling(ItemStack itemstack) { + + if (!StackUtils.equals(sapling, itemstack)) + return false; + + if (saplingMeta >= 0) + return itemstack.getItemDamage() == saplingMeta; + else + return true; + } + + @Override + public boolean isWindfall(ItemStack itemstack) { + for (ItemStack drop : windfall) + if (drop.isItemEqual(itemstack)) + return true; + return false; + } + + @Override + public boolean plantSaplingAt(ItemStack germling, World world, int x, int y, int z) { + return germling.copy().tryPlaceItemIntoWorld(Utils.getForestryPlayer(world, x, y, z), world, x, y - 1, z, 1, 0, 0, 0); + } + +} diff --git a/forestry_common/farming/forestry/farming/logic/FarmableGourd.java b/forestry_common/farming/forestry/farming/logic/FarmableGourd.java new file mode 100755 index 000000000..ae95f7d77 --- /dev/null +++ b/forestry_common/farming/forestry/farming/logic/FarmableGourd.java @@ -0,0 +1,71 @@ +/******************************************************************************* + * Copyright 2011-2014 by SirSengir + * + * This work is licensed under a Creative Commons Attribution-NonCommercial-NoDerivs 3.0 Unported License. + * + * To view a copy of this license, visit http://creativecommons.org/licenses/by-nc-nd/3.0/. + ******************************************************************************/ +package forestry.farming.logic; + +import net.minecraft.item.ItemStack; +import net.minecraft.world.World; + +import forestry.api.farming.ICrop; +import forestry.api.farming.IFarmable; +import forestry.core.config.Defaults; +import forestry.core.utils.StackUtils; +import forestry.core.utils.Vect; + +public class FarmableGourd implements IFarmable { + + public ItemStack seed; + public ItemStack stem; + public ItemStack fruit; + + public FarmableGourd(ItemStack seed, ItemStack stem, ItemStack fruit) { + this.seed = seed; + this.stem = stem; + this.fruit = fruit; + } + + @Override + public boolean isSaplingAt(World world, int x, int y, int z) { + if (world.isAirBlock(x, y, z)) + return false; + + if (!StackUtils.equals(world.getBlock(x, y, z), stem)) + return false; + + return true; + } + + @Override + public ICrop getCropAt(World world, int x, int y, int z) { + if (world.isAirBlock(x, y, z)) + return null; + + if (!StackUtils.equals(world.getBlock(x, y, z), fruit)) + return null; + + if (world.getBlockMetadata(x, y, z) != fruit.getItemDamage()) + return null; + + return new CropBlock(world, StackUtils.getBlock(fruit), fruit.getItemDamage(), new Vect(x, y, z)); + } + + @Override + public boolean isGermling(ItemStack itemstack) { + return seed.isItemEqual(itemstack); + } + + @Override + public boolean isWindfall(ItemStack itemstack) { + return false; + } + + @Override + public boolean plantSaplingAt(ItemStack germling, World world, int x, int y, int z) { + return world.setBlock(x, y, z, StackUtils.getBlock(stem), 0, Defaults.FLAG_BLOCK_SYNCH); + } + +} diff --git a/forestry_common/farming/forestry/farming/logic/FarmableStacked.java b/forestry_common/farming/forestry/farming/logic/FarmableStacked.java new file mode 100755 index 000000000..94721ee0f --- /dev/null +++ b/forestry_common/farming/forestry/farming/logic/FarmableStacked.java @@ -0,0 +1,58 @@ +/******************************************************************************* + * Copyright 2011-2014 by SirSengir + * + * This work is licensed under a Creative Commons Attribution-NonCommercial-NoDerivs 3.0 Unported License. + * + * To view a copy of this license, visit http://creativecommons.org/licenses/by-nc-nd/3.0/. + ******************************************************************************/ +package forestry.farming.logic; + +import net.minecraft.block.Block; +import net.minecraft.item.ItemStack; +import net.minecraft.world.World; + +import forestry.api.farming.ICrop; +import forestry.api.farming.IFarmable; +import forestry.core.config.Defaults; +import forestry.core.utils.StackUtils; +import forestry.core.utils.Vect; + +public class FarmableStacked implements IFarmable { + + Block block; + int matureHeight; + + public FarmableStacked(Block block, int matureHeight) { + this.block = block; + this.matureHeight = matureHeight; + } + + @Override + public boolean isSaplingAt(World world, int x, int y, int z) { + return world.getBlock(x, y, z) == block; + } + + @Override + public ICrop getCropAt(World world, int x, int y, int z) { + if (world.getBlock(x, y + (matureHeight - 1), z) != block) + return null; + + return new CropBlock(world, block, 0, new Vect(x, y + (matureHeight - 1), z)); + } + + @Override + public boolean isGermling(ItemStack itemstack) { + return StackUtils.equals(block, itemstack); + } + + @Override + public boolean plantSaplingAt(ItemStack germling, World world, int x, int y, int z) { + return world.setBlock(x, y, z, block, 0, Defaults.FLAG_BLOCK_SYNCH); + } + + @Override + public boolean isWindfall(ItemStack itemstack) { + return false; + } + +} diff --git a/forestry_common/farming/forestry/farming/logic/FarmableVanillaSapling.java b/forestry_common/farming/forestry/farming/logic/FarmableVanillaSapling.java new file mode 100755 index 000000000..8b82665b7 --- /dev/null +++ b/forestry_common/farming/forestry/farming/logic/FarmableVanillaSapling.java @@ -0,0 +1,47 @@ +/******************************************************************************* + * Copyright 2011-2014 by SirSengir + * + * This work is licensed under a Creative Commons Attribution-NonCommercial-NoDerivs 3.0 Unported License. + * + * To view a copy of this license, visit http://creativecommons.org/licenses/by-nc-nd/3.0/. + ******************************************************************************/ +package forestry.farming.logic; + +import java.util.Map; + +import net.minecraft.init.Blocks; +import net.minecraft.init.Items; +import net.minecraft.item.ItemStack; +import net.minecraft.world.World; + +import forestry.api.arboriculture.ITree; +import forestry.api.genetics.AlleleManager; +import forestry.api.genetics.IIndividual; +import forestry.core.config.Config; +import forestry.plugins.PluginArboriculture; + +public class FarmableVanillaSapling extends FarmableGenericSapling { + + int saplingId; + int saplingMeta; + + public FarmableVanillaSapling() { + super(Blocks.sapling, -1, new ItemStack(Items.apple), new ItemStack(FarmableCocoa.COCOA_SEED, 1, FarmableCocoa.COCOA_META)); + } + + @Override + public boolean plantSaplingAt(ItemStack germling, World world, int x, int y, int z) { + ITree tree = null; + for (Map.Entry entry : AlleleManager.ersatzSaplings.entrySet()) + if (entry.getKey().isItemEqual(germling) && entry.getValue() instanceof ITree) { + tree = (ITree) entry.getValue(); + break; + } + + if (tree == null) + return false; + + return PluginArboriculture.treeInterface.plantSapling(world, tree, Config.fakeUserLogin, x, y, z); + } + +} diff --git a/forestry_common/farming/forestry/farming/logic/FarmableVanillaShroom.java b/forestry_common/farming/forestry/farming/logic/FarmableVanillaShroom.java new file mode 100755 index 000000000..1c3292e58 --- /dev/null +++ b/forestry_common/farming/forestry/farming/logic/FarmableVanillaShroom.java @@ -0,0 +1,48 @@ +/******************************************************************************* + * Copyright 2011-2014 by SirSengir + * + * This work is licensed under a Creative Commons Attribution-NonCommercial-NoDerivs 3.0 Unported License. + * + * To view a copy of this license, visit http://creativecommons.org/licenses/by-nc-nd/3.0/. + ******************************************************************************/ +package forestry.farming.logic; + +import net.minecraft.block.Block; +import net.minecraft.init.Blocks; +import net.minecraft.item.ItemStack; +import net.minecraft.world.World; + +import forestry.api.farming.ICrop; +import forestry.core.config.Defaults; +import forestry.core.config.ForestryBlock; +import forestry.core.proxy.Proxies; +import forestry.core.utils.StackUtils; +import forestry.core.utils.Vect; + +public class FarmableVanillaShroom extends FarmableGenericSapling { + + public FarmableVanillaShroom(Block sapling, int saplingMeta) { + super(sapling, saplingMeta); + } + + @Override + public ICrop getCropAt(World world, int x, int y, int z) { + Block block = world.getBlock(x, y, z); + + if (block != Blocks.brown_mushroom_block && block != Blocks.red_mushroom_block) + return null; + + return new CropBlock(world, block, world.getBlockMetadata(x, y, z), new Vect(x, y, z)); + } + + @Override + public boolean plantSaplingAt(ItemStack germling, World world, int x, int y, int z) { + int meta = 0; + if (StackUtils.equals(Blocks.red_mushroom, germling)) + meta = 1; + + Proxies.common.addBlockPlaceEffects(world, x, y, z, Blocks.brown_mushroom, 0); + return world.setBlock(x, y, z, ForestryBlock.mushroom, meta, Defaults.FLAG_BLOCK_SYNCH); + } + +} diff --git a/forestry_common/farming/forestry/farming/proxy/ClientProxyFarming.java b/forestry_common/farming/forestry/farming/proxy/ClientProxyFarming.java new file mode 100755 index 000000000..235f31218 --- /dev/null +++ b/forestry_common/farming/forestry/farming/proxy/ClientProxyFarming.java @@ -0,0 +1,37 @@ +/******************************************************************************* + * Copyright 2011-2014 by SirSengir + * + * This work is licensed under a Creative Commons Attribution-NonCommercial-NoDerivs 3.0 Unported License. + * + * To view a copy of this license, visit http://creativecommons.org/licenses/by-nc-nd/3.0/. + ******************************************************************************/ +package forestry.farming.proxy; + +import net.minecraft.item.Item; + +import cpw.mods.fml.client.registry.RenderingRegistry; + +import net.minecraftforge.client.MinecraftForgeClient; + +import forestry.core.config.ForestryBlock; +import forestry.core.utils.Localization; +import forestry.farming.render.FarmItemRenderer; +import forestry.farming.render.FarmRenderingHandler; +import forestry.plugins.PluginFarming; + +public class ClientProxyFarming extends ProxyFarming { + + @Override + public void initializeRendering() { + PluginFarming.modelIdFarmBlock = RenderingRegistry.getNextAvailableRenderId(); + + RenderingRegistry.registerBlockHandler(new FarmRenderingHandler()); + MinecraftForgeClient.registerItemRenderer(Item.getItemFromBlock(ForestryBlock.farm), new FarmItemRenderer()); + } + + @Override + public void addLocalizations() { + Localization.instance.addLocalization("/lang/forestry/farming/"); + } + +} diff --git a/forestry_common/farming/forestry/farming/proxy/ProxyFarming.java b/forestry_common/farming/forestry/farming/proxy/ProxyFarming.java new file mode 100755 index 000000000..d305207e6 --- /dev/null +++ b/forestry_common/farming/forestry/farming/proxy/ProxyFarming.java @@ -0,0 +1,18 @@ +/******************************************************************************* + * Copyright 2011-2014 by SirSengir + * + * This work is licensed under a Creative Commons Attribution-NonCommercial-NoDerivs 3.0 Unported License. + * + * To view a copy of this license, visit http://creativecommons.org/licenses/by-nc-nd/3.0/. + ******************************************************************************/ +package forestry.farming.proxy; + +public class ProxyFarming { + + public void initializeRendering() { + } + + public void addLocalizations() { + } + +} diff --git a/forestry_common/farming/forestry/farming/render/FarmItemRenderer.java b/forestry_common/farming/forestry/farming/render/FarmItemRenderer.java new file mode 100755 index 000000000..3f319a852 --- /dev/null +++ b/forestry_common/farming/forestry/farming/render/FarmItemRenderer.java @@ -0,0 +1,113 @@ +/******************************************************************************* + * Copyright 2011-2014 by SirSengir + * + * This work is licensed under a Creative Commons Attribution-NonCommercial-NoDerivs 3.0 Unported License. + * + * To view a copy of this license, visit http://creativecommons.org/licenses/by-nc-nd/3.0/. + ******************************************************************************/ +package forestry.farming.render; + +import net.minecraft.client.renderer.RenderBlocks; +import net.minecraft.client.renderer.Tessellator; +import net.minecraft.item.ItemStack; + +import net.minecraftforge.client.IItemRenderer; + +import org.lwjgl.opengl.GL11; + +import forestry.core.utils.StackUtils; +import forestry.farming.gadgets.BlockFarm; +import forestry.farming.gadgets.TileFarm.EnumFarmBlock; + +public class FarmItemRenderer implements IItemRenderer { + + private void renderFarmBlock(RenderBlocks render, ItemStack item, float translateX, float translateY, float translateZ) { + + Tessellator tessellator = Tessellator.instance; + BlockFarm block = (BlockFarm) StackUtils.getBlock(item); + + block.setBlockBoundsForItemRender(); + render.setRenderBoundsFromBlock(block); + + EnumFarmBlock type = EnumFarmBlock.getFromCompound(item.getTagCompound()); + + GL11.glTranslatef(translateX, translateY, translateZ); + + tessellator.startDrawingQuads(); + tessellator.setNormal(0.0F, -1F, 0.0F); + render.renderFaceYNeg(block, 0.0D, 0.0D, 0.0D, block.getBlockTextureFromSideAndMetadata(type, 0, item.getItemDamage())); + render.renderFaceYNeg(block, 0.0D, 0.0D, 0.0D, block.getOverlayTextureForBlock(0, item.getItemDamage())); + tessellator.draw(); + + tessellator.startDrawingQuads(); + tessellator.setNormal(0.0F, 1.0F, 0.0F); + render.renderFaceYPos(block, 0.0D, 0.0D, 0.0D, block.getBlockTextureFromSideAndMetadata(type, 1, item.getItemDamage())); + render.renderFaceYPos(block, 0.0D, 0.0D, 0.0D, block.getOverlayTextureForBlock(1, item.getItemDamage())); + tessellator.draw(); + + tessellator.startDrawingQuads(); + tessellator.setNormal(0.0F, 0.0F, -1F); + render.renderFaceZNeg(block, 0.0D, 0.0D, 0.0D, block.getBlockTextureFromSideAndMetadata(type, 2, item.getItemDamage())); + render.renderFaceZNeg(block, 0.0D, 0.0D, 0.0D, block.getOverlayTextureForBlock(2, item.getItemDamage())); + tessellator.draw(); + + tessellator.startDrawingQuads(); + tessellator.setNormal(0.0F, 0.0F, 1.0F); + render.renderFaceZPos(block, 0.0D, 0.0D, 0.0D, block.getBlockTextureFromSideAndMetadata(type, 3, item.getItemDamage())); + render.renderFaceZPos(block, 0.0D, 0.0D, 0.0D, block.getOverlayTextureForBlock(3, item.getItemDamage())); + tessellator.draw(); + + tessellator.startDrawingQuads(); + tessellator.setNormal(-1F, 0.0F, 0.0F); + render.renderFaceXNeg(block, 0.0D, 0.0D, 0.0D, block.getBlockTextureFromSideAndMetadata(type, 4, item.getItemDamage())); + render.renderFaceXNeg(block, 0.0D, 0.0D, 0.0D, block.getOverlayTextureForBlock(4, item.getItemDamage())); + tessellator.draw(); + + tessellator.startDrawingQuads(); + tessellator.setNormal(1.0F, 0.0F, 0.0F); + render.renderFaceXPos(block, 0.0D, 0.0D, 0.0D, block.getBlockTextureFromSideAndMetadata(type, 5, item.getItemDamage())); + render.renderFaceXPos(block, 0.0D, 0.0D, 0.0D, block.getOverlayTextureForBlock(5, item.getItemDamage())); + tessellator.draw(); + + GL11.glTranslatef(0.5F, 0.5F, 0.5F); + + block.setBlockBounds(0.0F, 0.0F, 0.0F, 1.0F, 1.0F, 1.0F); + + } + + @Override + public boolean handleRenderType(ItemStack item, ItemRenderType type) { + switch (type) { + case ENTITY: + case EQUIPPED_FIRST_PERSON: + case EQUIPPED: + case INVENTORY: + return true; + default: + return false; + } + } + + @Override + public boolean shouldUseRenderHelper(ItemRenderType type, ItemStack item, ItemRendererHelper helper) { + return true; + } + + @Override + public void renderItem(ItemRenderType type, ItemStack item, Object... data) { + switch (type) { + case ENTITY: + renderFarmBlock((RenderBlocks) data[0], item, -0.5f, -0.5f, -0.5f); + break; + case EQUIPPED: + case EQUIPPED_FIRST_PERSON: + renderFarmBlock((RenderBlocks) data[0], item, 0f, 0f, 0f); + break; + case INVENTORY: + renderFarmBlock((RenderBlocks) data[0], item, -0.5f, -0.5f, -0.5f); + break; + default: + } + } + +} diff --git a/forestry_common/farming/forestry/farming/render/FarmRenderingHandler.java b/forestry_common/farming/forestry/farming/render/FarmRenderingHandler.java new file mode 100755 index 000000000..5e1668a74 --- /dev/null +++ b/forestry_common/farming/forestry/farming/render/FarmRenderingHandler.java @@ -0,0 +1,82 @@ +/******************************************************************************* + * Copyright 2011-2014 by SirSengir + * + * This work is licensed under a Creative Commons Attribution-NonCommercial-NoDerivs 3.0 Unported License. + * + * To view a copy of this license, visit http://creativecommons.org/licenses/by-nc-nd/3.0/. + ******************************************************************************/ +package forestry.farming.render; + +import net.minecraft.block.Block; +import net.minecraft.client.renderer.EntityRenderer; +import net.minecraft.client.renderer.RenderBlocks; +import net.minecraft.world.IBlockAccess; + +import forestry.core.config.ForestryBlock; +import forestry.core.render.OverlayRenderingHandler; +import forestry.farming.gadgets.BlockFarm; +import forestry.plugins.PluginFarming; + +public class FarmRenderingHandler extends OverlayRenderingHandler { + + @Override + public void renderInventoryBlock(Block block, int metadata, int modelID, RenderBlocks renderer) { + } + + @Override + public boolean renderWorldBlock(IBlockAccess world, int x, int y, int z, Block block, int modelId, RenderBlocks renderer) { + + // Render the plain block. + renderer.renderStandardBlock(block, x, y, z); + renderFarmOverlay(world, (BlockFarm) ForestryBlock.farm, x, y, z, renderer, 0xffffff); + + return true; + } + + private boolean renderFarmOverlay(IBlockAccess world, BlockFarm block, int x, int y, int z, RenderBlocks renderer, int multiplier) { + + float mR = (multiplier >> 16 & 255) / 255.0F; + float mG = (multiplier >> 8 & 255) / 255.0F; + float mB = (multiplier & 255) / 255.0F; + + if (EntityRenderer.anaglyphEnable) { + mR = (mR * 30.0F + mG * 59.0F + mB * 11.0F) / 100.0F; + mG = (mR * 30.0F + mG * 70.0F) / 100.0F; + mB = (mR * 30.0F + mB * 70.0F) / 100.0F; + } + + return renderFarmOverlayWithColourMultiplier(world, block, x, y, z, mR, mG, mB, renderer); + } + + private boolean renderFarmOverlayWithColourMultiplier(IBlockAccess world, BlockFarm block, int x, int y, int z, float r, float g, float b, + RenderBlocks renderer) { + + int mixedBrightness = block.getMixedBrightnessForBlock(world, x, y, z); + int metadata = world.getBlockMetadata(x, y, z); + + float adjR = 0.5f * r; + float adjG = 0.5f * g; + float adjB = 0.5f * b; + + // Bottom + renderBottomFace(world, block, x, y, z, renderer, block.getOverlayTextureForBlock(0, metadata), mixedBrightness, adjR, adjG, adjB); + renderTopFace(world, block, x, y, z, renderer, block.getOverlayTextureForBlock(1, metadata), mixedBrightness, adjR, adjG, adjB); + renderEastFace(world, block, x, y, z, renderer, block.getOverlayTextureForBlock(2, metadata), mixedBrightness, adjR, adjG, adjB); + renderWestFace(world, block, x, y, z, renderer, block.getOverlayTextureForBlock(3, metadata), mixedBrightness, adjR, adjG, adjB); + renderNorthFace(world, block, x, y, z, renderer, block.getOverlayTextureForBlock(4, metadata), mixedBrightness, adjR, adjG, adjB); + renderSouthFace(world, block, x, y, z, renderer, block.getOverlayTextureForBlock(5, metadata), mixedBrightness, adjR, adjG, adjB); + + return true; + } + + @Override + public boolean shouldRender3DInInventory(int modelId) { + return true; + } + + @Override + public int getRenderId() { + return PluginFarming.modelIdFarmBlock; + } + +} diff --git a/forestry_common/farming/forestry/farming/triggers/TriggerLowFertilizer.java b/forestry_common/farming/forestry/farming/triggers/TriggerLowFertilizer.java new file mode 100755 index 000000000..de4e44093 --- /dev/null +++ b/forestry_common/farming/forestry/farming/triggers/TriggerLowFertilizer.java @@ -0,0 +1,50 @@ +/******************************************************************************* + * Copyright 2011-2014 by SirSengir + * + * This work is licensed under a Creative Commons Attribution-NonCommercial-NoDerivs 3.0 Unported License. + * + * To view a copy of this license, visit http://creativecommons.org/licenses/by-nc-nd/3.0/. + ******************************************************************************/ +package forestry.farming.triggers; + +import net.minecraft.item.ItemStack; +import net.minecraft.tileentity.TileEntity; + +import net.minecraftforge.common.util.ForgeDirection; + +import buildcraft.api.gates.ITriggerParameter; + +import forestry.api.core.ITileStructure; +import forestry.core.triggers.Trigger; +import forestry.farming.gadgets.TileFarmPlain; +import forestry.farming.gadgets.TileHatch; + +public class TriggerLowFertilizer extends Trigger { + + private final float threshold; + + public TriggerLowFertilizer(String tag, float threshold) { + super(tag, "lowFertilizer"); + this.threshold = threshold; + } + + @Override + public String getDescription() { + return super.getDescription() + " < " + threshold * 100 + "%"; + } + + @Override + public boolean isTriggerActive(ForgeDirection direction, TileEntity tile, ITriggerParameter parameter) { + if (!(tile instanceof TileHatch)) + return false; + + ITileStructure central = ((TileHatch) tile).getCentralTE(); + if (central == null || !(central instanceof TileFarmPlain)) + return false; + + ItemStack fertilizer = central.getInventory().getStackInSlot(TileFarmPlain.SLOT_FERTILIZER); + if (fertilizer == null) + return true; + return ((float) fertilizer.stackSize / fertilizer.getMaxStackSize()) <= threshold; + } +} diff --git a/forestry_common/farming/forestry/farming/triggers/TriggerLowLiquid.java b/forestry_common/farming/forestry/farming/triggers/TriggerLowLiquid.java new file mode 100755 index 000000000..e58c6dc15 --- /dev/null +++ b/forestry_common/farming/forestry/farming/triggers/TriggerLowLiquid.java @@ -0,0 +1,52 @@ +/******************************************************************************* + * Copyright 2011-2014 by SirSengir + * + * This work is licensed under a Creative Commons Attribution-NonCommercial-NoDerivs 3.0 Unported License. + * + * To view a copy of this license, visit http://creativecommons.org/licenses/by-nc-nd/3.0/. + ******************************************************************************/ +package forestry.farming.triggers; + +import net.minecraft.tileentity.TileEntity; + +import net.minecraftforge.common.util.ForgeDirection; + +import buildcraft.api.gates.ITriggerParameter; + +import forestry.api.core.ITileStructure; +import forestry.core.triggers.Trigger; +import forestry.core.utils.ForestryTank; +import forestry.farming.gadgets.TileFarmPlain; +import forestry.farming.gadgets.TileHatch; + +public class TriggerLowLiquid extends Trigger { + + private float threshold = 0.25F; + + public TriggerLowLiquid(String tag, float threshold) { + super(tag, "lowLiquid"); + this.threshold = threshold; + } + + @Override + public String getDescription() { + return super.getDescription() + " < " + threshold * 100 + "%"; + } + + /** + * Return true if the tile given in parameter activates the trigger, given + * the parameters. + */ + @Override + public boolean isTriggerActive(ForgeDirection direction, TileEntity tile, ITriggerParameter parameter) { + if (!(tile instanceof TileHatch)) + return false; + + ITileStructure central = ((TileHatch) tile).getCentralTE(); + if (central == null || !(central instanceof TileFarmPlain)) + return false; + + ForestryTank tank = ((TileFarmPlain) central).getTank(); + return ((float) tank.getFluidAmount() / tank.getCapacity()) <= threshold; + } +} diff --git a/forestry_common/farming/forestry/farming/triggers/TriggerLowSoil.java b/forestry_common/farming/forestry/farming/triggers/TriggerLowSoil.java new file mode 100755 index 000000000..9e5197fe2 --- /dev/null +++ b/forestry_common/farming/forestry/farming/triggers/TriggerLowSoil.java @@ -0,0 +1,65 @@ +/******************************************************************************* + * Copyright 2011-2014 by SirSengir + * + * This work is licensed under a Creative Commons Attribution-NonCommercial-NoDerivs 3.0 Unported License. + * + * To view a copy of this license, visit http://creativecommons.org/licenses/by-nc-nd/3.0/. + ******************************************************************************/ +package forestry.farming.triggers; + +import net.minecraft.init.Blocks; +import net.minecraft.item.ItemStack; +import net.minecraft.tileentity.TileEntity; + +import net.minecraftforge.common.util.ForgeDirection; + +import buildcraft.api.gates.ITriggerParameter; + +import forestry.api.core.ITileStructure; +import forestry.core.triggers.Trigger; +import forestry.farming.gadgets.TileFarmPlain; +import forestry.farming.gadgets.TileHatch; + +public class TriggerLowSoil extends Trigger { + + private int threshold = 64; + + public TriggerLowSoil(int threshold) { + super("lowSoil." + threshold, "lowSoil"); + this.threshold = threshold; + } + + @Override + public String getDescription() { + return super.getDescription() + " < " + threshold; + } + + @Override + public boolean hasParameter() { + return true; + } + + /** + * Return true if the tile given in parameter activates the trigger, given + * the parameters. + */ + @Override + public boolean isTriggerActive(ForgeDirection direction, TileEntity tile, ITriggerParameter parameter) { + if (!(tile instanceof TileHatch)) + return false; + + ITileStructure central = ((TileHatch) tile).getCentralTE(); + if (central == null || !(central instanceof TileFarmPlain)) + return false; + + ItemStack filter; + if (parameter == null || parameter.getItemStack() == null) + filter = new ItemStack(Blocks.air, threshold, -1); + else { + filter = parameter.getItemStack().copy(); + filter.stackSize = threshold; + } + + return !((TileFarmPlain) central).hasResources(new ItemStack[] { filter }); + } +} diff --git a/forestry_common/farming/forestry/farming/worldgen/WorldGenBigMushroom.java b/forestry_common/farming/forestry/farming/worldgen/WorldGenBigMushroom.java new file mode 100755 index 000000000..f2f3caf0c --- /dev/null +++ b/forestry_common/farming/forestry/farming/worldgen/WorldGenBigMushroom.java @@ -0,0 +1,149 @@ +/******************************************************************************* + * Copyright 2011-2014 by SirSengir + * + * This work is licensed under a Creative Commons Attribution-NonCommercial-NoDerivs 3.0 Unported License. + * + * To view a copy of this license, visit http://creativecommons.org/licenses/by-nc-nd/3.0/. + ******************************************************************************/ +// Decompiled by Jad v1.5.8g. Copyright 2001 Pavel Kouznetsov. +// Jad home page: http://www.kpdus.com/jad.html +// Decompiler options: packimports(3) braces deadcode fieldsfirst + +package forestry.farming.worldgen; + +import java.util.Random; + +import net.minecraft.block.Block; +import net.minecraft.init.Blocks; +import net.minecraft.world.World; +import net.minecraft.world.gen.feature.WorldGenerator; + +import forestry.core.config.Defaults; + +// Referenced classes of package net.minecraft.src: +// WorldGenerator, World, Block, BlockLeaves, +// BlockGrass, BlockMycelium, BlockFlower + +public class WorldGenBigMushroom extends WorldGenerator { + private final Block mushroom; + + public WorldGenBigMushroom(Block block) { + mushroom = block; + } + + public WorldGenBigMushroom() { + mushroom = null; + } + + @Override + public boolean generate(World world, Random random, int x, int y, int z) { + Block type = mushroom; + + if (type == null) { + type = random.nextBoolean() ? Blocks.brown_mushroom_block : Blocks.red_mushroom_block; + } + + int height = random.nextInt(1) + 2; + boolean flag = true; + if (y < 1 || y + height + 1 > Defaults.WORLD_HEIGHT) + return false; + + for (int i = y; i <= y + 1 + height; i++) { + byte offset = 3; + if (i == y) + offset = 0; + + for (int j = x - offset; j <= x + offset && flag; j++) + for (int k = z - offset; k <= z + offset && flag; k++) + if (i >= 0 && i < Defaults.WORLD_HEIGHT) { + Block block = world.getBlock(j, i, k); + if (!block.isAir(world, j, i, k) && block != Blocks.leaves) + flag = false; + } else + flag = false; + } + + if (!flag) + return false; + + Block ground = world.getBlock(x, y - 1, z); + if (ground != Blocks.mycelium) + return false; + + if (!Blocks.brown_mushroom.canPlaceBlockAt(world, x, y, z)) + return false; + + func_150515_a(world, x, y - 1, z, Blocks.dirt); + + int capStartY = y + height; + if (type == Blocks.red_mushroom_block) + capStartY = (y + height) - 1; + + for (int i = capStartY; i <= y + height; i++) { + + int capRad = 1; + + if (type == Blocks.brown_mushroom_block) + capRad = 1; + + for (int j = x - capRad; j <= x + capRad; j++) + for (int k = z - capRad; k <= z + capRad; k++) { + int remain = 5; + if (j == x - capRad) + remain--; + + if (j == x + capRad) + remain++; + + if (k == z - capRad) + remain -= 3; + + if (k == z + capRad) + remain += 3; + + if (type == Blocks.brown_mushroom_block || i < y + height) { + + if (j == x - (capRad - 1) && k == z - capRad) + remain = 1; + + if (j == x - capRad && k == z - (capRad - 1)) + remain = 1; + + if (j == x + (capRad - 1) && k == z - capRad) + remain = 3; + + if (j == x + capRad && k == z - (capRad - 1)) + remain = 3; + + if (j == x - (capRad - 1) && k == z + capRad) + remain = 7; + + if (j == x - capRad && k == z + (capRad - 1)) + remain = 7; + + if (j == x + (capRad - 1) && k == z + capRad) + remain = 9; + + if (j == x + capRad && k == z + (capRad - 1)) + remain = 9; + + } + if (remain == 5 && i < y + height) + remain = 0; + + if ((remain != 0 || y >= (y + height) - 1) && !world.getBlock(j, i, k).isOpaqueCube()) + setBlockAndNotifyAdequately(world, j, i, k, type, remain); + + } + + } + + for (int i = 0; i < height; i++) { + Block block = world.getBlock(x, y + i, z); + if (!block.isOpaqueCube()) + setBlockAndNotifyAdequately(world, x, y + i, z, type, 10); + } + + return true; + } +} diff --git a/forestry_common/farming/forestry/plugins/PluginFarmCraftory.java b/forestry_common/farming/forestry/plugins/PluginFarmCraftory.java new file mode 100755 index 000000000..4e5ccbf9e --- /dev/null +++ b/forestry_common/farming/forestry/plugins/PluginFarmCraftory.java @@ -0,0 +1,159 @@ +/******************************************************************************* + * Copyright 2011-2014 by SirSengir + * + * This work is licensed under a Creative Commons Attribution-NonCommercial-NoDerivs 3.0 Unported License. + * + * To view a copy of this license, visit http://creativecommons.org/licenses/by-nc-nd/3.0/. + ******************************************************************************/ +package forestry.plugins; + +import java.lang.reflect.Method; +import java.util.HashMap; + +import net.minecraft.block.Block; +import net.minecraft.item.Item; +import net.minecraft.item.ItemStack; +import net.minecraft.tileentity.TileEntity; + +import cpw.mods.fml.common.network.IGuiHandler; + +import forestry.api.core.PluginInfo; +import forestry.api.farming.Farmables; +import forestry.core.config.Defaults; +import forestry.core.interfaces.IOreDictionaryHandler; +import forestry.core.interfaces.ISaveEventHandler; +import forestry.core.proxy.Proxies; +import forestry.farming.logic.FarmableFarmCraftory; + +@PluginInfo(pluginID = "FarmCraftory", name = "FarmCraftory", author = "SirSengir", url = Defaults.URL, description = "Enables compatibility with FarmCraftory. Adds crops and vegetables to farms.") +public class PluginFarmCraftory extends NativePlugin { + + public static Block blockSingle; + public static Block blockMulti; + + public static Class classSingle; + public static Class classMulti; + + public static Method methodGrowthSingle; + public static Method methodGrowthMulti; + + public static HashMap vegetableSeeds = new HashMap(); + public static final String[] seedIdentifiers = new String[] { "turnipSeedBag", "cabbageSeedBag", "onionSeedBag", "spinachSeedBag", "leekSeedBag", + "cucumberSeedBag", "tomatoSeedBag", "eggplantSeedBag", "greenPepperSeedBag", "yamSeedBag", "strawberrySeedBag", "pineappleSeedBag" }; + public static HashMap vegetableItems = new HashMap(); + public static final String[] vegetableIdentifiers = new String[] { "turnipItem", "cabbageItem", "onionItem", "spinachItem", "leekItem", "cucumberItem", + "tomatoItem", "eggplantItem", "greenPepperItem", "yamItem", "strawberryItem", "pineappleItem" }; + + public static HashMap cerealSeeds = new HashMap(); + public static final String[] cseedIdentifiers = new String[] { "cornSeedBag" }; + public static HashMap cerealItems = new HashMap(); + public static final String[] cerealIdentifiers = new String[] { "cornItem" }; + + @Override + public boolean isAvailable() { + return Proxies.common.isModLoaded("FarmCraftory"); + } + + @Override + public void doInit() { + super.doInit(); + + try { + + blockSingle = (Block) Class.forName("farmcraftory.FarmCraftory").getField("singleHarvest").get(null); + blockMulti = (Block) Class.forName("farmcraftory.FarmCraftory").getField("multiHarvest").get(null); + + classSingle = Class.forName("farmcraftory.TileEntitySingleHarvest"); + classMulti = Class.forName("farmcraftory.TileEntityMultiHarvest"); + + methodGrowthSingle = classSingle.getMethod("getGrowthStage"); + methodGrowthMulti = classMulti.getMethod("getGrowthStage"); + + for (String str : seedIdentifiers) + try { + vegetableSeeds.put(str, new ItemStack((Item) Class.forName("farmcraftory.FarmCraftory").getField(str).get(null))); + } catch (Exception ex) { + Proxies.log.info("FarmCraftory item '%s' could not be integrated.", str); + Proxies.log.info(ex.getMessage()); + } + + for (String str : vegetableIdentifiers) + try { + vegetableItems.put(str, new ItemStack((Item) Class.forName("farmcraftory.FarmCraftory").getField(str).get(null))); + } catch (Exception ex) { + Proxies.log.info("FarmCraftory item '%s' could not be integrated.", str); + Proxies.log.info(ex.getMessage()); + } + + for (String str : cseedIdentifiers) + try { + cerealSeeds.put(str, new ItemStack((Item) Class.forName("farmcraftory.FarmCraftory").getField(str).get(null))); + } catch (Exception ex) { + Proxies.log.info("FarmCraftory item '%s' could not be integrated.", str); + Proxies.log.info(ex.getMessage()); + } + + for (String str : cerealIdentifiers) + try { + cerealItems.put(str, new ItemStack((Item) Class.forName("farmcraftory.FarmCraftory").getField(str).get(null))); + } catch (Exception ex) { + Proxies.log.info("FarmCraftory item '%s' could not be integrated.", str); + Proxies.log.info(ex.getMessage()); + } + + if (blockMulti != null && blockSingle != null) { + Farmables.farmables.get("farmWheat").add(new FarmableFarmCraftory(cerealSeeds.values(), cerealItems.values())); + Farmables.farmables.get("farmVegetables").add(new FarmableFarmCraftory(vegetableSeeds.values(), vegetableItems.values())); + } + + } catch (Exception ex) { + Proxies.log.info("FarmCraftory plugin unexpectedly failed to load."); + Proxies.log.info(ex.getMessage()); + } + } + + public static int getGrowthStage(TileEntity tile) { + try { + if (classSingle.isInstance(tile)) + return (Integer) methodGrowthSingle.invoke(tile); + else if (classMulti.isInstance(tile)) + return (Integer) methodGrowthMulti.invoke(tile); + } catch (Exception ex) { + return 0; + } + + return 0; + } + + @Override + public IGuiHandler getGuiHandler() { + return null; + } + + @Override + public ISaveEventHandler getSaveEventHandler() { + return null; + } + + @Override + public IOreDictionaryHandler getDictionaryHandler() { + return null; + } + + @Override + protected void registerItems() { + } + + @Override + protected void registerBackpackItems() { + } + + @Override + protected void registerCrates() { + } + + @Override + protected void registerRecipes() { + } + +} diff --git a/forestry_common/farming/forestry/plugins/PluginFarming.java b/forestry_common/farming/forestry/plugins/PluginFarming.java new file mode 100755 index 000000000..3fc36428f --- /dev/null +++ b/forestry_common/farming/forestry/plugins/PluginFarming.java @@ -0,0 +1,359 @@ +/******************************************************************************* + * Copyright 2011-2014 by SirSengir + * + * This work is licensed under a Creative Commons Attribution-NonCommercial-NoDerivs 3.0 Unported License. + * + * To view a copy of this license, visit http://creativecommons.org/licenses/by-nc-nd/3.0/. + ******************************************************************************/ +package forestry.plugins; + +import java.util.ArrayList; + +import net.minecraft.block.Block; +import net.minecraft.init.Blocks; +import net.minecraft.init.Items; +import net.minecraft.item.Item; +import net.minecraft.item.ItemStack; +import net.minecraft.nbt.NBTTagCompound; + +import cpw.mods.fml.common.SidedProxy; +import cpw.mods.fml.common.event.FMLInterModComms.IMCMessage; +import cpw.mods.fml.common.network.IGuiHandler; +import cpw.mods.fml.common.registry.GameData; +import cpw.mods.fml.common.registry.GameRegistry; + +import net.minecraftforge.common.MinecraftForge; + +import forestry.api.circuits.ChipsetManager; +import forestry.api.circuits.ICircuitLayout; +import forestry.api.core.PluginInfo; +import forestry.api.farming.Farmables; +import forestry.api.farming.IFarmable; +import forestry.core.circuits.Circuit; +import forestry.core.circuits.CircuitLayout; +import forestry.core.config.Config; +import forestry.core.config.Defaults; +import forestry.core.config.ForestryBlock; +import forestry.core.config.ForestryItem; +import forestry.core.interfaces.IOreDictionaryHandler; +import forestry.core.interfaces.ISaveEventHandler; +import forestry.core.proxy.Proxies; +import forestry.core.triggers.Trigger; +import forestry.core.utils.ShapedRecipeCustom; +import forestry.farming.EventHandlerFarming; +import forestry.farming.FarmHelper; +import forestry.farming.GuiHandlerFarming; +import forestry.farming.circuits.CircuitFarmLogic; +import forestry.farming.gadgets.BlockFarm; +import forestry.farming.gadgets.BlockMushroom; +import forestry.farming.gadgets.TileControl; +import forestry.farming.gadgets.TileFarm.EnumFarmBlock; +import forestry.farming.gadgets.TileFarmPlain; +import forestry.farming.gadgets.TileGearbox; +import forestry.farming.gadgets.TileHatch; +import forestry.farming.gadgets.TileValve; +import forestry.farming.items.ItemFarmBlock; +import forestry.farming.logic.FarmLogicArboreal; +import forestry.farming.logic.FarmLogicCereal; +import forestry.farming.logic.FarmLogicCocoa; +import forestry.farming.logic.FarmLogicGourd; +import forestry.farming.logic.FarmLogicInfernal; +import forestry.farming.logic.FarmLogicOrchard; +import forestry.farming.logic.FarmLogicPeat; +import forestry.farming.logic.FarmLogicPoale; +import forestry.farming.logic.FarmLogicRubber; +import forestry.farming.logic.FarmLogicShroom; +import forestry.farming.logic.FarmLogicSucculent; +import forestry.farming.logic.FarmLogicVegetable; +import forestry.farming.logic.FarmableGE; +import forestry.farming.logic.FarmableGenericCrop; +import forestry.farming.logic.FarmableGenericSapling; +import forestry.farming.logic.FarmableGourd; +import forestry.farming.logic.FarmableStacked; +import forestry.farming.logic.FarmableVanillaSapling; +import forestry.farming.logic.FarmableVanillaShroom; +import forestry.farming.proxy.ProxyFarming; +import forestry.farming.triggers.TriggerLowFertilizer; +import forestry.farming.triggers.TriggerLowLiquid; +import forestry.farming.triggers.TriggerLowSoil; + +@PluginInfo(pluginID = "Farming", name = "Farming", author = "SirSengir", url = Defaults.URL, description = "Adds automatic farms and harvesters for a wide variety of products.") +public class PluginFarming extends NativePlugin { + + @SidedProxy(clientSide = "forestry.farming.proxy.ClientProxyFarming", serverSide = "forestry.farming.proxy.ProxyFarming") + public static ProxyFarming proxy; + public static int modelIdFarmBlock; + public static ItemStack farmFertilizer; + public static Trigger lowResourceLiquid50; + public static Trigger lowResourceLiquid25; + public static Trigger lowSoil128; + public static Trigger lowSoil64; + public static Trigger lowSoil32; + public static Trigger lowFertilizer50; + public static Trigger lowFertilizer25; + + @Override + public boolean isAvailable() { + return !Config.disableFarming; + } + + @Override + public void preInit() { + super.preInit(); + + Farmables.farmInterface = new FarmHelper(); + + ForestryBlock.mushroom = new BlockMushroom(); + + Farmables.farmables.put("farmArboreal", new ArrayList()); + Farmables.farmables.get("farmArboreal").add(new FarmableVanillaSapling()); + Farmables.farmables.get("farmArboreal").add(new FarmableGE()); + + Farmables.farmables.put("farmShroom", new ArrayList()); + Farmables.farmables.get("farmShroom").add(new FarmableVanillaShroom(Blocks.brown_mushroom, 0)); + Farmables.farmables.get("farmShroom").add(new FarmableVanillaShroom(Blocks.red_mushroom, 0)); + + Farmables.farmables.put("farmWheat", new ArrayList()); + Farmables.farmables.get("farmWheat").add(new FarmableGenericCrop(new ItemStack(Items.wheat_seeds), Blocks.wheat, 7)); + + Farmables.farmables.put("farmGourd", new ArrayList()); + Farmables.farmables.get("farmGourd").add( + new FarmableGourd(new ItemStack(Items.pumpkin_seeds), new ItemStack(Blocks.pumpkin_stem), new ItemStack(Blocks.pumpkin))); + Farmables.farmables.get("farmGourd").add(new FarmableGourd(new ItemStack(Items.melon_seeds), new ItemStack(Blocks.melon_stem), new ItemStack(Blocks.melon_block))); + + Farmables.farmables.put("farmInfernal", new ArrayList()); + Farmables.farmables.get("farmInfernal").add(new FarmableGenericCrop(new ItemStack(Items.nether_wart), Blocks.nether_wart, 3)); + + Farmables.farmables.put("farmPoales", new ArrayList()); + Farmables.farmables.get("farmPoales").add(new FarmableStacked(Blocks.reeds, 3)); + + Farmables.farmables.put("farmSucculentes", new ArrayList()); + Farmables.farmables.get("farmSucculentes").add(new FarmableStacked(Blocks.cactus, 3)); + + Farmables.farmables.put("farmVegetables", new ArrayList()); + Farmables.farmables.get("farmVegetables").add(new FarmableGenericCrop(new ItemStack(Items.potato), Blocks.potatoes, 7)); + Farmables.farmables.get("farmVegetables").add(new FarmableGenericCrop(new ItemStack(Items.carrot), Blocks.carrots, 7)); + + ForestryBlock.farm = new BlockFarm().setBlockName("ffarm"); + Proxies.common.registerBlock(ForestryBlock.farm, ItemFarmBlock.class); + /*Item.itemsList[ForestryBlock.farm] = null; + Item.itemsList[ForestryBlock.farm] = (new ItemFarmBlock(ForestryBlock.farm - 256, "ffarm"));*/ + ForestryBlock.farm.setHarvestLevel("pickaxe", 0); + + proxy.initializeRendering(); + + // Triggers + lowResourceLiquid50 = new TriggerLowLiquid("lowLiquid.50", 0.5f); + lowResourceLiquid25 = new TriggerLowLiquid("lowLiquid.25", 0.25f); + lowSoil128 = new TriggerLowSoil(128); + lowSoil64 = new TriggerLowSoil(64); + lowSoil32 = new TriggerLowSoil(32); + lowFertilizer50 = new TriggerLowFertilizer("lowFertilizer.50", 0.5f); + lowFertilizer25 = new TriggerLowFertilizer("lowFertilizer.25", 0.25f); + + // Layouts + ICircuitLayout layoutManaged = new CircuitLayout("farms.managed"); + ChipsetManager.circuitRegistry.registerLayout(layoutManaged); + ICircuitLayout layoutManual = new CircuitLayout("farms.manual"); + ChipsetManager.circuitRegistry.registerLayout(layoutManual); + } + + @Override + public void doInit() { + super.doInit(); + + proxy.addLocalizations(); + + GameRegistry.registerTileEntity(TileFarmPlain.class, "forestry.Farm"); + GameRegistry.registerTileEntity(TileGearbox.class, "forestry.FarmGearbox"); + GameRegistry.registerTileEntity(TileHatch.class, "forestry.FarmHatch"); + GameRegistry.registerTileEntity(TileValve.class, "forestry.FarmValve"); + GameRegistry.registerTileEntity(TileControl.class, "forestry.FarmControl"); + + Circuit.farmArborealManaged = new CircuitFarmLogic("managedArboreal", FarmLogicArboreal.class, new String[] { "Arboreal Plants" }); + Circuit.farmShroomManaged = new CircuitFarmLogic("managedShroom", FarmLogicShroom.class, new String[] { "Mushrooms" }); + Circuit.farmPeatManaged = new CircuitFarmLogic("managedPeat", FarmLogicPeat.class, new String[] { "Peat Bog" }); + Circuit.farmCerealManaged = new CircuitFarmLogic("managedCereal", FarmLogicCereal.class, new String[] { "Crops" }); + Circuit.farmVegetableManaged = new CircuitFarmLogic("managedVegetable", FarmLogicVegetable.class, new String[] { "Vegetables" }); + Circuit.farmInfernalManaged = new CircuitFarmLogic("managedInfernal", FarmLogicInfernal.class, new String[] { "Infernal Crops" }); + + Circuit.farmPeatManual = new CircuitFarmLogic("manualPeat", FarmLogicPeat.class, new String[] { "Peat Bog" }).setManual(); + Circuit.farmShroomManual = new CircuitFarmLogic("manualShroom", FarmLogicShroom.class, new String[] { "Mushrooms" }).setManual(); + Circuit.farmCerealManual = new CircuitFarmLogic("manualCereal", FarmLogicCereal.class, new String[] { "Crops" }).setManual(); + Circuit.farmVegetableManual = new CircuitFarmLogic("manualVegetable", FarmLogicVegetable.class, new String[] { "Vegetables" }).setManual(); + Circuit.farmSucculentManual = new CircuitFarmLogic("manualSucculent", FarmLogicSucculent.class, new String[] { "Succulents" }).setManual(); + Circuit.farmPoalesManual = new CircuitFarmLogic("manualPoales", FarmLogicPoale.class, new String[] { "Reeds" }).setManual(); + Circuit.farmGourdManual = new CircuitFarmLogic("manualGourd", FarmLogicGourd.class, new String[] { "Gourds" }).setManual(); + Circuit.farmCocoaManual = new CircuitFarmLogic("manualCocoa", FarmLogicCocoa.class, new String[] { "Cocoa Plantation" }).setManual(); + + Circuit.farmOrchardManual = new CircuitFarmLogic("manualOrchard", FarmLogicOrchard.class, new String[] { "Orchard" }); + Circuit.farmRubberManual = new CircuitFarmLogic("manualRubber", FarmLogicRubber.class, new String[] { "Rubber Plantation" }); + + MinecraftForge.EVENT_BUS.register(new EventHandlerFarming()); + } + + @Override + public void postInit() { + super.postInit(); + farmFertilizer = ForestryItem.fertilizerCompound.getItemStack(); + } + + @Override + public boolean processIMCMessage(IMCMessage message) { + + if (message.key.equals("add-farmable-sapling")) { + String[] tokens = message.getStringValue().split("@"); + String errormsg = String.format("Received an invalid 'add-farmable-sapling' request '%s' from mod %s", message.getStringValue(), + message.getSender()); + if (tokens.length != 2) { + Proxies.log.info(errormsg + "."); + return true; + } + + if (!Farmables.farmables.containsKey(tokens[0])) { + Proxies.log.info("%s for non-existent farm %s.", errormsg, tokens[0]); + return true; + } + + String[] items = tokens[1].split("[\\.]+"); + if (items.length != 2 && items.length != 4) { + Proxies.log.info("%s for farm '%s': id definitions did not match.", errormsg, tokens[0]); + return true; + } + + try { + Block sapling = GameData.blockRegistry.getObject(items[0]); + if (sapling == null || sapling == Blocks.air) throw new RuntimeException("can't find block for "+items[0]); + + if (items.length == 2) { + Farmables.farmables.get(tokens[0]).add(new FarmableGenericSapling(sapling, Integer.parseInt(items[1]))); + } else { + Item windfall = GameData.itemRegistry.getObject(items[2]); + if (windfall == null) throw new RuntimeException("can't find item for "+items[2]); + + Farmables.farmables.get(tokens[0]).add( + new FarmableGenericSapling(sapling, Integer.parseInt(items[1]), + new ItemStack(windfall, 1, Integer.parseInt(items[3])))); + } + } catch (Exception ex) { + Proxies.log.info("%s for farm '%s': ", errormsg, tokens[0], ex.getMessage()); + } + return true; + + } else if (message.key.equals("add-farmable-crop")) { + + String[] tokens = message.getStringValue().split("@"); + String errormsg = String.format("Received an invalid 'add-farmable-crop' request '%s' from mod %s", message.getStringValue(), message.getSender()); + if (tokens.length != 2) { + Proxies.log.info(errormsg + "."); + return true; + } + + if (!Farmables.farmables.containsKey(tokens[0])) { + Proxies.log.info("%s for non-existent farm %s.", errormsg, tokens[0]); + return true; + } + + String[] items = tokens[1].split("[\\.]+"); + if (items.length != 4) { + Proxies.log.info("%s for farm '%s': id definitions did not match.", errormsg, tokens[0]); + return true; + } + + try { + Item seed = GameData.itemRegistry.getObject(items[0]); + if (seed == null) throw new RuntimeException("can't find item for "+items[0]); + Block crop = GameData.blockRegistry.getObject(items[2]); + if (crop == null || crop == Blocks.air) throw new RuntimeException("can't find block for "+items[2]); + + Farmables.farmables.get(tokens[0]).add( + new FarmableGenericCrop(new ItemStack(seed, 1, Integer.parseInt(items[1])), + crop, + Integer.parseInt(items[3]))); + } catch (Exception ex) { + Proxies.log.info("%s for farm '%s': ", errormsg, tokens[0], ex.getMessage()); + } + + return true; + } + + return false; + } + + @Override + public IGuiHandler getGuiHandler() { + return new GuiHandlerFarming(); + } + + @Override + public ISaveEventHandler getSaveEventHandler() { + return null; + } + + @Override + public IOreDictionaryHandler getDictionaryHandler() { + return null; + } + + @Override + protected void registerItems() { + } + + @Override + protected void registerBackpackItems() { + } + + @Override + protected void registerCrates() { + } + + @Override + protected void registerRecipes() { + + ItemStack basic = new ItemStack(ForestryBlock.farm, 1, 0); + for (EnumFarmBlock block : EnumFarmBlock.values()) { + NBTTagCompound compound = new NBTTagCompound(); + block.saveToCompound(compound); + + basic.setTagCompound((NBTTagCompound) compound.copy()); + ShapedRecipeCustom.buildRecipe(basic.copy(), "I#I", "WCW", '#', block.getCraftingIngredient(), 'W', "slabWood", 'C', ForestryItem.tubes.getItemStack(1, 1), 'I', "ingotCopper"); + + } + + ItemStack gearbox = new ItemStack(ForestryBlock.farm, 1, 2); + ShapedRecipeCustom.buildRecipe(gearbox, " # ", "TTT", '#', basic, 'T', "gearTin").setPreserveNBT(); + + ItemStack hatch = new ItemStack(ForestryBlock.farm, 1, 3); + ShapedRecipeCustom.buildRecipe(hatch, " # ", "TDT", '#', basic, 'T', "gearTin", 'D', Blocks.trapdoor).setPreserveNBT(); + + ItemStack valve = new ItemStack(ForestryBlock.farm, 1, 4); + ShapedRecipeCustom.buildRecipe(valve, " # ", "XTX", '#', basic, 'T', "gearTin", 'X', Blocks.glass).setPreserveNBT(); + + ItemStack control = new ItemStack(ForestryBlock.farm, 1, 5); + ShapedRecipeCustom.buildRecipe(control, " # ", "XTX", '#', basic, 'T', ForestryItem.tubes.getItemStack(1, 4), 'X', Items.redstone).setPreserveNBT(); + + // Circuits + ICircuitLayout layoutManaged = ChipsetManager.circuitRegistry.getLayout("forestry.farms.managed"); + ICircuitLayout layoutManual = ChipsetManager.circuitRegistry.getLayout("forestry.farms.manual"); + + ChipsetManager.solderManager.addRecipe(layoutManaged, ForestryItem.tubes.getItemStack(1, 0), Circuit.farmArborealManaged); + ChipsetManager.solderManager.addRecipe(layoutManaged, ForestryItem.tubes.getItemStack(1, 1), Circuit.farmPeatManaged); + ChipsetManager.solderManager.addRecipe(layoutManaged, ForestryItem.tubes.getItemStack(1, 2), Circuit.farmCerealManaged); + ChipsetManager.solderManager.addRecipe(layoutManaged, ForestryItem.tubes.getItemStack(1, 3), Circuit.farmVegetableManaged); + ChipsetManager.solderManager.addRecipe(layoutManaged, ForestryItem.tubes.getItemStack(1, 7), Circuit.farmInfernalManaged); + ChipsetManager.solderManager.addRecipe(layoutManaged, ForestryItem.tubes.getItemStack(1, 10), Circuit.farmShroomManaged); + + ChipsetManager.solderManager.addRecipe(layoutManual, ForestryItem.tubes.getItemStack(1, 0), Circuit.farmOrchardManual); + ChipsetManager.solderManager.addRecipe(layoutManual, ForestryItem.tubes.getItemStack(1, 1), Circuit.farmPeatManual); + ChipsetManager.solderManager.addRecipe(layoutManual, ForestryItem.tubes.getItemStack(1, 2), Circuit.farmCerealManual); + ChipsetManager.solderManager.addRecipe(layoutManual, ForestryItem.tubes.getItemStack(1, 3), Circuit.farmVegetableManual); + ChipsetManager.solderManager.addRecipe(layoutManual, ForestryItem.tubes.getItemStack(1, 4), Circuit.farmSucculentManual); + ChipsetManager.solderManager.addRecipe(layoutManual, ForestryItem.tubes.getItemStack(1, 5), Circuit.farmPoalesManual); + ChipsetManager.solderManager.addRecipe(layoutManual, ForestryItem.tubes.getItemStack(1, 6), Circuit.farmGourdManual); + ChipsetManager.solderManager.addRecipe(layoutManual, ForestryItem.tubes.getItemStack(1, 10), Circuit.farmShroomManual); + ChipsetManager.solderManager.addRecipe(layoutManual, ForestryItem.tubes.getItemStack(1, 11), Circuit.farmCocoaManual); + + if (PluginIC2.resin != null && PluginIC2.rubberwood != null) + ChipsetManager.solderManager.addRecipe(layoutManual, ForestryItem.tubes.getItemStack(1, 8), Circuit.farmRubberManual); + } +} diff --git a/forestry_common/farming/forestry/plugins/PluginNatura.java b/forestry_common/farming/forestry/plugins/PluginNatura.java new file mode 100755 index 000000000..de9f585fc --- /dev/null +++ b/forestry_common/farming/forestry/plugins/PluginNatura.java @@ -0,0 +1,107 @@ +/******************************************************************************* + * Copyright 2011-2014 by SirSengir + * + * This work is licensed under a Creative Commons Attribution-NonCommercial-NoDerivs 3.0 Unported License. + * + * To view a copy of this license, visit http://creativecommons.org/licenses/by-nc-nd/3.0/. + ******************************************************************************/ +package forestry.plugins; + +import java.util.ArrayList; + +import net.minecraft.block.Block; +import net.minecraft.item.ItemStack; + +import cpw.mods.fml.common.event.FMLInterModComms; +import cpw.mods.fml.common.registry.GameRegistry; + +import forestry.api.recipes.RecipeManagers; +import forestry.core.GameMode; +import forestry.core.config.Defaults; +import forestry.core.proxy.Proxies; +import forestry.core.utils.LiquidHelper; + +public class PluginNatura extends NativePlugin { + + private static final String NATURA = "Natura"; + + public static Block logNatura; + public static Block logWillow; + + public static Block leavesNatura; + public static Block saplingNatura; + + @Override + public boolean isAvailable() { + return Proxies.common.isModLoaded(NATURA); + } + + @Override + public void doInit() { + super.doInit(); + + logNatura = GameRegistry.findBlock(NATURA, "tree"); + logWillow = GameRegistry.findBlock(NATURA, "willow"); + leavesNatura = GameRegistry.findBlock(NATURA, "floraleaves"); + saplingNatura = GameRegistry.findBlock(NATURA, "florasapling"); + + if(saplingNatura != null) + FMLInterModComms.sendMessage(Defaults.MOD, "add-farmable-sapling", String.format("farmArboreal@%s.-1", saplingNatura)); + } + + @Override protected void registerItems() {} + @Override protected void registerBackpackItems() {} + @Override protected void registerCrates() {} + @Override + protected void registerRecipes() { + ItemStack seedBarley = GameRegistry.findItemStack(NATURA, "seedBarley", 1); + ItemStack seedCotton = GameRegistry.findItemStack(NATURA, "seedCotton", 1); + + ArrayList seedList = new ArrayList(); + if (seedBarley != null) + seedList.add(seedBarley); + if (seedCotton != null) + seedList.add(seedCotton); + + int amount = GameMode.getGameMode().getIntegerSetting("squeezer.liquid.seed"); + for (int i = 0; i < seedList.size(); ++i) { + RecipeManagers.squeezerManager.addRecipe(10, new ItemStack[] { seedList.get(i) }, + LiquidHelper.getLiquid(Defaults.LIQUID_SEEDOIL, amount)); + } + + ItemStack berryBlight = GameRegistry.findItemStack(NATURA, "berryBlight", 1); + ItemStack berryDusk = GameRegistry.findItemStack(NATURA, "berryDusk", 1); + ItemStack berrySky = GameRegistry.findItemStack(NATURA, "berrySting", 1); + ItemStack berrySting = GameRegistry.findItemStack(NATURA, "berrySting", 1); + ItemStack berryRasp = GameRegistry.findItemStack(NATURA, "berryRasp", 1); + ItemStack berryBlue = GameRegistry.findItemStack(NATURA, "berryBlue", 1); + ItemStack berryBlack = GameRegistry.findItemStack(NATURA, "berryBlack", 1); + ItemStack berryMalo = GameRegistry.findItemStack(NATURA, "berryMalo", 1); + + ArrayList berries = new ArrayList(); + if (berryBlight != null) + berries.add(berryBlight); + if (berryDusk != null) + berries.add(berryDusk); + if (berrySky != null) + berries.add(berrySky); + if (berrySting!= null) + berries.add(berrySting); + if (berryRasp != null) + berries.add(berryRasp); + if (berryBlue != null) + berries.add(berryBlue); + if (berryBlack != null) + berries.add(berryBlack); + if (berryMalo != null) + berries.add(berryMalo); + + amount = GameMode.getGameMode().getIntegerSetting("squeezer.liquid.apple") / 25; + amount = (amount > 1) ? amount : 1; // Produce at least 1 mb of juice. + for (int i = 0; i < berries.size(); ++i) { + RecipeManagers.squeezerManager.addRecipe(3, new ItemStack[] { berries.get(i) }, + LiquidHelper.getLiquid(Defaults.LIQUID_JUICE, amount)); + } + } + +} diff --git a/forestry_common/food/forestry/food/BeverageEffect.java b/forestry_common/food/forestry/food/BeverageEffect.java new file mode 100755 index 000000000..621f19684 --- /dev/null +++ b/forestry_common/food/forestry/food/BeverageEffect.java @@ -0,0 +1,48 @@ +/******************************************************************************* + * Copyright 2011-2014 by SirSengir + * + * This work is licensed under a Creative Commons Attribution-NonCommercial-NoDerivs 3.0 Unported License. + * + * To view a copy of this license, visit http://creativecommons.org/licenses/by-nc-nd/3.0/. + ******************************************************************************/ +package forestry.food; + +import forestry.api.food.BeverageManager; +import forestry.api.food.IBeverageEffect; +import forestry.core.utils.StringUtil; + +public abstract class BeverageEffect implements IBeverageEffect { + + public static final IBeverageEffect weakAlcoholic = new BeverageEffectDrunk(10, 0.2f); + public static final IBeverageEffect weakAntidote = new BeverageEffectAntidote(20, 0.5f); + public static final IBeverageEffect strongAntidote = new BeverageEffectAntidote(21, 1.0f); + + private int id; + protected String description; + + public BeverageEffect(int id) { + this.id = id; + + if (BeverageManager.effectList[id] != null) + throw new RuntimeException("Beverage effect slot " + id + " was already occupied by " + BeverageManager.effectList[id].toString() + + " when trying to add " + this.toString()); + else + BeverageManager.effectList[id] = this; + } + + public int getId() { + return this.id; + } + + public String getLevel() { + return null; + } + + @Override + public String getDescription() { + if (getLevel() != null) + return StringUtil.localize(description) + " " + getLevel(); + else + return StringUtil.localize(description); + } +} diff --git a/forestry_common/food/forestry/food/BeverageEffectAntidote.java b/forestry_common/food/forestry/food/BeverageEffectAntidote.java new file mode 100755 index 000000000..5db04f482 --- /dev/null +++ b/forestry_common/food/forestry/food/BeverageEffectAntidote.java @@ -0,0 +1,45 @@ +/******************************************************************************* + * Copyright 2011-2014 by SirSengir + * + * This work is licensed under a Creative Commons Attribution-NonCommercial-NoDerivs 3.0 Unported License. + * + * To view a copy of this license, visit http://creativecommons.org/licenses/by-nc-nd/3.0/. + ******************************************************************************/ +package forestry.food; + +import net.minecraft.entity.player.EntityPlayer; +import net.minecraft.potion.Potion; +import net.minecraft.world.World; + +import forestry.core.proxy.Proxies; + +public class BeverageEffectAntidote extends BeverageEffect { + + private float chance = 0.2f; + + public BeverageEffectAntidote(int id, float chance) { + super(id); + this.chance = chance; + this.description = "beverage.effect.antidote"; + } + + @Override + public void doEffect(World world, EntityPlayer player) { + + if (world.rand.nextFloat() >= chance) + return; + + Proxies.common.removePotionEffect(player, Potion.poison); + } + + @Override + public String getLevel() { + if (chance > 0.5f) + return "III"; + else if (chance > 0.2f) + return "II"; + else + return "I"; + } + +} diff --git a/forestry_common/food/forestry/food/BeverageEffectDrunk.java b/forestry_common/food/forestry/food/BeverageEffectDrunk.java new file mode 100755 index 000000000..f99343cec --- /dev/null +++ b/forestry_common/food/forestry/food/BeverageEffectDrunk.java @@ -0,0 +1,33 @@ +/******************************************************************************* + * Copyright 2011-2014 by SirSengir + * + * This work is licensed under a Creative Commons Attribution-NonCommercial-NoDerivs 3.0 Unported License. + * + * To view a copy of this license, visit http://creativecommons.org/licenses/by-nc-nd/3.0/. + ******************************************************************************/ +package forestry.food; + +import net.minecraft.entity.player.EntityPlayer; +import net.minecraft.potion.Potion; +import net.minecraft.potion.PotionEffect; +import net.minecraft.world.World; + +public class BeverageEffectDrunk extends BeverageEffect { + + private PotionEffect drunkEffect; + private float chance = 0.2f; + + public BeverageEffectDrunk(int id, float chance) { + super(id); + this.chance = chance; + this.description = "beverage.effect.alcoholic"; + drunkEffect = new PotionEffect(Potion.confusion.id, 25 * 20, 0); + } + + @Override + public void doEffect(World world, EntityPlayer player) { + if (world.rand.nextFloat() < chance) + player.addPotionEffect(drunkEffect); + } + +} diff --git a/forestry_common/food/forestry/food/GuiHandlerFood.java b/forestry_common/food/forestry/food/GuiHandlerFood.java new file mode 100755 index 000000000..6b42608dd --- /dev/null +++ b/forestry_common/food/forestry/food/GuiHandlerFood.java @@ -0,0 +1,52 @@ +/******************************************************************************* + * Copyright 2011-2014 by SirSengir + * + * This work is licensed under a Creative Commons Attribution-NonCommercial-NoDerivs 3.0 Unported License. + * + * To view a copy of this license, visit http://creativecommons.org/licenses/by-nc-nd/3.0/. + ******************************************************************************/ +package forestry.food; + +import net.minecraft.entity.player.EntityPlayer; +import net.minecraft.world.World; + +import forestry.core.GuiHandlerBase; +import forestry.core.network.GuiId; +import forestry.food.gui.ContainerInfuser; +import forestry.food.gui.GuiInfuser; +import forestry.food.items.ItemInfuser.InfuserInventory; + +public class GuiHandlerFood extends GuiHandlerBase { + @Override + public Object getClientGuiElement(int id, EntityPlayer player, World world, int x, int y, int z) { + + if (id >= GuiId.values().length) + return null; + + switch (GuiId.values()[id]) { + + case InfuserGUI: + return new GuiInfuser(player.inventory, new InfuserInventory(player)); + + default: + return null; + } + } + + @Override + public Object getServerGuiElement(int id, EntityPlayer player, World world, int x, int y, int z) { + + if (id >= GuiId.values().length) + return null; + + switch (GuiId.values()[id]) { + + case InfuserGUI: + return new ContainerInfuser(player.inventory, new InfuserInventory(player)); + + default: + return null; + + } + } +} diff --git a/forestry_common/food/forestry/food/gui/ContainerInfuser.java b/forestry_common/food/forestry/food/gui/ContainerInfuser.java new file mode 100755 index 000000000..df819b1c0 --- /dev/null +++ b/forestry_common/food/forestry/food/gui/ContainerInfuser.java @@ -0,0 +1,68 @@ +/******************************************************************************* + * Copyright 2011-2014 by SirSengir + * + * This work is licensed under a Creative Commons Attribution-NonCommercial-NoDerivs 3.0 Unported License. + * + * To view a copy of this license, visit http://creativecommons.org/licenses/by-nc-nd/3.0/. + ******************************************************************************/ +package forestry.food.gui; + +import net.minecraft.entity.player.EntityPlayer; +import net.minecraft.entity.player.InventoryPlayer; +import net.minecraft.inventory.Slot; +import net.minecraft.item.ItemStack; + +import forestry.core.config.ForestryItem; +import forestry.core.gui.ContainerForestry; +import forestry.core.gui.slots.SlotCustom; +import forestry.core.proxy.Proxies; +import forestry.food.items.ItemBeverage; +import forestry.food.items.ItemInfuser.InfuserInventory; + +public class ContainerInfuser extends ContainerForestry { + + InfuserInventory inventory; + + public ContainerInfuser(InventoryPlayer inventoryplayer, InfuserInventory inventory) { + super(inventory); + this.inventory = inventory; + + // Input + this.addSlot(new SlotCustom(inventory, 0, 152, 12, ForestryItem.beverage.getItemStack())); + + // Output + this.addSlot(new SlotCustom(inventory, 1, 152, 72, ItemBeverage.class)); + + // Ingredients + this.addSlot(new Slot(inventory, 2, 12, 12)); + this.addSlot(new Slot(inventory, 3, 12, 32)); + this.addSlot(new Slot(inventory, 4, 12, 52)); + this.addSlot(new Slot(inventory, 5, 12, 72)); + + // Player inventory + for (int i1 = 0; i1 < 3; i1++) + for (int l1 = 0; l1 < 9; l1++) + addSlot(new Slot(inventoryplayer, l1 + i1 * 9 + 9, 8 + l1 * 18, 103 + i1 * 18)); + // Player hotbar + for (int j1 = 0; j1 < 9; j1++) + addSlot(new Slot(inventoryplayer, j1, 8 + j1 * 18, 161)); + } + + @Override + public void onContainerClosed(EntityPlayer entityplayer) { + + if (!Proxies.common.isSimulating(entityplayer.worldObj)) + return; + + // Drop everything still in there. + for (int i = 0; i < inventory.getSizeInventory(); i++) { + ItemStack stack = inventory.getStackInSlot(i); + if (stack == null) + continue; + + Proxies.common.dropItemPlayer(entityplayer, stack); + inventory.setInventorySlotContents(i, null); + } + + } +} diff --git a/forestry_common/food/forestry/food/gui/GuiInfuser.java b/forestry_common/food/forestry/food/gui/GuiInfuser.java new file mode 100755 index 000000000..133a6c490 --- /dev/null +++ b/forestry_common/food/forestry/food/gui/GuiInfuser.java @@ -0,0 +1,55 @@ +/******************************************************************************* + * Copyright 2011-2014 by SirSengir + * + * This work is licensed under a Creative Commons Attribution-NonCommercial-NoDerivs 3.0 Unported License. + * + * To view a copy of this license, visit http://creativecommons.org/licenses/by-nc-nd/3.0/. + ******************************************************************************/ +package forestry.food.gui; + +import net.minecraft.entity.player.InventoryPlayer; +import net.minecraft.inventory.IInventory; + +import forestry.api.food.BeverageManager; +import forestry.core.config.Defaults; +import forestry.core.gadgets.TileForestry; +import forestry.core.gui.GuiForestry; +import forestry.food.items.ItemInfuser.InfuserInventory; + +public class GuiInfuser extends GuiForestry { + + private final IInventory inventory; + private int startX; + private int startY; + + public GuiInfuser(InventoryPlayer inventoryplayer, InfuserInventory inventory) { + super(Defaults.TEXTURE_PATH_GUI + "/infuser.png", new ContainerInfuser(inventoryplayer, inventory), inventory); + + this.inventory = inventory; + + xSize = 176; + ySize = 185; + } + + @Override + protected void drawGuiContainerBackgroundLayer(float var1, int mouseX, int mouseY) { + super.drawGuiContainerBackgroundLayer(var1, mouseX, mouseY); + + for (int l = 2; l < inventory.getSizeInventory(); l++) { + String description = BeverageManager.ingredientManager.getDescription(inventory.getStackInSlot(l)); + if (description == null) + description = "(No effect)"; + + int row = (l - 2) * 20; + fontRendererObj.drawString(description, startX + 32, startY + 16 + row, fontColor.get("gui.screen")); + } + } + + @Override + public void initGui() { + super.initGui(); + + startX = (this.width - this.xSize) / 2; + startY = (this.height - this.ySize) / 2; + } +} diff --git a/forestry_common/food/forestry/food/items/ItemAmbrosia.java b/forestry_common/food/forestry/food/items/ItemAmbrosia.java new file mode 100755 index 000000000..a99fc552c --- /dev/null +++ b/forestry_common/food/forestry/food/items/ItemAmbrosia.java @@ -0,0 +1,29 @@ +/******************************************************************************* + * Copyright 2011-2014 by SirSengir + * + * This work is licensed under a Creative Commons Attribution-NonCommercial-NoDerivs 3.0 Unported License. + * + * To view a copy of this license, visit http://creativecommons.org/licenses/by-nc-nd/3.0/. + ******************************************************************************/ +package forestry.food.items; + +import net.minecraft.item.ItemStack; +import net.minecraft.potion.Potion; + +import forestry.core.config.Defaults; +import forestry.core.items.ItemForestryFood; + +public class ItemAmbrosia extends ItemForestryFood { + + public ItemAmbrosia() { + super(Defaults.FOOD_AMBROSIA_HEAL, 0.6f); + setAlwaysEdible(); + setPotionEffect(Potion.regeneration.id, 40, 0, 1.0F); + } + + @Override + public boolean hasEffect(ItemStack itemstack) { + return true; + } + +} diff --git a/forestry_common/food/forestry/food/items/ItemBeverage.java b/forestry_common/food/forestry/food/items/ItemBeverage.java new file mode 100755 index 000000000..4dbe5869d --- /dev/null +++ b/forestry_common/food/forestry/food/items/ItemBeverage.java @@ -0,0 +1,226 @@ +/******************************************************************************* + * Copyright 2011-2014 by SirSengir + * + * This work is licensed under a Creative Commons Attribution-NonCommercial-NoDerivs 3.0 Unported License. + * + * To view a copy of this license, visit http://creativecommons.org/licenses/by-nc-nd/3.0/. + ******************************************************************************/ +package forestry.food.items; + +import java.util.List; + +import net.minecraft.client.renderer.texture.IIconRegister; +import net.minecraft.creativetab.CreativeTabs; +import net.minecraft.entity.player.EntityPlayer; +import net.minecraft.item.EnumAction; +import net.minecraft.item.Item; +import net.minecraft.item.ItemStack; +import net.minecraft.nbt.NBTTagCompound; +import net.minecraft.nbt.NBTTagList; +import net.minecraft.util.IIcon; +import net.minecraft.world.World; + +import cpw.mods.fml.relauncher.Side; +import cpw.mods.fml.relauncher.SideOnly; + +import forestry.api.food.BeverageManager; +import forestry.api.food.IBeverageEffect; +import forestry.core.CreativeTabForestry; +import forestry.core.config.Config; +import forestry.core.proxy.Proxies; +import forestry.core.render.TextureManager; +import forestry.core.utils.StringUtil; + +public class ItemBeverage extends Item { + + public static class BeverageInfo { + + public final String name; + private final String iconType; + public final int primaryColor; + public final int secondaryColor; + + @SideOnly(Side.CLIENT) + public IIcon iconBottle; + @SideOnly(Side.CLIENT) + public IIcon iconContents; + + public final int heal; + public final float saturation; + public final boolean isAlwaysEdible; + + public boolean isSecret = false; + + public BeverageInfo(String name, String iconType, int primaryColor, int secondaryColor, int heal, float saturation, boolean isAlwaysEdible) { + this.name = name; + this.iconType = iconType; + this.primaryColor = primaryColor; + this.secondaryColor = secondaryColor; + this.heal = heal; + this.saturation = saturation; + this.isAlwaysEdible = isAlwaysEdible; + } + + @SideOnly(Side.CLIENT) + public void registerIcons(IIconRegister register) { + iconBottle = TextureManager.getInstance().registerTex(register, "liquids/" + iconType + ".bottle"); + iconContents = TextureManager.getInstance().registerTex(register, "liquids/" + iconType + ".contents"); + } + + public IBeverageEffect[] loadEffects(ItemStack stack) { + IBeverageEffect[] effects = new IBeverageEffect[0]; + + NBTTagCompound nbttagcompound = stack.getTagCompound(); + if (nbttagcompound == null) + return effects; + + if (nbttagcompound.hasKey("E")) { + int effectLength = nbttagcompound.getInteger("L"); + NBTTagList nbttaglist = nbttagcompound.getTagList("E", 10); + effects = new IBeverageEffect[effectLength]; + for (int i = 0; i < nbttaglist.tagCount(); i++) { + NBTTagCompound nbttagcompound1 = nbttaglist.getCompoundTagAt(i); + byte byte0 = nbttagcompound1.getByte("S"); + if (byte0 >= 0 && byte0 < effects.length) + effects[byte0] = BeverageManager.effectList[nbttagcompound1.getInteger("ID")]; + } + } + + return effects; + } + + public void saveEffects(ItemStack stack, IBeverageEffect[] effects) { + NBTTagCompound nbttagcompound = new NBTTagCompound(); + + NBTTagList nbttaglist = new NBTTagList(); + nbttagcompound.setInteger("L", effects.length); + for (int i = 0; i < effects.length; i++) + if (effects[i] != null) { + NBTTagCompound nbttagcompound1 = new NBTTagCompound(); + nbttagcompound1.setByte("S", (byte) i); + nbttagcompound1.setInteger("ID", effects[i].getId()); + nbttaglist.appendTag(nbttagcompound1); + } + nbttagcompound.setTag("E", nbttaglist); + + stack.setTagCompound(nbttagcompound); + } + + } + + public BeverageInfo[] beverages; + + public ItemBeverage(BeverageInfo... beverages) { + super(); + setMaxStackSize(1); + this.beverages = beverages; + setCreativeTab(CreativeTabForestry.tabForestry); + } + + /** + * @return true if the item's stackTagCompound needs to be synchronized over SMP. + */ + @Override + public boolean getShareTag() { + return true; + } + + @Override + public ItemStack onEaten(ItemStack itemstack, World world, EntityPlayer entityplayer) { + + int meta = itemstack.getItemDamage(); + BeverageInfo beverage = beverages[meta]; + IBeverageEffect[] effects = beverage.loadEffects(itemstack); + + itemstack.stackSize--; + entityplayer.getFoodStats().addStats(beverage.heal, beverage.saturation); + world.playSoundAtEntity(entityplayer, "random.burp", 0.5F, world.rand.nextFloat() * 0.1F + 0.9F); + + if (!Proxies.common.isSimulating(world)) + return itemstack; + + for (IBeverageEffect effect : effects) + effect.doEffect(world, entityplayer); + + return itemstack; + } + + @Override + public int getMaxItemUseDuration(ItemStack itemstack) { + return 32; + } + + @Override + public EnumAction getItemUseAction(ItemStack itemstack) { + return EnumAction.drink; + } + + @Override + public ItemStack onItemRightClick(ItemStack itemstack, World world, EntityPlayer entityplayer) { + + int meta = itemstack.getItemDamage(); + BeverageInfo beverage = beverages[meta]; + + if (entityplayer.canEat(beverage.isAlwaysEdible)) + entityplayer.setItemInUse(itemstack, getMaxItemUseDuration(itemstack)); + return itemstack; + } + + @SuppressWarnings({ "rawtypes", "unchecked" }) + @Override + public void getSubItems(Item item, CreativeTabs par2CreativeTabs, List itemList) { + for (int i = 0; i < beverages.length; i++) + if (Config.isDebug || !beverages[i].isSecret) + itemList.add(new ItemStack(this, 1, i)); + } + + @SuppressWarnings({ "rawtypes", "unchecked" }) + @Override + public void addInformation(ItemStack itemstack, EntityPlayer player, List list, boolean flag) { + int meta = itemstack.getItemDamage(); + BeverageInfo beverage = beverages[meta]; + IBeverageEffect[] effects = beverage.loadEffects(itemstack); + + for (IBeverageEffect effect : effects) + if (effect.getDescription() != null) + list.add(effect.getDescription()); + } + + @Override + public String getItemStackDisplayName(ItemStack itemstack) { + return StringUtil.localize("item.beverage." + beverages[itemstack.getItemDamage()].name); + } + + /* ICONS */ + @SideOnly(Side.CLIENT) + @Override + public void registerIcons(IIconRegister register) { + for (BeverageInfo info : beverages) + info.registerIcons(register); + } + + @SideOnly(Side.CLIENT) + @Override + public IIcon getIconFromDamageForRenderPass(int i, int j) { + if (j > 0 && beverages[i].secondaryColor != 0) + return beverages[i].iconBottle; + else + return beverages[i].iconContents; + } + + // Return true to enable color overlay + @Override + public boolean requiresMultipleRenderPasses() { + return true; + } + + @Override + public int getColorFromItemStack(ItemStack itemstack, int j) { + + if (j == 0 || beverages[itemstack.getItemDamage()].secondaryColor == 0) + return beverages[itemstack.getItemDamage()].primaryColor; + else + return beverages[itemstack.getItemDamage()].secondaryColor; + } + +} diff --git a/forestry_common/food/forestry/food/items/ItemInfuser.java b/forestry_common/food/forestry/food/items/ItemInfuser.java new file mode 100755 index 000000000..1e26f6dc3 --- /dev/null +++ b/forestry_common/food/forestry/food/items/ItemInfuser.java @@ -0,0 +1,394 @@ +/******************************************************************************* + * Copyright 2011-2014 by SirSengir + * + * This work is licensed under a Creative Commons Attribution-NonCommercial-NoDerivs 3.0 Unported License. + * + * To view a copy of this license, visit http://creativecommons.org/licenses/by-nc-nd/3.0/. + ******************************************************************************/ +package forestry.food.items; + +import java.util.ArrayList; +import java.util.Arrays; + +import net.minecraft.entity.player.EntityPlayer; +import net.minecraft.inventory.IInventory; +import net.minecraft.item.ItemStack; +import net.minecraft.world.World; + +import forestry.api.core.ForestryAPI; +import forestry.api.food.BeverageManager; +import forestry.api.food.IBeverageEffect; +import forestry.api.food.IInfuserManager; +import forestry.api.food.IIngredientManager; +import forestry.core.CreativeTabForestry; +import forestry.core.config.ForestryItem; +import forestry.core.items.ItemForestry; +import forestry.core.network.GuiId; +import forestry.core.proxy.Proxies; +import forestry.food.BeverageEffect; + +public class ItemInfuser extends ItemForestry { + + // / RECIPE MANAGMENT + /** + * Mixture describes the itemstacks required to achieve a certain effect. + */ + public static class Mixture { + + private final int meta; + private final ItemStack[] ingredients; + private final IBeverageEffect effect; + + public Mixture(int meta, ItemStack ingredient, IBeverageEffect effect) { + this(meta, new ItemStack[] { ingredient }, effect); + } + + public Mixture(int meta, ItemStack ingredients[], IBeverageEffect effect) { + this.meta = meta; + this.ingredients = ingredients; + this.effect = effect; + } + + public ItemStack[] getIngredients() { + return ingredients; + } + + public boolean isIngredient(ItemStack itemstack) { + for (ItemStack ingredient : ingredients) { + if (ingredient.getItemDamage() < 0 && ingredient.getItem() == itemstack.getItem()) + return true; + else if (ingredient.getItemDamage() >= 0 && ingredient.isItemEqual(itemstack)) + return true; + } + + return false; + } + + public boolean matches(ItemStack[] res) { + + // No recipe without resource! + if (res == null || res.length <= 0) + return false; + + boolean matchedAll = true; + + for (ItemStack stack : ingredients) { + boolean matched = false; + for (ItemStack matchStack : res) { + if (matchStack == null) + continue; + + // Check item matching + if (stack.getItemDamage() < 0 && stack.getItem() == matchStack.getItem()) { + if (stack.stackSize <= matchStack.stackSize) { + matched = true; + break; + } + } else if (stack.getItemDamage() >= 0 && stack.isItemEqual(matchStack)) + if (stack.stackSize <= matchStack.stackSize) { + matched = true; + break; + } + } + if (!matched) + matchedAll = false; + } + return matchedAll; + + } + + public IBeverageEffect getEffect() { + return this.effect; + } + + public int getMeta() { + return meta; + } + + public int getWeight() { + return ingredients.length; + } + } + + /** + * MixtureManager contains the available mixtures. + */ + public static class MixtureManager implements IInfuserManager { + + private final ArrayList mixtures = new ArrayList(); + + @Override + public void addMixture(int meta, ItemStack ingredient, IBeverageEffect effect) { + this.mixtures.add(new Mixture(meta, ingredient, effect)); + } + + @Override + public void addMixture(int meta, ItemStack[] ingredients, IBeverageEffect effect) { + this.mixtures.add(new Mixture(meta, ingredients, effect)); + } + + public boolean isIngredient(ItemStack itemstack) { + for (Mixture ingredient : mixtures) { + if (ingredient.isIngredient(itemstack)) + return true; + } + + return false; + } + + private Mixture[] getMatchingMixtures(ItemStack[] ingredients) { + + ArrayList matches = new ArrayList(); + + for (Mixture mixture : mixtures) { + if (mixture.matches(ingredients)) + matches.add(mixture); + } + + return matches.toArray(new Mixture[0]); + } + + @Override + public boolean hasMixtures(ItemStack[] ingredients) { + return getMatchingMixtures(ingredients).length > 0; + } + + @Override + public ItemStack[] getRequired(ItemStack[] ingredients) { + Mixture[] mixtures = getMatchingMixtures(ingredients); + ArrayList required = new ArrayList(); + + for (Mixture mixture : mixtures) { + required.addAll(Arrays.asList(mixture.getIngredients())); + } + + return required.toArray(new ItemStack[0]); + } + + @Override + public ItemStack getSeasoned(ItemStack base, ItemStack[] ingredients) { + Mixture[] mixtures = getMatchingMixtures(ingredients); + ArrayList effects = new ArrayList(); + effects.addAll(Arrays.asList(((ItemBeverage) base.getItem()).beverages[base.getItemDamage()].loadEffects(base))); + + int weight = 0; + int meta = 0; + for (Mixture mixture : mixtures) { + effects.add(mixture.getEffect()); + if (mixture.getWeight() > weight) { + weight = mixture.getWeight(); + meta = mixture.getMeta(); + } + } + + ItemStack seasoned = base.copy(); + seasoned.setItemDamage(meta); + ((ItemBeverage) base.getItem()).beverages[meta].saveEffects(seasoned, effects.toArray(new IBeverageEffect[0])); + return seasoned; + } + } + + public static class Ingredient { + + public final ItemStack ingredient; + public final String description; + + public Ingredient(ItemStack ingredient, String description) { + this.ingredient = ingredient; + this.description = description; + } + } + + public static class IngredientManager implements IIngredientManager { + + private final ArrayList ingredients = new ArrayList(); + + @Override + public void addIngredient(ItemStack ingredient, String description) { + this.ingredients.add(new Ingredient(ingredient, description)); + } + + @Override + public String getDescription(ItemStack itemstack) { + if (itemstack == null) + return null; + + for (Ingredient ingredient : ingredients) { + if (ingredient.ingredient.getItemDamage() < 0 && ingredient.ingredient.getItem() == itemstack.getItem()) + return ingredient.description; + else if (ingredient.ingredient.getItemDamage() >= 0 && ingredient.ingredient.isItemEqual(itemstack)) + return ingredient.description; + } + + return null; + } + } + + // / INVENTORY MANAGMENT + public static class InfuserInventory implements IInventory { + + private final ItemStack[] inventoryStacks = new ItemStack[6]; + private final short inputSlot = 0; + private final short outputSlot = 1; + private final short ingredientSlot1 = 2; + EntityPlayer player; + + public InfuserInventory(EntityPlayer player) { + this.player = player; + } + + private void trySeasoning() { + + // Need input + if (inventoryStacks[inputSlot] == null) + return; + + // Output slot may not be occupied + if (inventoryStacks[outputSlot] != null) + return; + + // Need a valid base + if (!inventoryStacks[inputSlot].isItemEqual(ForestryItem.beverage.getItemStack())) + return; + + // Create the seasoned item + ItemStack[] ingredients = new ItemStack[4]; + System.arraycopy(inventoryStacks, ingredientSlot1, ingredients, 0, 4); + + // Only continue if there is anything to season + if (!BeverageManager.infuserManager.hasMixtures(ingredients)) + return; + + ItemStack seasoned = BeverageManager.infuserManager.getSeasoned(inventoryStacks[inputSlot], ingredients); + if (seasoned == null) + return; + + // Remove required ingredients. + ItemStack[] toRemove = BeverageManager.infuserManager.getRequired(ingredients); + for (ItemStack templ : toRemove) { + ItemStack ghost = templ.copy(); + + for (int i = ingredientSlot1; i < this.getSizeInventory(); i++) { + if (inventoryStacks[i] == null) + continue; + if (ghost.stackSize <= 0) + break; + + if ((ghost.getItemDamage() >= 0 && inventoryStacks[i].isItemEqual(ghost)) + || (ghost.getItemDamage() < 0 && ghost.getItem() == inventoryStacks[i].getItem())) { + ItemStack removed = decrStackSize(i, 1); + ghost.stackSize -= removed.stackSize; + } + } + } + decrStackSize(inputSlot, 1); + inventoryStacks[outputSlot] = seasoned; + + } + + @Override + public ItemStack decrStackSize(int i, int j) { + if (inventoryStacks[i] == null) + return null; + + ItemStack product; + if (inventoryStacks[i].stackSize <= j) { + product = inventoryStacks[i]; + inventoryStacks[i] = null; + return product; + } else { + product = inventoryStacks[i].splitStack(j); + if (inventoryStacks[i].stackSize == 0) + inventoryStacks[i] = null; + + return product; + } + } + + @Override + public void markDirty() { + if (!Proxies.common.isSimulating(player.worldObj)) + return; + trySeasoning(); + } + + @Override + public void setInventorySlotContents(int i, ItemStack itemstack) { + inventoryStacks[i] = itemstack; + } + + @Override + public ItemStack getStackInSlot(int i) { + return inventoryStacks[i]; + } + + @Override + public int getSizeInventory() { + return inventoryStacks.length; + } + + @Override + public String getInventoryName() { + return "Infuser"; + } + + @Override + public int getInventoryStackLimit() { + return 64; + } + + @Override + public boolean isUseableByPlayer(EntityPlayer entityplayer) { + return true; + } + + @Override + public void openInventory() { + } + + @Override + public void closeInventory() { + } + + @Override + public ItemStack getStackInSlotOnClosing(int slot) { + if (inventoryStacks[slot] == null) + return null; + ItemStack toReturn = inventoryStacks[slot]; + inventoryStacks[slot] = null; + return toReturn; + } + + @Override + public boolean hasCustomInventoryName() { + return true; + } + + @Override + public boolean isItemValidForSlot(int i, ItemStack itemstack) { + return true; + } + } + + public ItemInfuser() { + super(); + setMaxStackSize(1); + setCreativeTab(CreativeTabForestry.tabForestry); + } + + @Override + public ItemStack onItemRightClick(ItemStack itemstack, World world, EntityPlayer entityplayer) { + if (Proxies.common.isSimulating(world)) + entityplayer.openGui(ForestryAPI.instance, GuiId.InfuserGUI.ordinal(), world, (int) entityplayer.posX, (int) entityplayer.posY, + (int) entityplayer.posZ); + + return itemstack; + } + + public static void initialize() { + BeverageManager.ingredientManager.addIngredient(ForestryItem.pollen.getItemStack(1, 0), "Strong Curative"); + BeverageManager.ingredientManager.addIngredient(ForestryItem.pollen.getItemStack(1, 1), "Weak Curative"); + BeverageManager.infuserManager.addMixture(1, ForestryItem.pollen.getItemStack(1, 0), BeverageEffect.strongAntidote); + BeverageManager.infuserManager.addMixture(1, ForestryItem.pollen.getItemStack(1, 1), BeverageEffect.weakAntidote); + } +} diff --git a/forestry_common/food/forestry/plugins/PluginFood.java b/forestry_common/food/forestry/plugins/PluginFood.java new file mode 100755 index 000000000..21ba551b1 --- /dev/null +++ b/forestry_common/food/forestry/plugins/PluginFood.java @@ -0,0 +1,110 @@ +/******************************************************************************* + * Copyright 2011-2014 by SirSengir + * + * This work is licensed under a Creative Commons Attribution-NonCommercial-NoDerivs 3.0 Unported License. + * + * To view a copy of this license, visit http://creativecommons.org/licenses/by-nc-nd/3.0/. + ******************************************************************************/ +package forestry.plugins; + +import net.minecraft.init.Items; +import net.minecraft.item.ItemStack; + +import cpw.mods.fml.common.network.IGuiHandler; + +import forestry.api.core.PluginInfo; +import forestry.api.food.BeverageManager; +import forestry.api.food.IBeverageEffect; +import forestry.core.config.Config; +import forestry.core.config.Defaults; +import forestry.core.config.ForestryItem; +import forestry.core.interfaces.IOreDictionaryHandler; +import forestry.core.interfaces.ISaveEventHandler; +import forestry.core.items.ItemForestryFood; +import forestry.core.proxy.Proxies; +import forestry.core.utils.LiquidHelper; +import forestry.food.BeverageEffect; +import forestry.food.GuiHandlerFood; +import forestry.food.items.ItemAmbrosia; +import forestry.food.items.ItemBeverage; +import forestry.food.items.ItemBeverage.BeverageInfo; +import forestry.food.items.ItemInfuser; + +@PluginInfo(pluginID = "Food", name = "Food", author = "SirSengir", url = Defaults.URL, description = "Adds food.") +public class PluginFood extends NativePlugin { + + @Override + public boolean isAvailable() { + return !Config.disableFood; + } + + @Override + public void preInit() { + super.preInit(); + + // Init seasoner + BeverageManager.infuserManager = new ItemInfuser.MixtureManager(); + BeverageManager.ingredientManager = new ItemInfuser.IngredientManager(); + } + + @Override + public void postInit() { + super.postInit(); + + ItemInfuser.initialize(); + } + + @Override + protected void registerItems() { + // / FOOD ITEMS + ForestryItem.honeyedSlice.registerItem(new ItemForestryFood(8, 0.6f), "honeyedSlice"); + ForestryItem.beverage.registerItem(new ItemBeverage( + new BeverageInfo("meadShort", "glass", 0xec9a19, 0xffffff, 1, 0.2f, true), + new BeverageInfo("meadCurative", "glass", 0xc5feff, 0xffffff, 1, 0.2f, true)), + "shortMead"); + ForestryItem.ambrosia.registerItem(new ItemAmbrosia().setIsDrink(), "ambrosia"); + ForestryItem.honeyPot.registerItem(new ItemForestryFood(2, 0.2f).setIsDrink(), "honeyPot"); + + // / SEASONER + ForestryItem.infuser.registerItem(new ItemInfuser(), "infuser"); + + // Mead + ItemStack meadBottle = ForestryItem.beverage.getItemStack(); + ((ItemBeverage) ForestryItem.beverage.item()).beverages[0].saveEffects(meadBottle, new IBeverageEffect[] { BeverageEffect.weakAlcoholic }); + + LiquidHelper.getOrCreateLiquid(Defaults.LIQUID_MEAD); + LiquidHelper.injectLiquidContainer(Defaults.LIQUID_MEAD, Defaults.BUCKET_VOLUME, meadBottle, new ItemStack(Items.glass_bottle)); + } + + @Override + protected void registerBackpackItems() { + } + + @Override + protected void registerRecipes() { + // INFUSER + Proxies.common.addRecipe(ForestryItem.infuser.getItemStack(), + "X", "#", "X", + '#', Items.iron_ingot, + 'X', "ingotBronze"); + } + + @Override + protected void registerCrates() { + } + + @Override + public IGuiHandler getGuiHandler() { + return new GuiHandlerFood(); + } + + @Override + public ISaveEventHandler getSaveEventHandler() { + return null; + } + + @Override + public IOreDictionaryHandler getDictionaryHandler() { + return null; + } +} diff --git a/forestry_common/lepidopterology/forestry/lepidopterology/ButterflySpawner.java b/forestry_common/lepidopterology/forestry/lepidopterology/ButterflySpawner.java new file mode 100755 index 000000000..148157231 --- /dev/null +++ b/forestry_common/lepidopterology/forestry/lepidopterology/ButterflySpawner.java @@ -0,0 +1,55 @@ +/******************************************************************************* + * Copyright 2011-2014 by SirSengir + * + * This work is licensed under a Creative Commons Attribution-NonCommercial-NoDerivs 3.0 Unported License. + * + * To view a copy of this license, visit http://creativecommons.org/licenses/by-nc-nd/3.0/. + ******************************************************************************/ +package forestry.lepidopterology; + +import net.minecraft.world.World; + +import forestry.api.arboriculture.ILeafTickHandler; +import forestry.api.arboriculture.ITree; +import forestry.api.lepidopterology.IButterfly; +import forestry.core.proxy.Proxies; +import forestry.lepidopterology.entities.EntityButterfly; +import forestry.plugins.PluginLepidopterology; + +public class ButterflySpawner implements ILeafTickHandler { + + @Override + public boolean onRandomLeafTick(ITree tree, World world, int biomeId, int x, int y, int z, boolean isDestroyed) { + + if(world.rand.nextFloat() >= tree.getGenome().getSappiness() * tree.getGenome().getYield()) + return false; + + IButterfly spawn = PluginLepidopterology.butterflyInterface.getIndividualTemplates().get(world.rand.nextInt(PluginLepidopterology.butterflyInterface.getIndividualTemplates().size())); + if(world.rand.nextFloat() >= spawn.getGenome().getPrimary().getRarity() * 0.5f) + return false; + + if(world.countEntities(EntityButterfly.class) > PluginLepidopterology.spawnConstraint) + return false; + + if(!spawn.canSpawn(world, x, y, z)) + return false; + + if(world.isAirBlock(x - 1, y, z)) { + attemptButterflySpawn(world, spawn, x - 1, y, z); + } else if(world.isAirBlock(x + 1, y, z)) { + attemptButterflySpawn(world, spawn, x + 1, y, z); + } else if(world.isAirBlock(x, y, z - 1)) { + attemptButterflySpawn(world, spawn, x, y, z - 1); + } else if(world.isAirBlock(x, y, z + 1)) { + attemptButterflySpawn(world, spawn, x, y, z + 1); + } + + return false; + } + + private void attemptButterflySpawn(World world, IButterfly butterfly, double x, double y, double z) { + if(PluginLepidopterology.butterflyInterface.spawnButterflyInWorld(world, butterfly.copy(), x, y + 0.1f, z) != null) + Proxies.log.finest("Spawned a butterfly '%s' at %s/%s/%s.", butterfly.getDisplayName(), x, y, z); + } + +} diff --git a/forestry_common/lepidopterology/forestry/lepidopterology/GuiHandlerLepidopterology.java b/forestry_common/lepidopterology/forestry/lepidopterology/GuiHandlerLepidopterology.java new file mode 100755 index 000000000..64c5475f7 --- /dev/null +++ b/forestry_common/lepidopterology/forestry/lepidopterology/GuiHandlerLepidopterology.java @@ -0,0 +1,72 @@ +/******************************************************************************* + * Copyright 2011-2014 by SirSengir + * + * This work is licensed under a Creative Commons Attribution-NonCommercial-NoDerivs 3.0 Unported License. + * + * To view a copy of this license, visit http://creativecommons.org/licenses/by-nc-nd/3.0/. + ******************************************************************************/ +package forestry.lepidopterology; + +import net.minecraft.entity.player.EntityPlayer; +import net.minecraft.item.ItemStack; +import net.minecraft.world.World; + +import forestry.core.GuiHandlerBase; +import forestry.core.network.GuiId; +import forestry.lepidopterology.genetics.ButterflyHelper; +import forestry.lepidopterology.gui.ContainerFlutterlyzer; +import forestry.lepidopterology.gui.GuiFlutterlyzer; +import forestry.lepidopterology.items.ItemFlutterlyzer.FlutterlyzerInventory; + +public class GuiHandlerLepidopterology extends GuiHandlerBase { + + @Override + public Object getServerGuiElement(int id, EntityPlayer player, World world, int x, int y, int z) { + int cleanId = decodeGuiID(id); + int guiData = decodeGuiData(id); + + if (cleanId >= GuiId.values().length) + return null; + + switch (GuiId.values()[cleanId]) { + case FlutterlyzerGUI: + ItemStack equipped = getEquippedItem(player); + if (equipped == null) + return null; + + return new ContainerFlutterlyzer(player.inventory, new FlutterlyzerInventory(player, equipped)); + + case LepidopteristChestGUI: + return getNaturalistChestContainer(ButterflyHelper.UID, player, world, x, y, z, guiData); + + default: + return null; + + } + } + + @Override + public Object getClientGuiElement(int id, EntityPlayer player, World world, int x, int y, int z) { + int cleanId = decodeGuiID(id); + int guiData = decodeGuiData(id); + + if (cleanId >= GuiId.values().length) + return null; + + switch (GuiId.values()[cleanId]) { + case FlutterlyzerGUI: + ItemStack equipped = getEquippedItem(player); + if (equipped == null) + return null; + + return new GuiFlutterlyzer(player, new FlutterlyzerInventory(player, equipped)); + + case LepidopteristChestGUI: + return getNaturalistChestGui(ButterflyHelper.UID, player, world, x, y, z, guiData); + + default: + return null; + + } + } +} diff --git a/forestry_common/lepidopterology/forestry/lepidopterology/MatingRecipe.java b/forestry_common/lepidopterology/forestry/lepidopterology/MatingRecipe.java new file mode 100755 index 000000000..7db9e1848 --- /dev/null +++ b/forestry_common/lepidopterology/forestry/lepidopterology/MatingRecipe.java @@ -0,0 +1,76 @@ +/******************************************************************************* + * Copyright 2011-2014 by SirSengir + * + * This work is licensed under a Creative Commons Attribution-NonCommercial-NoDerivs 3.0 Unported License. + * + * To view a copy of this license, visit http://creativecommons.org/licenses/by-nc-nd/3.0/. + ******************************************************************************/ +package forestry.lepidopterology; + +import net.minecraft.inventory.InventoryCrafting; +import net.minecraft.item.ItemStack; +import net.minecraft.item.crafting.IRecipe; +import net.minecraft.world.World; + +import forestry.api.lepidopterology.EnumFlutterType; +import forestry.api.lepidopterology.IButterfly; +import forestry.plugins.PluginLepidopterology; + +public class MatingRecipe implements IRecipe { + + ItemStack unknown; + ItemStack cached; + + public MatingRecipe() { + unknown = PluginLepidopterology.butterflyInterface.getMemberStack(PluginLepidopterology.butterflyInterface.getIndividualTemplates().get(0), EnumFlutterType.BUTTERFLY.ordinal()); + } + + @Override + public boolean matches(InventoryCrafting crafting, World world) { + + boolean mated = true; + int butterflies = 0; + int sera = 0; + + for(int i = 0; i < crafting.getSizeInventory(); i++) { + if(PluginLepidopterology.butterflyInterface.isMember(crafting.getStackInSlot(i), EnumFlutterType.BUTTERFLY.ordinal())) { + butterflies++; + mated = PluginLepidopterology.butterflyInterface.isMated(crafting.getStackInSlot(i)); + cached = crafting.getStackInSlot(i); + } else if(PluginLepidopterology.butterflyInterface.isMember(crafting.getStackInSlot(i), EnumFlutterType.SERUM.ordinal())) + sera++; + } + + return !mated && butterflies == 1 && sera == 1; + } + + @Override + public ItemStack getRecipeOutput() { + if(cached != null) + return cached; + else + return unknown; + } + + @Override + public ItemStack getCraftingResult(InventoryCrafting crafting) { + IButterfly butterfly = null; + IButterfly serum = null; + for(int i = 0; i < crafting.getSizeInventory(); i++) { + if(PluginLepidopterology.butterflyInterface.isMember(crafting.getStackInSlot(i), EnumFlutterType.BUTTERFLY.ordinal())) { + butterfly = PluginLepidopterology.butterflyInterface.getMember(crafting.getStackInSlot(i)); + } else if(PluginLepidopterology.butterflyInterface.isMember(crafting.getStackInSlot(i), EnumFlutterType.SERUM.ordinal())) + serum = PluginLepidopterology.butterflyInterface.getMember(crafting.getStackInSlot(i)); + } + + IButterfly mated = butterfly.copy(); + mated.mate(serum); + return PluginLepidopterology.butterflyInterface.getMemberStack(mated, EnumFlutterType.BUTTERFLY.ordinal()); + } + + @Override + public int getRecipeSize() { + return 2; + } + +} diff --git a/forestry_common/lepidopterology/forestry/lepidopterology/entities/AIButterflyBase.java b/forestry_common/lepidopterology/forestry/lepidopterology/entities/AIButterflyBase.java new file mode 100755 index 000000000..c0c805b34 --- /dev/null +++ b/forestry_common/lepidopterology/forestry/lepidopterology/entities/AIButterflyBase.java @@ -0,0 +1,58 @@ +/******************************************************************************* + * Copyright 2011-2014 by SirSengir + * + * This work is licensed under a Creative Commons Attribution-NonCommercial-NoDerivs 3.0 Unported License. + * + * To view a copy of this license, visit http://creativecommons.org/licenses/by-nc-nd/3.0/. + ******************************************************************************/ +package forestry.lepidopterology.entities; + +import net.minecraft.entity.ai.EntityAIBase; +import net.minecraft.entity.ai.RandomPositionGenerator; +import net.minecraft.util.ChunkCoordinates; +import net.minecraft.util.Vec3; + +public abstract class AIButterflyBase extends EntityAIBase { + + protected EntityButterfly entity; + + public AIButterflyBase(EntityButterfly entity) { + this.entity = entity; + } + + protected ChunkCoordinates getRandomDestination() { + if(entity.isInWater()) + return getRandomDestinationUpwards(); + + Vec3 randomTarget = RandomPositionGenerator.findRandomTargetBlockAwayFrom(entity, 16, 7, + entity.worldObj.getWorldVec3Pool().getVecFromPool(entity.posX, entity.posY, entity.posZ)); + + if (randomTarget == null) + return null; + + ChunkCoordinates dest = new ChunkCoordinates((int)randomTarget.xCoord, (int)randomTarget.yCoord, (int)randomTarget.zCoord); + if(validateDestination(dest)) + return dest; + else + return null; + } + + protected ChunkCoordinates getRandomDestinationUpwards() { + ChunkCoordinates dest = new ChunkCoordinates((int)entity.posX, (int)entity.posY + entity.worldObj.rand.nextInt(10) + 2, (int)entity.posZ); + if(validateDestination(dest)) + return dest; + else + return null; + } + + protected boolean validateDestination(ChunkCoordinates dest) { + if(!entity.worldObj.isAirBlock(dest.posX, dest.posY, dest.posZ) || dest.posY < 1) + return false; + if(!entity.getButterfly().isAcceptedEnvironment(entity.worldObj, dest.posX, dest.posY, dest.posZ)) + return false; + + return true; + } + + +} diff --git a/forestry_common/lepidopterology/forestry/lepidopterology/entities/AIButterflyFlee.java b/forestry_common/lepidopterology/forestry/lepidopterology/entities/AIButterflyFlee.java new file mode 100755 index 000000000..8e271537a --- /dev/null +++ b/forestry_common/lepidopterology/forestry/lepidopterology/entities/AIButterflyFlee.java @@ -0,0 +1,89 @@ +/******************************************************************************* + * Copyright 2011-2014 by SirSengir + * + * This work is licensed under a Creative Commons Attribution-NonCommercial-NoDerivs 3.0 Unported License. + * + * To view a copy of this license, visit http://creativecommons.org/licenses/by-nc-nd/3.0/. + ******************************************************************************/ +package forestry.lepidopterology.entities; + +import net.minecraft.entity.player.EntityPlayer; +import net.minecraft.util.ChunkCoordinates; + +import forestry.lepidopterology.entities.EntityButterfly.EnumButterflyState; + + +public class AIButterflyFlee extends AIButterflyBase { + + private EntityPlayer player; + private ChunkCoordinates flightTarget; + + public AIButterflyFlee(EntityButterfly entity) { + super(entity); + setMutexBits(3); + } + + @Override + public boolean shouldExecute() { + + player = entity.worldObj.getClosestPlayerToEntity(entity, entity.getButterfly().getGenome().getPrimary().getFlightDistance()); + + if (player == null || player.isSneaking()) + return false; + + if (!entity.getEntitySenses().canSee(player)) + return false; + + flightTarget = getRandomDestination(); + if(flightTarget == null) + return false; + + if (player.getDistanceSq(flightTarget.posX, flightTarget.posY, flightTarget.posZ) < player.getDistanceSqToEntity(entity)) + return false; + + entity.setDestination(flightTarget); + entity.setState(EnumButterflyState.FLYING); + return true; + } + + @Override + public boolean continueExecuting() { + if(entity.getState() != EnumButterflyState.FLYING) + return false; + if(flightTarget == null) + return false; + // Abort if the flight target changed on us. + if(entity.getDestination() == null || !entity.getDestination().equals(flightTarget)) + return false; + + // Continue if we have not yet reached the destination. + if(entity.getDestination().getDistanceSquared((int)entity.posX, (int)entity.posY, (int)entity.posZ) > 2.0f) + return true; + + entity.setDestination(null); + return false; + } + + @Override + public void startExecuting() { + } + + @Override + public void resetTask() { + flightTarget = null; + } + + @Override + public void updateTask() { + // Reset destination if we did collide. + if(entity.isInWater()) { + flightTarget = getRandomDestinationUpwards(); + entity.setDestination(flightTarget); + } if(entity.isCollided || entity.worldObj.rand.nextInt(300) == 0) { + flightTarget = getRandomDestination(); + entity.setDestination(flightTarget); + } + + entity.changeExhaustion(1); + } +} diff --git a/forestry_common/lepidopterology/forestry/lepidopterology/entities/AIButterflyInteract.java b/forestry_common/lepidopterology/forestry/lepidopterology/entities/AIButterflyInteract.java new file mode 100755 index 000000000..8851dd0e1 --- /dev/null +++ b/forestry_common/lepidopterology/forestry/lepidopterology/entities/AIButterflyInteract.java @@ -0,0 +1,159 @@ +/******************************************************************************* + * Copyright 2011-2014 by SirSengir + * + * This work is licensed under a Creative Commons Attribution-NonCommercial-NoDerivs 3.0 Unported License. + * + * To view a copy of this license, visit http://creativecommons.org/licenses/by-nc-nd/3.0/. + ******************************************************************************/ +package forestry.lepidopterology.entities; + +import java.util.Map; + +import net.minecraft.init.Blocks; +import net.minecraft.item.ItemStack; +import net.minecraft.tileentity.TileEntity; +import net.minecraft.util.ChunkCoordinates; + +import forestry.api.arboriculture.ITreeRoot; +import forestry.api.genetics.AlleleManager; +import forestry.api.genetics.IIndividual; +import forestry.api.genetics.IPollinatable; +import forestry.api.lepidopterology.IButterflyNursery; +import forestry.core.proxy.Proxies; +import forestry.core.utils.StackUtils; +import forestry.core.utils.Utils; +import forestry.lepidopterology.entities.EntityButterfly.EnumButterflyState; + +public class AIButterflyInteract extends AIButterflyBase { + + private ChunkCoordinates rest; + + private boolean canLayEgg = false; + private boolean canPollinate = false; + + private boolean hasLayedEgg = false; + private boolean hasPollinated = false; + + public AIButterflyInteract(EntityButterfly entity) { + super(entity); + setMutexBits(3); + } + + @Override + public boolean shouldExecute() { + if(entity.getState() != EnumButterflyState.RESTING) + return false; + + rest = new ChunkCoordinates((int)entity.posX, ((int)Math.floor(entity.posY)) - 1, (int)entity.posZ); + if(entity.worldObj.isAirBlock(rest.posX, rest.posY, rest.posZ)) + return false; + + canLayEgg = canLayEgg(); + canPollinate = canPollinate(); + + return canLayEgg || canPollinate; + } + + private boolean canLayEgg() { + if(entity.cooldownEgg > 0) + return false; + + if(entity.getButterfly().getMate() == null) + return false; + + TileEntity tile = entity.worldObj.getTileEntity(rest.posX, rest.posY, rest.posZ); + IButterflyNursery nursery = null; + + if(tile instanceof IButterflyNursery) + nursery = (IButterflyNursery)tile; + else { + for (Map.Entry entry : AlleleManager.ersatzSpecimen.entrySet()) { + + if (!StackUtils.equals(entity.worldObj.getBlock(rest.posX, rest.posY, rest.posZ), entry.getKey())) + continue; + + int meta = entity.worldObj.getBlockMetadata(rest.posX, rest.posY, rest.posZ); + if (StackUtils.equals(Blocks.leaves, entry.getKey())) + meta = meta & 3; + if (entry.getKey().getItemDamage() != meta) + continue; + + // We matched, replace the leaf block with ours and set the ersatz genome + ((ITreeRoot)AlleleManager.alleleRegistry.getSpeciesRoot("rootTrees")).setLeaves(entity.worldObj, entry.getValue(), "", rest.posX, rest.posY, rest.posZ); + // Now let's pollinate + nursery = (IButterflyNursery)entity.worldObj.getTileEntity(rest.posX, rest.posY, rest.posZ); + } + } + if(nursery == null) + return false; + + return nursery.canNurse(entity.getButterfly()); + } + + private boolean canPollinate() { + if(entity.cooldownPollination > 0) + return false; + + IPollinatable pollinatable = Utils.getOrCreatePollinatable("", entity.worldObj, rest.posX, rest.posY, rest.posZ); + if(pollinatable == null) + return false; + + if(!entity.getButterfly().getGenome().getFlowerProvider().isAcceptedPollinatable(entity.worldObj, pollinatable)) + return false; + + if(entity.getPollen() != null && !pollinatable.canMateWith(entity.getPollen())) + return false; + + return true; + } + + @Override + public boolean continueExecuting() { + return (canLayEgg && !hasLayedEgg) || (canPollinate && !hasPollinated); + } + + @Override + public void startExecuting() { + } + + @Override + public void resetTask() { + hasLayedEgg = false; + hasPollinated = false; + + canLayEgg = false; + canPollinate = false; + + rest = null; + } + + @Override + public void updateTask() { + if(canLayEgg && !hasLayedEgg) { + IButterflyNursery tile = (IButterflyNursery)entity.worldObj.getTileEntity(rest.posX, rest.posY, rest.posZ); + if(tile.canNurse(entity.getButterfly())) { + tile.setCaterpillar(entity.getButterfly().spawnCaterpillar(tile)); + Proxies.log.finest("A butterfly '%s' laid an egg at %s/%s/%s.", entity.getButterfly().getIdent(), rest.posX, rest.posY, rest.posZ); + if(entity.getRNG().nextFloat() < 1.0f / entity.getButterfly().getGenome().getFertility()) + entity.setHealth(0); + } + hasLayedEgg = true; + entity.cooldownEgg = EntityButterfly.COOLDOWNS; + } + + if(canPollinate && !hasPollinated) { + IPollinatable pollinatable = (IPollinatable)entity.worldObj.getTileEntity(rest.posX, rest.posY, rest.posZ); + if(entity.getPollen() == null) { + entity.setPollen(pollinatable.getPollen()); + //Proxies.log.finest("A butterfly '%s' grabbed a pollen '%s' at %s/%s/%s.", entity.getButterfly().getIdent(), entity.getPollen().getIdent(), rest.posX, rest.posY, rest.posZ); + } else if(pollinatable.canMateWith(entity.getPollen())) { + pollinatable.mateWith(entity.getPollen()); + //Proxies.log.finest("A butterfly '%s' unloaded pollen '%s' at %s/%s/%s.", entity.getButterfly().getIdent(), entity.getPollen().getIdent(), rest.posX, rest.posY, rest.posZ); + entity.setPollen(null); + } + hasPollinated = true; + entity.cooldownPollination = EntityButterfly.COOLDOWNS; + } + } + +} diff --git a/forestry_common/lepidopterology/forestry/lepidopterology/entities/AIButterflyRest.java b/forestry_common/lepidopterology/forestry/lepidopterology/entities/AIButterflyRest.java new file mode 100755 index 000000000..fcbd30a98 --- /dev/null +++ b/forestry_common/lepidopterology/forestry/lepidopterology/entities/AIButterflyRest.java @@ -0,0 +1,67 @@ +/******************************************************************************* + * Copyright 2011-2014 by SirSengir + * + * This work is licensed under a Creative Commons Attribution-NonCommercial-NoDerivs 3.0 Unported License. + * + * To view a copy of this license, visit http://creativecommons.org/licenses/by-nc-nd/3.0/. + ******************************************************************************/ +package forestry.lepidopterology.entities; + +import net.minecraft.util.ChunkCoordinates; + +import forestry.core.utils.Utils; +import forestry.lepidopterology.entities.EntityButterfly.EnumButterflyState; + +public class AIButterflyRest extends AIButterflyBase { + + public AIButterflyRest(EntityButterfly entity) { + super(entity); + setMutexBits(3); + } + + @Override + public boolean shouldExecute() { + + if(entity.getExhaustion() < EntityButterfly.EXHAUSTION_REST + && entity.canFly()) + return false; + + if(!entity.worldObj.isAirBlock((int)entity.posX, ((int)Math.floor(entity.posY)), (int)entity.posZ)) + return false; + + ChunkCoordinates rest = new ChunkCoordinates((int)entity.posX, ((int)Math.floor(entity.posY)) - 1, (int)entity.posZ); + if(entity.worldObj.isAirBlock(rest.posX, rest.posY, rest.posZ)) + return false; + if(Utils.isLiquidBlock(entity.worldObj, rest.posX, rest.posY, rest.posZ)) + return false; + if(!entity.getButterfly().isAcceptedEnvironment(entity.worldObj, rest.posX, rest.posY, rest.posZ)) + return false; + + entity.setDestination(null); + entity.setState(EnumButterflyState.RESTING); + return true; + } + + @Override + public boolean continueExecuting() { + if(entity.getExhaustion() <= 0 && entity.canFly()) + return false; + if(entity.isInWater()) + return false; + + return true; + } + + @Override + public void startExecuting() { + } + + @Override + public void resetTask() { + } + + @Override + public void updateTask() { + entity.changeExhaustion(-1); + } +} diff --git a/forestry_common/lepidopterology/forestry/lepidopterology/entities/AIButterflyWander.java b/forestry_common/lepidopterology/forestry/lepidopterology/entities/AIButterflyWander.java new file mode 100755 index 000000000..4a97cfae4 --- /dev/null +++ b/forestry_common/lepidopterology/forestry/lepidopterology/entities/AIButterflyWander.java @@ -0,0 +1,82 @@ +/******************************************************************************* + * Copyright 2011-2014 by SirSengir + * + * This work is licensed under a Creative Commons Attribution-NonCommercial-NoDerivs 3.0 Unported License. + * + * To view a copy of this license, visit http://creativecommons.org/licenses/by-nc-nd/3.0/. + ******************************************************************************/ +package forestry.lepidopterology.entities; + +import net.minecraft.util.ChunkCoordinates; + +import forestry.lepidopterology.entities.EntityButterfly.EnumButterflyState; + +public class AIButterflyWander extends AIButterflyBase { + + private ChunkCoordinates flightTarget; + + public AIButterflyWander(EntityButterfly entity) { + super(entity); + setMutexBits(1); + } + + @Override + public boolean shouldExecute() { + + if(entity.getDestination() != null) + return false; + + flightTarget = getRandomDestination(); + if(flightTarget == null) { + if(entity.getState().doesMovement) + entity.setState(EnumButterflyState.HOVER); + return false; + } + + entity.setDestination(flightTarget); + entity.setState(EnumButterflyState.FLYING); + return true; + } + + @Override + public boolean continueExecuting() { + if(entity.getState() != EnumButterflyState.FLYING) + return false; + if(flightTarget == null) + return false; + // Abort if the flight target changed on us. + if(entity.getDestination() == null || !entity.getDestination().equals(flightTarget)) + return false; + + // Continue if we have not yet reached the destination. + if(entity.getDestination().getDistanceSquared((int)entity.posX, (int)entity.posY, (int)entity.posZ) > 2.0f) + return true; + + entity.setDestination(null); + return false; + } + + @Override + public void startExecuting() { + } + + @Override + public void resetTask() { + flightTarget = null; + } + + @Override + public void updateTask() { + // Reset destination if we did collide. + if(entity.isInWater()) { + flightTarget = getRandomDestinationUpwards(); + entity.setDestination(flightTarget); + } if(entity.isCollided || entity.worldObj.rand.nextInt(300) == 0) { + flightTarget = getRandomDestination(); + entity.setDestination(flightTarget); + } + + entity.changeExhaustion(1); + + } +} diff --git a/forestry_common/lepidopterology/forestry/lepidopterology/entities/EntityButterfly.java b/forestry_common/lepidopterology/forestry/lepidopterology/entities/EntityButterfly.java new file mode 100755 index 000000000..7f99f2b47 --- /dev/null +++ b/forestry_common/lepidopterology/forestry/lepidopterology/entities/EntityButterfly.java @@ -0,0 +1,397 @@ +/******************************************************************************* + * Copyright 2011-2014 by SirSengir + * + * This work is licensed under a Creative Commons Attribution-NonCommercial-NoDerivs 3.0 Unported License. + * + * To view a copy of this license, visit http://creativecommons.org/licenses/by-nc-nd/3.0/. + ******************************************************************************/ +package forestry.lepidopterology.entities; + +import net.minecraft.entity.Entity; +import net.minecraft.entity.EntityCreature; +import net.minecraft.entity.IEntityLivingData; +import net.minecraft.entity.player.EntityPlayer; +import net.minecraft.item.ItemStack; +import net.minecraft.nbt.NBTTagCompound; +import net.minecraft.util.ChunkCoordinates; +import net.minecraft.util.DamageSource; +import net.minecraft.util.MathHelper; +import net.minecraft.util.ResourceLocation; +import net.minecraft.world.World; + +import cpw.mods.fml.relauncher.Side; +import cpw.mods.fml.relauncher.SideOnly; + +import forestry.api.arboriculture.EnumGermlingType; +import forestry.api.core.IToolScoop; +import forestry.api.genetics.AlleleManager; +import forestry.api.genetics.IAllele; +import forestry.api.genetics.IIndividual; +import forestry.api.lepidopterology.EnumFlutterType; +import forestry.api.lepidopterology.IAlleleButterflySpecies; +import forestry.api.lepidopterology.IButterfly; +import forestry.api.lepidopterology.IEntityButterfly; +import forestry.core.proxy.Proxies; +import forestry.core.utils.StackUtils; +import forestry.lepidopterology.genetics.Butterfly; +import forestry.lepidopterology.render.ButterflyItemRenderer; +import forestry.plugins.PluginLepidopterology; + +public class EntityButterfly extends EntityCreature implements IEntityButterfly { + + public enum EnumButterflyState { + FLYING(true), GLIDING(true), RESTING(false), HOVER(false); + + public static final EnumButterflyState[] VALUES = values(); + + public final boolean doesMovement; + + private EnumButterflyState(boolean doesMovement) { + this.doesMovement = doesMovement; + } + + public float getWingFlap(EntityButterfly entity, float partialTicktime) { + if(this == RESTING || this == HOVER) { + long systemTime = System.currentTimeMillis(); + long flapping = systemTime + entity.contained.getIdent().hashCode(); + float flap = (float) (flapping % 1000) / 1000; // 0 to 1 + + return ButterflyItemRenderer.getIrregularWingYaw(flapping, flap); + } else + return entity.ticksExisted + partialTicktime; + } + } + + /* CONSTANTS */ + public static final int COOLDOWNS = 1000; + + private static final int DATAWATCHER_ID_SPECIES = 16; + private static final int DATAWATCHER_ID_SCALE = 17; + private static final int DATAWATCHER_ID_STATE = 18; + + //private static final String DEFAULT_TEXTURE = Defaults.TEXTURE_PATH_ENTITIES + "/butterflies/mothBrimstone.png"; + public static final float DEFAULT_BUTTERFLY_SCALE = 0.75f; + private static final EnumButterflyState DEFAULT_STATE = EnumButterflyState.FLYING; + + public static final int EXHAUSTION_REST = 1000; + public static final int EXHAUSTION_CONSUMPTION = 100 * EXHAUSTION_REST; + + private ChunkCoordinates flightTarget; + private int exhaustion; + + private IAlleleButterflySpecies species; + private IButterfly contained; + + private IIndividual pollen; + + private EnumButterflyState state = DEFAULT_STATE; + private float scale = DEFAULT_BUTTERFLY_SCALE; + private String mothTexture; + + private long lastUpdate; + + public int cooldownPollination = 0; + public int cooldownEgg = 0; + + /* CONSTRUCTOR */ + public EntityButterfly(World world) { + super(world); + setDefaults(PluginLepidopterology.butterflyInterface.templateAsIndividual(PluginLepidopterology.butterflyInterface.getRandomTemplate(rand))); + } + + public EntityButterfly(World world, IButterfly butterfly) { + super(world); + setDefaults(butterfly); + } + + private void setDefaults(IButterfly butterfly) { + contained = butterfly; + tasks.addTask(10, new AIButterflyWander(this)); + tasks.addTask(9, new AIButterflyRest(this)); + tasks.addTask(8, new AIButterflyInteract(this)); + tasks.addTask(8, new AIButterflyFlee(this)); + } + + @Override + public EntityCreature getEntity() { + return this; + } + + /* SAVING & LOADING */ + @Override + public void writeEntityToNBT(NBTTagCompound nbttagcompound) { + super.writeEntityToNBT(nbttagcompound); + + NBTTagCompound bio = new NBTTagCompound(); + contained.writeToNBT(bio); + nbttagcompound.setTag("BTFLY", bio); + + if(pollen != null) { + NBTTagCompound pln = new NBTTagCompound(); + pollen.writeToNBT(pln); + nbttagcompound.setTag("PLN", pln); + } + + nbttagcompound.setByte("STATE", (byte)state.ordinal()); + nbttagcompound.setInteger("EXH", exhaustion); + } + + @Override + public void readEntityFromNBT(NBTTagCompound nbttagcompound) { + super.readEntityFromNBT(nbttagcompound); + + if(nbttagcompound.hasKey("BTFLY")) { + contained = new Butterfly((NBTTagCompound)nbttagcompound.getTag("BTFLY")); + } + setIndividual(contained); + + if(nbttagcompound.hasKey("PLN")) { + pollen = AlleleManager.alleleRegistry.getSpeciesRoot("rootTrees").getMember((NBTTagCompound)nbttagcompound.getTag("PLN")); + } + + state = EnumButterflyState.VALUES[nbttagcompound.getByte("STATE")]; + exhaustion = nbttagcompound.getInteger("EXH"); + } + + public float getWingFlap(float partialTicktime) { + return state.getWingFlap(this, partialTicktime); + } + + public float getScale() { + return scale; + } + + // Client side helper to set size for rendering if necessary. + public void setScale(float size) { + scale = size; + } + + public float getSpeed() { + return contained.getGenome().getSpeed(); + } + + /* DESTINATION */ + public ChunkCoordinates getDestination() { + return flightTarget; + } + + public void setDestination(ChunkCoordinates destination) { + flightTarget = destination; + } + + /* POLLEN */ + @Override + public IIndividual getPollen() { + return pollen; + } + + @Override + public void setPollen(IIndividual pollen) { + this.pollen = pollen; + } + + /* STATE - Used for rendering */ + public EnumButterflyState getState() { + return state; + } + + public void setState(EnumButterflyState state) { + if(state != this.state) { + this.state = state; + dataWatcher.updateObject(DATAWATCHER_ID_STATE, (byte)state.ordinal()); + } + } + + public boolean isRenderable() { + return species != null; + } + + /* EXHAUSTION */ + @Override + public void changeExhaustion(int change) { + exhaustion = exhaustion + change > 0 ? exhaustion + change : 0; + } + + @Override + public int getExhaustion() { + return exhaustion; + } + + /* FLYING ABILITY */ + public boolean canFly() { + return contained.canTakeFlight(worldObj, posX, posY, posZ); + } + + /* SETTING GENETIC INDIVIDUAL */ + private void resetAppearance() { + mothTexture = species.getEntityTexture(); + setSize(getScale(), 0.2f); + } + + public EntityButterfly setIndividual(IButterfly butterfly) { + if(butterfly != null) + contained = butterfly; + else + contained = PluginLepidopterology.butterflyInterface.templateAsIndividual(PluginLepidopterology.butterflyInterface.getDefaultTemplate()); + + isImmuneToFire = contained.getGenome().getFireResist(); + setSpecies(contained.getGenome().getPrimary()); + dataWatcher.updateObject(DATAWATCHER_ID_SPECIES, species.getUID()); + dataWatcher.updateObject(DATAWATCHER_ID_SCALE, (int)(contained.getSize() * 100)); + return this; + } + + @Override + public IButterfly getButterfly() { + return contained; + } + + public EntityButterfly setSpecies(IAlleleButterflySpecies butterfly) { + species = butterfly; + resetAppearance(); + lastUpdate = worldObj.getTotalWorldTime(); + return this; + } + + @Override + public IEntityLivingData onSpawnWithEgg(IEntityLivingData data) { + if(Proxies.common.isSimulating(worldObj)) + setIndividual(contained); + return data; + } + @Override public boolean getCanSpawnHere() { return true; } + + @Override + protected void entityInit() { + super.entityInit(); + + if(state == null) + state = DEFAULT_STATE; + + dataWatcher.addObject(DATAWATCHER_ID_SPECIES, ""); + dataWatcher.addObject(DATAWATCHER_ID_SCALE, 75); + dataWatcher.addObject(DATAWATCHER_ID_STATE, (byte)state.ordinal()); + } + + @Override + public int getMaxInPortalTime() { + return 1000; + } + + @SideOnly(Side.CLIENT) + private ResourceLocation textureResource; + private long lastTextureUpdate; + @SideOnly(Side.CLIENT) + public ResourceLocation getTexture() { + if(textureResource == null || lastTextureUpdate != lastUpdate) + textureResource = new ResourceLocation(mothTexture); + + return textureResource; + } + + @Override public boolean canBePushed() { return false; } + @Override protected void collideWithEntity(Entity other) {} + @Override protected boolean isAIEnabled() { return true; } + @Override protected boolean canDespawn() { return false; } + + /* INTERACTION */ + @Override + public boolean interact(EntityPlayer player) { + if(isDead) + return false; + if(player.getHeldItem() == null) + return false; + if(!(player.getHeldItem().getItem() instanceof IToolScoop)) + return false; + + if(Proxies.common.isSimulating(worldObj)) { + contained.getGenome().getPrimary().getRoot().getBreedingTracker(worldObj, player.getGameProfile().getId()).registerCatch(contained); + StackUtils.dropItemStackAsEntity(PluginLepidopterology.butterflyInterface.getMemberStack(contained.copy(), EnumFlutterType.BUTTERFLY.ordinal()), worldObj, posX, posY, posZ); + setDead(); + } else + player.swingItem(); + return true; + } + + /* LOOT */ + @Override + protected void dropFewItems(boolean playerKill, int lootLevel) { + for(ItemStack stack : contained.getLootDrop(this, playerKill, lootLevel)) + StackUtils.dropItemStackAsEntity(stack, worldObj, posX, posY, posZ); + + // Drop pollen if any + if(getPollen() != null) { + StackUtils.dropItemStackAsEntity(AlleleManager.alleleRegistry.getSpeciesRoot(getPollen().getClass()).getMemberStack(getPollen(), EnumGermlingType.POLLEN.ordinal()), worldObj, posX, posY, posZ); + } + } + + /* UPDATING */ + @Override + public void onUpdate() { + super.onUpdate(); + + // Update stuff client side + if(!Proxies.common.isSimulating(worldObj)) { + if (species == null || dataWatcher.hasChanges()) { + scale = (float)dataWatcher.getWatchableObjectInt(DATAWATCHER_ID_SCALE) / 100; + String uid = dataWatcher.getWatchableObjectString(DATAWATCHER_ID_SPECIES); + if(species == null || !species.getUID().equals(uid)) { + IAllele allele = AlleleManager.alleleRegistry.getAllele(uid); + if(allele instanceof IAlleleButterflySpecies) { + setSpecies((IAlleleButterflySpecies)allele); + } + } + } + state = EnumButterflyState.VALUES[dataWatcher.getWatchableObjectByte(DATAWATCHER_ID_STATE)]; + } + + motionY *= 0.6000000238418579d; + + // Make sure we die if the butterfly hasn't rested in a long, long time. + if(exhaustion > EXHAUSTION_CONSUMPTION && getRNG().nextInt(20) == 0) + attackEntityFrom(DamageSource.generic, 1); + + // Reduce cooldowns + if(cooldownEgg > 0) cooldownEgg--; + if(cooldownPollination > 0) cooldownPollination--; + } + + @Override + protected void updateAITasks() { + super.updateAITasks(); + + if(state.doesMovement && flightTarget != null) { + double diffX = flightTarget.posX + 0.5d - posX; + double diffY = flightTarget.posY + 0.1d - posY; + double diffZ = flightTarget.posZ + 0.5d - posZ; + + motionX += (Math.signum(diffX) * 0.5d - motionX) * 0.10000000149011612d; + motionY += (Math.signum(diffY) * 0.699999988079071d - motionY) * 0.10000000149011612d; + motionZ += (Math.signum(diffZ) * 0.5d - motionZ) * 0.10000000149011612d; + + //float f = (float)(Math.atan2(motionZ, motionX) * 180.0d / Math.PI) - 90f; + //rotationYaw += MathHelper.wrapAngleTo180_float(f - rotationYaw); + float horizontal = (float)((Math.atan2(motionZ, motionX) * 180d) / Math.PI) - 90f; + rotationYaw += MathHelper.wrapAngleTo180_float(horizontal - rotationYaw); + + setMoveForward(contained.getGenome().getSpeed()); + } + + } + + @Override protected boolean canTriggerWalking() { return false; } + @Override protected void fall(float par1) {} + @Override protected void updateFallState(double par1, boolean par3) {} + @Override public boolean doesEntityNotTriggerPressurePlate() { return true; } + + @Override + public float getSwingProgress(float partialTicktime) { + float flap = swingProgress - prevSwingProgress; + if (flap < 0.0F) + ++flap; + + return prevSwingProgress + flap * partialTicktime; + + } + +} diff --git a/forestry_common/lepidopterology/forestry/lepidopterology/gadgets/TileLepidopteristChest.java b/forestry_common/lepidopterology/forestry/lepidopterology/gadgets/TileLepidopteristChest.java new file mode 100755 index 000000000..227cce120 --- /dev/null +++ b/forestry_common/lepidopterology/forestry/lepidopterology/gadgets/TileLepidopteristChest.java @@ -0,0 +1,20 @@ +/******************************************************************************* + * Copyright 2011-2014 by SirSengir + * + * This work is licensed under a Creative Commons Attribution-NonCommercial-NoDerivs 3.0 Unported License. + * + * To view a copy of this license, visit http://creativecommons.org/licenses/by-nc-nd/3.0/. + ******************************************************************************/ +package forestry.lepidopterology.gadgets; + +import forestry.api.genetics.AlleleManager; +import forestry.core.gadgets.TileNaturalistChest; +import forestry.core.network.GuiId; + +public class TileLepidopteristChest extends TileNaturalistChest { + + public TileLepidopteristChest() { + super(AlleleManager.alleleRegistry.getSpeciesRoot("rootButterflies"), GuiId.LepidopteristChestGUI.ordinal()); + } + +} diff --git a/forestry_common/lepidopterology/forestry/lepidopterology/genetics/AlleleButterflySpecies.java b/forestry_common/lepidopterology/forestry/lepidopterology/genetics/AlleleButterflySpecies.java new file mode 100755 index 000000000..1a263a734 --- /dev/null +++ b/forestry_common/lepidopterology/forestry/lepidopterology/genetics/AlleleButterflySpecies.java @@ -0,0 +1,172 @@ +/******************************************************************************* + * Copyright 2011-2014 by SirSengir + * + * This work is licensed under a Creative Commons Attribution-NonCommercial-NoDerivs 3.0 Unported License. + * + * To view a copy of this license, visit http://creativecommons.org/licenses/by-nc-nd/3.0/. + ******************************************************************************/ +package forestry.lepidopterology.genetics; + +import java.util.EnumSet; +import java.util.HashMap; +import java.util.Map; + +import net.minecraft.init.Items; +import net.minecraft.item.ItemStack; +import net.minecraft.world.World; + +import cpw.mods.fml.relauncher.Side; +import cpw.mods.fml.relauncher.SideOnly; + +import net.minecraftforge.common.BiomeDictionary; + +import forestry.api.core.IIconProvider; +import forestry.api.genetics.AlleleManager; +import forestry.api.genetics.IClassification; +import forestry.api.genetics.IIndividual; +import forestry.api.lepidopterology.EnumFlutterType; +import forestry.api.lepidopterology.IAlleleButterflySpecies; +import forestry.api.lepidopterology.IButterflyRoot; +import forestry.core.config.Defaults; +import forestry.core.genetics.AlleleSpecies; + +public class AlleleButterflySpecies extends AlleleSpecies implements IAlleleButterflySpecies { + + private final IButterflyRoot root; + + private final String texture; + private final int serumColour; + private float rarity = 0.1f; + private float flightDistance = 5.0f; + private boolean isActualNocturnal = false; + + private final EnumSet spawnBiomes = EnumSet.noneOf(BiomeDictionary.Type.class); + + private final Map butterflyLoot = new HashMap(); + private final Map caterpillarLoot = new HashMap(); + + public AlleleButterflySpecies(String uid, boolean isDominant, String name, IClassification branch, String binomial, int serumColour) { + super(uid, isDominant, name, branch, binomial); + this.root = (IButterflyRoot)AlleleManager.alleleRegistry.getSpeciesRoot("rootButterflies"); + this.serumColour = serumColour; + texture = "forestry:" + Defaults.TEXTURE_PATH_ENTITIES + "/butterflies/" + uid + ".png"; + } + + @Override + public IButterflyRoot getRoot() { + return root; + } + + public AlleleButterflySpecies setRarity(float rarity) { + this.rarity = rarity; + return this; + } + + public AlleleButterflySpecies setFlightDistance(float flightDistance) { + this.flightDistance = flightDistance; + return this; + } + + public AlleleButterflySpecies setNocturnal(boolean isActualNocturnal) { + this.isActualNocturnal = isActualNocturnal; + return this; + } + + public AlleleButterflySpecies addSpawnBiomes(EnumSet biomeTags) { + spawnBiomes.addAll(biomeTags); + return this; + } + + public AlleleButterflySpecies addSpawnBiome(BiomeDictionary.Type biomeTag) { + spawnBiomes.add(biomeTag); + return this; + } + + @Override + @SideOnly(Side.CLIENT) + public IIconProvider getIconProvider() { + return null; + } + + @Override + public String getEntityTexture() { + return texture; + } + + @Override + public EnumSet getSpawnBiomes() { + return spawnBiomes; + } + + @Override + public boolean strictSpawnMatch() { + return false; + } + + /* RESEARCH */ + @Override + public int getComplexity() { + return (int)((1.35f/rarity)*1.5); + } + + @Override + public float getResearchSuitability(ItemStack itemstack) { + if(itemstack == null) + return 0f; + + if(itemstack.getItem() == Items.glass_bottle) + return 0.9f; + + for(ItemStack stack : butterflyLoot.keySet()) + if(stack.isItemEqual(itemstack)) + return 1.0f; + for(ItemStack stack : caterpillarLoot.keySet()) + if(stack.isItemEqual(itemstack)) + return 1.0f; + + return super.getResearchSuitability(itemstack); + } + + @Override + public ItemStack[] getResearchBounty(World world, String researcher, IIndividual individual, int bountyLevel) { + return new ItemStack[] { getRoot().getMemberStack(individual.copy(), EnumFlutterType.SERUM.ordinal()) }; + } + + /* OTHER */ + @Override + public boolean isSecret() { + return rarity < 0.8f; + } + + @Override + public float getRarity() { + return rarity; + } + + @Override + public float getFlightDistance() { + return flightDistance; + } + + @Override + public boolean isNocturnal() { + return isActualNocturnal; + } + + @Override + public Map getButterflyLoot() { + return butterflyLoot; + } + + @Override + public Map getCaterpillarLoot() { + return caterpillarLoot; + } + + @Override + public int getIconColour(int renderPass) { + if(renderPass > 0) + return 0xffffff; + return serumColour; + } +} diff --git a/forestry_common/lepidopterology/forestry/lepidopterology/genetics/AlleleEffectNone.java b/forestry_common/lepidopterology/forestry/lepidopterology/genetics/AlleleEffectNone.java new file mode 100755 index 000000000..731d6231c --- /dev/null +++ b/forestry_common/lepidopterology/forestry/lepidopterology/genetics/AlleleEffectNone.java @@ -0,0 +1,41 @@ +/******************************************************************************* + * Copyright 2011-2014 by SirSengir + * + * This work is licensed under a Creative Commons Attribution-NonCommercial-NoDerivs 3.0 Unported License. + * + * To view a copy of this license, visit http://creativecommons.org/licenses/by-nc-nd/3.0/. + ******************************************************************************/ +package forestry.lepidopterology.genetics; + +import forestry.api.genetics.IEffectData; +import forestry.api.lepidopterology.IAlleleButterflyEffect; +import forestry.api.lepidopterology.IEntityButterfly; +import forestry.core.genetics.Allele; + +public class AlleleEffectNone extends Allele implements IAlleleButterflyEffect { + + public AlleleEffectNone(String uid, boolean isDominant) { + super(uid, isDominant, false); + } + + @Override + public boolean isCombinable() { + return true; + } + + @Override + public IEffectData validateStorage(IEffectData storedData) { + return null; + } + + @Override + public String getName() { + return "None"; + } + + @Override + public IEffectData doEffect(IEntityButterfly butterfly, IEffectData storedData) { + return storedData; + } + +} diff --git a/forestry_common/lepidopterology/forestry/lepidopterology/genetics/Butterfly.java b/forestry_common/lepidopterology/forestry/lepidopterology/genetics/Butterfly.java new file mode 100755 index 000000000..0d9ba7cf5 --- /dev/null +++ b/forestry_common/lepidopterology/forestry/lepidopterology/genetics/Butterfly.java @@ -0,0 +1,291 @@ +/******************************************************************************* + * Copyright 2011-2014 by SirSengir + * + * This work is licensed under a Creative Commons Attribution-NonCommercial-NoDerivs 3.0 Unported License. + * + * To view a copy of this license, visit http://creativecommons.org/licenses/by-nc-nd/3.0/. + ******************************************************************************/ +package forestry.lepidopterology.genetics; + +import java.util.ArrayList; +import java.util.List; +import java.util.Locale; +import java.util.Map; + +import net.minecraft.entity.EntityCreature; +import net.minecraft.item.ItemStack; +import net.minecraft.nbt.NBTTagCompound; +import net.minecraft.world.World; +import net.minecraft.world.biome.BiomeGenBase; + +import net.minecraftforge.common.BiomeDictionary; + +import forestry.api.core.EnumHumidity; +import forestry.api.core.EnumTemperature; +import forestry.api.genetics.IAllele; +import forestry.api.genetics.IChromosome; +import forestry.api.genetics.IGenome; +import forestry.api.genetics.IIndividual; +import forestry.api.lepidopterology.EnumButterflyChromosome; +import forestry.api.lepidopterology.IAlleleButterflySpecies; +import forestry.api.lepidopterology.IButterfly; +import forestry.api.lepidopterology.IButterflyGenome; +import forestry.api.lepidopterology.IButterflyMutation; +import forestry.api.lepidopterology.IButterflyNursery; +import forestry.api.lepidopterology.IEntityButterfly; +import forestry.core.genetics.Chromosome; +import forestry.core.genetics.ClimateHelper; +import forestry.core.genetics.GenericRatings; +import forestry.core.genetics.IndividualLiving; +import forestry.core.utils.StackUtils; +import forestry.core.utils.StringUtil; +import forestry.core.utils.Utils; +import forestry.plugins.PluginLepidopterology; + +public class Butterfly extends IndividualLiving implements IButterfly { + + public IButterflyGenome genome; + public IButterflyGenome mate; + + /* CONSTRUCTOR */ + public Butterfly(NBTTagCompound nbttagcompound) { + readFromNBT(nbttagcompound); + } + + public Butterfly(IButterflyGenome genome) { + this(genome, true, 0); + } + + public Butterfly(IButterflyGenome genome, boolean isNatural, int generation) { + super(genome.getLifespan(), isNatural, generation); + this.genome = genome; + } + + @Override + public void addTooltip(List list) { + IAlleleButterflySpecies primary = genome.getPrimary(); + IAlleleButterflySpecies secondary = genome.getSecondary(); + if (!isPureBred(EnumButterflyChromosome.SPECIES.ordinal())) + list.add("\u00A79" + StringUtil.localize("gui.hybrid") + ":" + primary.getName() + "-" + secondary.getName()); + + if(getMate() != null) + list.add("\u00A7c" + StringUtil.localize("gui.fecundated").toUpperCase(Locale.ENGLISH)); + list.add("\u00A7e" + genome.getActiveAllele(EnumButterflyChromosome.SIZE.ordinal()).getName()); + list.add("\u00A7f" + genome.getActiveAllele(EnumButterflyChromosome.SPEED.ordinal()).getName() + " " + StringUtil.localize("gui.flyer")); + list.add(genome.getActiveAllele(EnumButterflyChromosome.LIFESPAN.ordinal()).getName() + " " + StringUtil.localize("gui.life")); + list.add("\u00A7aT: " + ClimateHelper.toDisplay(genome.getPrimary().getTemperature()) + " / " + + StringUtil.capitalize(genome.getToleranceTemp().name())); + list.add("\u00A7aH: " + ClimateHelper.toDisplay(genome.getPrimary().getHumidity()) + " / " + + StringUtil.capitalize(genome.getToleranceHumid().name())); + list.add("\u00A7c" + GenericRatings.rateActivityTime(genome.getNocturnal(), genome.getPrimary().isNocturnal())); + } + + /* SAVING & LOADING */ + @Override + public void readFromNBT(NBTTagCompound nbttagcompound) { + + if (nbttagcompound == null) { + this.genome = PluginLepidopterology.butterflyInterface.templateAsGenome(PluginLepidopterology.butterflyInterface.getDefaultTemplate()); + return; + } + + super.readFromNBT(nbttagcompound); + + if (nbttagcompound.hasKey("Genome")) + genome = new ButterflyGenome(nbttagcompound.getCompoundTag("Genome")); + else + genome = PluginLepidopterology.butterflyInterface.templateAsGenome(PluginLepidopterology.butterflyInterface.getDefaultTemplate()); + if (nbttagcompound.hasKey("Mate")) + mate = new ButterflyGenome(nbttagcompound.getCompoundTag("Mate")); + + } + + + @Override + public IButterfly copy() { + NBTTagCompound nbttagcompound = new NBTTagCompound(); + this.writeToNBT(nbttagcompound); + return new Butterfly(nbttagcompound); + } + + @Override + public IButterflyGenome getGenome() { + return genome; + } + + @Override + public IButterflyGenome getMate() { + return mate; + } + + @Override + public boolean canSpawn(World world, double x, double y, double z) { + if(!canFly(world)) + return false; + + BiomeGenBase biome = Utils.getBiomeAt(world, (int)x, (int)z); + if(getGenome().getPrimary().getSpawnBiomes().size() > 0) { + boolean noneMatched = true; + + if(getGenome().getPrimary().strictSpawnMatch()) { + BiomeDictionary.Type[] types = BiomeDictionary.getTypesForBiome(biome); + if(types.length == 1 && getGenome().getPrimary().getSpawnBiomes().contains(types[0])) + noneMatched = false; + } else { + for(BiomeDictionary.Type type : getGenome().getPrimary().getSpawnBiomes()) { + if(BiomeDictionary.isBiomeOfType(biome, type)) { + noneMatched = false; + break; + } + } + } + + if(noneMatched) + return false; + } + + return isAcceptedEnvironment(biome); + } + + @Override + public boolean canTakeFlight(World world, double x, double y, double z) { + if(!canFly(world)) + return false; + return isAcceptedEnvironment(Utils.getBiomeAt(world, (int)x, (int)z)); + } + + private boolean canFly(World world) { + if(world.isRaining() && !getGenome().getTolerantFlyer()) + return false; + if(!isActiveThisTime(world.isDaytime())) + return false; + return true; + } + + @Override + public boolean isAcceptedEnvironment(World world, double x, double y, double z) { + return isAcceptedEnvironment(Utils.getBiomeAt(world, (int)x, (int)z)); + } + + private boolean isAcceptedEnvironment(BiomeGenBase biome) { + return ClimateHelper.isWithinLimits(EnumTemperature.getFromValue(biome.temperature), + EnumHumidity.getFromValue(biome.rainfall), + getGenome().getPrimary().getTemperature(), getGenome().getToleranceTemp(), + getGenome().getPrimary().getHumidity(), getGenome().getToleranceHumid()); + } + + @Override + public IButterfly spawnCaterpillar(IButterflyNursery nursery) { + // We need a mated queen to produce offspring. + if (mate == null) + return null; + + World world = nursery.getWorld(); + + IChromosome[] chromosomes = new IChromosome[genome.getChromosomes().length]; + IChromosome[] parent1 = genome.getChromosomes(); + IChromosome[] parent2 = mate.getChromosomes(); + + // Check for mutation. Replace one of the parents with the mutation + // template if mutation occured. + IChromosome[] mutated1 = mutateSpecies(nursery, genome, mate); + if (mutated1 != null) + parent1 = mutated1; + IChromosome[] mutated2 = mutateSpecies(nursery, mate, genome); + if (mutated2 != null) + parent2 = mutated2; + + for (int i = 0; i < parent1.length; i++) + if (parent1[i] != null && parent2[i] != null) + chromosomes[i] = Chromosome.inheritChromosome(world.rand, parent1[i], parent2[i]); + + return new Butterfly(new ButterflyGenome(chromosomes), true, generation); + } + + private IChromosome[] mutateSpecies(IButterflyNursery nursery, IGenome genomeOne, IGenome genomeTwo) { + + World world = nursery.getWorld(); + + IChromosome[] parent1 = genomeOne.getChromosomes(); + IChromosome[] parent2 = genomeTwo.getChromosomes(); + + IGenome genome0; + IGenome genome1; + IAllele allele0; + IAllele allele1; + + if (world.rand.nextBoolean()) { + allele0 = parent1[EnumButterflyChromosome.SPECIES.ordinal()].getPrimaryAllele(); + allele1 = parent2[EnumButterflyChromosome.SPECIES.ordinal()].getSecondaryAllele(); + + genome0 = genomeOne; + genome1 = genomeTwo; + } else { + allele0 = parent2[EnumButterflyChromosome.SPECIES.ordinal()].getPrimaryAllele(); + allele1 = parent1[EnumButterflyChromosome.SPECIES.ordinal()].getSecondaryAllele(); + + genome0 = genomeTwo; + genome1 = genomeOne; + } + + for (IButterflyMutation mutation : PluginLepidopterology.butterflyInterface.getMutations(true)) { + float chance = 0; + + if ((chance = mutation.getChance(nursery, allele0, allele1, genome0, genome1)) > 0) + if (world.rand.nextFloat()*100 < chance) { + //IApiaristTracker breedingTracker = PluginApiculture.beeInterface.getBreedingTracker(world, housing.getOwnerName()); + //breedingTracker.registerMutation(mutation); + return PluginLepidopterology.butterflyInterface.templateAsChromosomes(mutation.getTemplate()); + } + } + + return null; + } + + private boolean isActiveThisTime(boolean isDayTime) { + if(getGenome().getNocturnal()) + return true; + + return isDayTime ? !getGenome().getPrimary().isNocturnal() : getGenome().getPrimary().isNocturnal(); + } + + @Override + public float getSize() { + return getGenome().getSize(); + } + + @Override + public void mate(IIndividual individual) { + if(!(individual instanceof IButterfly)) + return; + + mate = ((IButterfly)individual).getGenome(); + } + + @Override + public ItemStack[] getLootDrop(IEntityButterfly entity, boolean playerKill, int lootLevel) { + ArrayList drop = new ArrayList(); + + EntityCreature creature = entity.getEntity(); + float metabolism = (float)getGenome().getMetabolism() / 10; + + for (Map.Entry entry : getGenome().getPrimary().getButterflyLoot().entrySet()) + if (creature.worldObj.rand.nextFloat() < entry.getValue() * metabolism) + drop.add(entry.getKey().copy()); + + return drop.toArray(StackUtils.EMPTY_STACK_ARRAY); + } + + @Override + public ItemStack[] getCaterpillarDrop(IButterflyNursery nursery, boolean playerKill, int lootLevel) { + ArrayList drop = new ArrayList(); + float metabolism = (float)getGenome().getMetabolism() / 10; + + for (Map.Entry entry : getGenome().getPrimary().getCaterpillarLoot().entrySet()) + if (nursery.getWorld().rand.nextFloat() < entry.getValue() * metabolism) + drop.add(entry.getKey().copy()); + + return drop.toArray(StackUtils.EMPTY_STACK_ARRAY); + } + +} diff --git a/forestry_common/lepidopterology/forestry/lepidopterology/genetics/ButterflyGenome.java b/forestry_common/lepidopterology/forestry/lepidopterology/genetics/ButterflyGenome.java new file mode 100755 index 000000000..847013306 --- /dev/null +++ b/forestry_common/lepidopterology/forestry/lepidopterology/genetics/ButterflyGenome.java @@ -0,0 +1,115 @@ +/******************************************************************************* + * Copyright 2011-2014 by SirSengir + * + * This work is licensed under a Creative Commons Attribution-NonCommercial-NoDerivs 3.0 Unported License. + * + * To view a copy of this license, visit http://creativecommons.org/licenses/by-nc-nd/3.0/. + ******************************************************************************/ +package forestry.lepidopterology.genetics; + +import net.minecraft.nbt.NBTTagCompound; + +import forestry.api.genetics.EnumTolerance; +import forestry.api.genetics.IAlleleFloat; +import forestry.api.genetics.IAlleleFlowers; +import forestry.api.genetics.IAlleleInteger; +import forestry.api.genetics.IChromosome; +import forestry.api.genetics.IFlowerProvider; +import forestry.api.genetics.ISpeciesRoot; +import forestry.api.lepidopterology.EnumButterflyChromosome; +import forestry.api.lepidopterology.IAlleleButterflyEffect; +import forestry.api.lepidopterology.IAlleleButterflySpecies; +import forestry.api.lepidopterology.IButterflyGenome; +import forestry.core.genetics.AlleleBoolean; +import forestry.core.genetics.AlleleTolerance; +import forestry.core.genetics.Genome; +import forestry.plugins.PluginLepidopterology; + +public class ButterflyGenome extends Genome implements IButterflyGenome { + + /* CONSTRUCTOR */ + public ButterflyGenome(NBTTagCompound nbttagcompound) { + super(nbttagcompound); + } + + public ButterflyGenome(IChromosome[] chromosomes) { + super(chromosomes); + } + + /* SPECIES */ + @Override + public IAlleleButterflySpecies getPrimary() { + return (IAlleleButterflySpecies) getActiveAllele(EnumButterflyChromosome.SPECIES.ordinal()); + } + + @Override + public IAlleleButterflySpecies getSecondary() { + return (IAlleleButterflySpecies) getInactiveAllele(EnumButterflyChromosome.SPECIES.ordinal()); + } + + @Override + public float getSize() { + return ((IAlleleFloat) getActiveAllele(EnumButterflyChromosome.SIZE.ordinal())).getValue(); + } + + @Override + public int getLifespan() { + return ((IAlleleInteger) getActiveAllele(EnumButterflyChromosome.LIFESPAN.ordinal())).getValue(); + } + + @Override + public float getSpeed() { + return ((IAlleleFloat) getActiveAllele(EnumButterflyChromosome.SPEED.ordinal())).getValue(); + } + + @Override + public int getMetabolism() { + return ((IAlleleInteger) getActiveAllele(EnumButterflyChromosome.METABOLISM.ordinal())).getValue(); + } + + @Override + public int getFertility() { + return ((IAlleleInteger) getActiveAllele(EnumButterflyChromosome.FERTILITY.ordinal())).getValue(); + } + + @Override + public EnumTolerance getToleranceTemp() { + return ((AlleleTolerance) getActiveAllele(EnumButterflyChromosome.TEMPERATURE_TOLERANCE.ordinal())).getValue(); + } + + @Override + public EnumTolerance getToleranceHumid() { + return ((AlleleTolerance) getActiveAllele(EnumButterflyChromosome.HUMIDITY_TOLERANCE.ordinal())).getValue(); + } + + @Override + public boolean getNocturnal() { + return ((AlleleBoolean) getActiveAllele(EnumButterflyChromosome.NOCTURNAL.ordinal())).getValue(); + } + + @Override + public boolean getTolerantFlyer() { + return ((AlleleBoolean) getActiveAllele(EnumButterflyChromosome.TOLERANT_FLYER.ordinal())).getValue(); + } + + @Override + public boolean getFireResist() { + return ((AlleleBoolean) getActiveAllele(EnumButterflyChromosome.FIRE_RESIST.ordinal())).getValue(); + } + + @Override + public IFlowerProvider getFlowerProvider() { + return ((IAlleleFlowers) getActiveAllele(EnumButterflyChromosome.FLOWER_PROVIDER.ordinal())).getProvider(); + } + + @Override + public IAlleleButterflyEffect getEffect() { + return (IAlleleButterflyEffect) getActiveAllele(EnumButterflyChromosome.EFFECT.ordinal()); + } + + @Override + public ISpeciesRoot getSpeciesRoot() { + return PluginLepidopterology.butterflyInterface; + } + +} diff --git a/forestry_common/lepidopterology/forestry/lepidopterology/genetics/ButterflyHelper.java b/forestry_common/lepidopterology/forestry/lepidopterology/genetics/ButterflyHelper.java new file mode 100755 index 000000000..17295b99d --- /dev/null +++ b/forestry_common/lepidopterology/forestry/lepidopterology/genetics/ButterflyHelper.java @@ -0,0 +1,239 @@ +/******************************************************************************* + * Copyright 2011-2014 by SirSengir + * + * This work is licensed under a Creative Commons Attribution-NonCommercial-NoDerivs 3.0 Unported License. + * + * To view a copy of this license, visit http://creativecommons.org/licenses/by-nc-nd/3.0/. + ******************************************************************************/ +package forestry.lepidopterology.genetics; + +import java.util.ArrayList; +import java.util.Collection; +import java.util.Collections; +import java.util.Map.Entry; + +import net.minecraft.entity.EntityLiving; +import net.minecraft.item.Item; +import net.minecraft.item.ItemStack; +import net.minecraft.nbt.NBTTagCompound; +import net.minecraft.world.World; + +import forestry.api.genetics.AlleleManager; +import forestry.api.genetics.IAllele; +import forestry.api.genetics.IChromosomeType; +import forestry.api.genetics.IIndividual; +import forestry.api.genetics.IMutation; +import forestry.api.lepidopterology.EnumButterflyChromosome; +import forestry.api.lepidopterology.EnumFlutterType; +import forestry.api.lepidopterology.IAlleleButterflySpecies; +import forestry.api.lepidopterology.IButterfly; +import forestry.api.lepidopterology.IButterflyGenome; +import forestry.api.lepidopterology.IButterflyMutation; +import forestry.api.lepidopterology.IButterflyRoot; +import forestry.api.lepidopterology.ILepidopteristTracker; +import forestry.core.config.ForestryItem; +import forestry.core.genetics.SpeciesRoot; +import forestry.core.utils.Utils; +import forestry.lepidopterology.entities.EntityButterfly; +import forestry.plugins.PluginLepidopterology; + +public class ButterflyHelper extends SpeciesRoot implements IButterflyRoot { + + public static int butterflySpeciesCount = -1; + public static final String UID = "rootButterflies"; + + @Override + public String getUID() { + return UID; + } + + @Override + public Class getMemberClass() { + return IButterfly.class; + } + + @Override + public int getSpeciesCount() { + if (butterflySpeciesCount < 0) { + butterflySpeciesCount = 0; + for (Entry entry : AlleleManager.alleleRegistry.getRegisteredAlleles().entrySet()) { + if (entry.getValue() instanceof IAlleleButterflySpecies) + if (((IAlleleButterflySpecies) entry.getValue()).isCounted()) + butterflySpeciesCount++; + } + } + + return butterflySpeciesCount; + } + + @Override + public boolean isMember(ItemStack stack) { + return getType(stack) != EnumFlutterType.NONE; + } + + private EnumFlutterType getType(ItemStack stack) { + if(stack == null) + return EnumFlutterType.NONE; + + if(ForestryItem.butterflyGE.isItemEqual(stack)) + return EnumFlutterType.BUTTERFLY; + else if(ForestryItem.serumGE.isItemEqual(stack)) + return EnumFlutterType.SERUM; + else if(ForestryItem.caterpillarGE.isItemEqual(stack)) + return EnumFlutterType.CATERPILLAR; + else + return EnumFlutterType.NONE; + } + + @Override + public boolean isMember(ItemStack stack, int type) { + return getType(stack).ordinal() == type; + } + + @Override + public boolean isMember(IIndividual individual) { + return individual instanceof IButterfly; + } + + @Override + public IButterfly getMember(ItemStack stack) { + if(!stack.hasTagCompound()) + return null; + if(!isMember(stack)) + return null; + + return new Butterfly(stack.getTagCompound()); + } + + @Override + public IButterfly getMember(NBTTagCompound compound) { + return new Butterfly(compound); + } + + @Override + public ItemStack getMemberStack(IIndividual butterfly, int type) { + + Item butterflyItem; + switch(EnumFlutterType.VALUES[type]) { + case SERUM: + butterflyItem = ForestryItem.serumGE.item(); + break; + case CATERPILLAR: + butterflyItem = ForestryItem.caterpillarGE.item(); + break; + case BUTTERFLY: + default: + butterflyItem = ForestryItem.butterflyGE.item(); + break; + } + + NBTTagCompound nbttagcompound = new NBTTagCompound(); + butterfly.writeToNBT(nbttagcompound); + ItemStack stack = new ItemStack(butterflyItem); + stack.setTagCompound(nbttagcompound); + return stack; + + } + + @Override + public EntityLiving spawnButterflyInWorld(World world, IButterfly butterfly, double x, double y, double z) { + return (EntityButterfly)Utils.spawnEntity(world, new EntityButterfly(world, butterfly), x, y, z); + } + + @Override + public boolean isMated(ItemStack stack) { + IButterfly butterfly = getMember(stack); + if(butterfly == null) + return false; + + return butterfly.getMate() != null; + } + + /* GENOME CONVERSIONS */ + @Override + public IButterfly templateAsIndividual(IAllele[] template) { + return new Butterfly(templateAsGenome(template)); + } + + @Override + public IButterfly templateAsIndividual(IAllele[] templateActive, IAllele[] templateInactive) { + return new Butterfly(templateAsGenome(templateActive, templateInactive)); + } + + @Override + public IButterflyGenome templateAsGenome(IAllele[] template) { + return new ButterflyGenome(templateAsChromosomes(template)); + } + + @Override + public IButterflyGenome templateAsGenome(IAllele[] templateActive, IAllele[] templateInactive) { + return new ButterflyGenome(templateAsChromosomes(templateActive, templateInactive)); + } + + /* TEMPLATES */ + public static ArrayList butterflyTemplates = new ArrayList(); + + @Override + public ArrayList getIndividualTemplates() { + return butterflyTemplates; + } + + @Override + public IAllele[] getDefaultTemplate() { + return ButterflyTemplates.getDefaultTemplate(); + } + + @Override + public void registerTemplate(String identifier, IAllele[] template) { + butterflyTemplates.add(PluginLepidopterology.butterflyInterface.templateAsIndividual(template)); + speciesTemplates.put(identifier, template); + } + + /* MUTATIONS */ + private static ArrayList butterflyMutations = new ArrayList(); + + @Override + public void registerMutation(IMutation mutation) { + if (AlleleManager.alleleRegistry.isBlacklisted(mutation.getTemplate()[0].getUID())) + return; + if (AlleleManager.alleleRegistry.isBlacklisted(mutation.getAllele0().getUID())) + return; + if (AlleleManager.alleleRegistry.isBlacklisted(mutation.getAllele1().getUID())) + return; + + butterflyMutations.add((IButterflyMutation)mutation); + } + + @Override + public Collection getMutations(boolean shuffle) { + if (shuffle) + Collections.shuffle(butterflyMutations); + return butterflyMutations; + } + + /* BREEDING TRACKER */ + @Override + public ILepidopteristTracker getBreedingTracker(World world, String player) { + String filename = "LepidopteristTracker." + player; + LepidopteristTracker tracker = (LepidopteristTracker) world.loadItemData(LepidopteristTracker.class, filename); + + // Create a tracker if there is none yet. + if (tracker == null) { + tracker = new LepidopteristTracker(filename, player); + world.setItemData(filename, tracker); + } + + return tracker; + } + + @Override + public IChromosomeType[] getKaryotype() { + return EnumButterflyChromosome.values(); + } + + @Override + public IChromosomeType getKaryotypeKey() { + return EnumButterflyChromosome.SPECIES; + } + +} diff --git a/forestry_common/lepidopterology/forestry/lepidopterology/genetics/ButterflyTemplates.java b/forestry_common/lepidopterology/forestry/lepidopterology/genetics/ButterflyTemplates.java new file mode 100755 index 000000000..a305a8d4a --- /dev/null +++ b/forestry_common/lepidopterology/forestry/lepidopterology/genetics/ButterflyTemplates.java @@ -0,0 +1,304 @@ +/******************************************************************************* + * Copyright 2011-2014 by SirSengir + * + * This work is licensed under a Creative Commons Attribution-NonCommercial-NoDerivs 3.0 Unported License. + * + * To view a copy of this license, visit http://creativecommons.org/licenses/by-nc-nd/3.0/. + ******************************************************************************/ +package forestry.lepidopterology.genetics; + +import forestry.api.genetics.IAllele; +import forestry.api.lepidopterology.EnumButterflyChromosome; +import forestry.core.genetics.Allele; + +public class ButterflyTemplates { + + public static IAllele[] getDefaultTemplate() { + IAllele[] alleles = new IAllele[EnumButterflyChromosome.values().length]; + + alleles[EnumButterflyChromosome.SPECIES.ordinal()] = Allele.lepiCabbageWhite; + alleles[EnumButterflyChromosome.SIZE.ordinal()] = Allele.sizeSmall; + alleles[EnumButterflyChromosome.SPEED.ordinal()] = Allele.speedSlowest; + alleles[EnumButterflyChromosome.LIFESPAN.ordinal()] = Allele.lifespanShorter; + alleles[EnumButterflyChromosome.METABOLISM.ordinal()] = Allele.int3; + alleles[EnumButterflyChromosome.FERTILITY.ordinal()] = Allele.int3; + alleles[EnumButterflyChromosome.TEMPERATURE_TOLERANCE.ordinal()] = Allele.toleranceNone; + alleles[EnumButterflyChromosome.HUMIDITY_TOLERANCE.ordinal()] = Allele.toleranceNone; + alleles[EnumButterflyChromosome.NOCTURNAL.ordinal()] = Allele.boolFalse; + alleles[EnumButterflyChromosome.TOLERANT_FLYER.ordinal()] = Allele.boolFalse; + alleles[EnumButterflyChromosome.FIRE_RESIST.ordinal()] = Allele.boolFalse; + alleles[EnumButterflyChromosome.FLOWER_PROVIDER.ordinal()] = Allele.flowersVanilla; + alleles[EnumButterflyChromosome.EFFECT.ordinal()] = Allele.butterflyNone; + + return alleles; + } + + public static IAllele[] getCabbageWhiteTemplate() { + IAllele[] alleles = getDefaultTemplate(); + alleles[EnumButterflyChromosome.SIZE.ordinal()] = Allele.sizeAverage; + return alleles; + } + + public static IAllele[] getGlasswingTemplate() { + IAllele[] alleles = getDefaultTemplate(); + alleles[EnumButterflyChromosome.SPECIES.ordinal()] = Allele.lepiGlasswing; + alleles[EnumButterflyChromosome.SIZE.ordinal()] = Allele.sizeSmaller; + alleles[EnumButterflyChromosome.LIFESPAN.ordinal()] = Allele.lifespanShort; + alleles[EnumButterflyChromosome.FERTILITY.ordinal()] = Allele.int5; + alleles[EnumButterflyChromosome.TEMPERATURE_TOLERANCE.ordinal()] = Allele.toleranceDown1; + return alleles; + } + + public static IAllele[] getEmeraldPeacockTemplate() { + IAllele[] alleles = getDefaultTemplate(); + alleles[EnumButterflyChromosome.SPECIES.ordinal()] = Allele.lepiEmeraldPeacock; + alleles[EnumButterflyChromosome.SIZE.ordinal()] = Allele.sizeLarge; + alleles[EnumButterflyChromosome.LIFESPAN.ordinal()] = Allele.lifespanNormal; + alleles[EnumButterflyChromosome.FERTILITY.ordinal()] = Allele.int5; + alleles[EnumButterflyChromosome.TEMPERATURE_TOLERANCE.ordinal()] = Allele.toleranceDown1; + alleles[EnumButterflyChromosome.HUMIDITY_TOLERANCE.ordinal()] = Allele.toleranceDown1; + return alleles; + } + + public static IAllele[] getCitrusSwallowTemplate() { + IAllele[] alleles = getDefaultTemplate(); + alleles[EnumButterflyChromosome.SPECIES.ordinal()] = Allele.lepiCitrusSwallow; + alleles[EnumButterflyChromosome.SPEED.ordinal()] = Allele.speedSlower; + alleles[EnumButterflyChromosome.SIZE.ordinal()] = Allele.sizeLarge; + alleles[EnumButterflyChromosome.FERTILITY.ordinal()] = Allele.int10; + alleles[EnumButterflyChromosome.METABOLISM.ordinal()] = Allele.int8; + alleles[EnumButterflyChromosome.LIFESPAN.ordinal()] = Allele.lifespanShorter; + alleles[EnumButterflyChromosome.TEMPERATURE_TOLERANCE.ordinal()] = Allele.toleranceDown1; + alleles[EnumButterflyChromosome.HUMIDITY_TOLERANCE.ordinal()] = Allele.toleranceDown1; + return alleles; + } + + public static IAllele[] getBlackSwallowTemplate() { + IAllele[] alleles = getDefaultTemplate(); + alleles[EnumButterflyChromosome.SPECIES.ordinal()] = Allele.lepiBlackSwallow; + alleles[EnumButterflyChromosome.SPEED.ordinal()] = Allele.speedSlow; + alleles[EnumButterflyChromosome.SIZE.ordinal()] = Allele.sizeLarge; + alleles[EnumButterflyChromosome.LIFESPAN.ordinal()] = Allele.lifespanShorter; + alleles[EnumButterflyChromosome.TEMPERATURE_TOLERANCE.ordinal()] = Allele.toleranceDown1; + alleles[EnumButterflyChromosome.HUMIDITY_TOLERANCE.ordinal()] = Allele.toleranceDown1; + return alleles; + } + + public static IAllele[] getBrimstoneMothTemplate() { + IAllele[] alleles = getDefaultTemplate(); + alleles[EnumButterflyChromosome.SPECIES.ordinal()] = Allele.mothBrimstone; + return alleles; + } + + public static IAllele[] getSpeckledWoodTemplate() { + IAllele[] alleles = getDefaultTemplate(); + alleles[EnumButterflyChromosome.SPECIES.ordinal()] = Allele.lepiSpeckledWood; + alleles[EnumButterflyChromosome.FERTILITY.ordinal()] = Allele.int2; + return alleles; + } + + public static IAllele[] getMadeiranSpeckledWoodTemplate() { + IAllele[] alleles = getDefaultTemplate(); + alleles[EnumButterflyChromosome.SPECIES.ordinal()] = Allele.lepiMadeiranSpeckledWood; + alleles[EnumButterflyChromosome.FERTILITY.ordinal()] = Allele.int2; + return alleles; + } + + public static IAllele[] getCanarySpeckledWoodTemplate() { + IAllele[] alleles = getDefaultTemplate(); + alleles[EnumButterflyChromosome.SPECIES.ordinal()] = Allele.lepiCanarySpeckledWood; + alleles[EnumButterflyChromosome.FERTILITY.ordinal()] = Allele.int2; + return alleles; + } + + public static IAllele[] getMenelausBlueMorphoTemplate() { + IAllele[] alleles = getDefaultTemplate(); + alleles[EnumButterflyChromosome.SPECIES.ordinal()] = Allele.lepiMenelausBlueMorpho; + alleles[EnumButterflyChromosome.SIZE.ordinal()] = Allele.sizeLarger; + alleles[EnumButterflyChromosome.LIFESPAN.ordinal()] = Allele.lifespanShortest; + alleles[EnumButterflyChromosome.FERTILITY.ordinal()] = Allele.int2; + return alleles; + } + + public static IAllele[] getRhetenorBlueMorphoTemplate() { + IAllele[] alleles = getDefaultTemplate(); + alleles[EnumButterflyChromosome.SPECIES.ordinal()] = Allele.lepiRhetenorBlueMorpho; + alleles[EnumButterflyChromosome.SIZE.ordinal()] = Allele.sizeLarger; + alleles[EnumButterflyChromosome.LIFESPAN.ordinal()] = Allele.lifespanShortest; + alleles[EnumButterflyChromosome.FERTILITY.ordinal()] = Allele.int2; + return alleles; + } + + public static IAllele[] getPeleidesBlueMorphoTemplate() { + IAllele[] alleles = getDefaultTemplate(); + alleles[EnumButterflyChromosome.SPECIES.ordinal()] = Allele.lepiPeleidesBlueMorpho; + alleles[EnumButterflyChromosome.SIZE.ordinal()] = Allele.sizeLarger; + alleles[EnumButterflyChromosome.LIFESPAN.ordinal()] = Allele.lifespanShortest; + alleles[EnumButterflyChromosome.FERTILITY.ordinal()] = Allele.int2; + return alleles; + } + + public static IAllele[] getBrimstoneTemplate() { + IAllele[] alleles = getDefaultTemplate(); + alleles[EnumButterflyChromosome.SPECIES.ordinal()] = Allele.lepiBrimstone; + return alleles; + } + + public static IAllele[] getAuroraTemplate() { + IAllele[] alleles = getDefaultTemplate(); + alleles[EnumButterflyChromosome.SPECIES.ordinal()] = Allele.lepiAurora; + alleles[EnumButterflyChromosome.SIZE.ordinal()] = Allele.sizeSmaller; + return alleles; + } + + public static IAllele[] getPostillionTemplate() { + IAllele[] alleles = getDefaultTemplate(); + alleles[EnumButterflyChromosome.SPECIES.ordinal()] = Allele.lepiPostillion; + alleles[EnumButterflyChromosome.SPEED.ordinal()] = Allele.speedSlow; + return alleles; + } + + public static IAllele[] getPalaenoSulphurTemplate() { + IAllele[] alleles = getDefaultTemplate(); + alleles[EnumButterflyChromosome.SPECIES.ordinal()] = Allele.lepiPalaenoSulphur; + alleles[EnumButterflyChromosome.SPEED.ordinal()] = Allele.speedSlower; + return alleles; + } + + public static IAllele[] getResedaTemplate() { + IAllele[] alleles = getDefaultTemplate(); + alleles[EnumButterflyChromosome.SPECIES.ordinal()] = Allele.lepiReseda; + alleles[EnumButterflyChromosome.SPEED.ordinal()] = Allele.speedSlower; + return alleles; + } + + public static IAllele[] getSpringAzureTemplate() { + IAllele[] alleles = getDefaultTemplate(); + alleles[EnumButterflyChromosome.SPECIES.ordinal()] = Allele.lepiSpringAzure; + alleles[EnumButterflyChromosome.SIZE.ordinal()] = Allele.sizeSmaller; + alleles[EnumButterflyChromosome.LIFESPAN.ordinal()] = Allele.lifespanShort; + return alleles; + } + + public static IAllele[] getGozoraAzureTemplate() { + IAllele[] alleles = getDefaultTemplate(); + alleles[EnumButterflyChromosome.SPECIES.ordinal()] = Allele.lepiGozoraAzure; + alleles[EnumButterflyChromosome.SIZE.ordinal()] = Allele.sizeSmaller; + alleles[EnumButterflyChromosome.LIFESPAN.ordinal()] = Allele.lifespanShort; + return alleles; + } + + public static IAllele[] getCommaTemplate() { + IAllele[] alleles = getDefaultTemplate(); + alleles[EnumButterflyChromosome.SPECIES.ordinal()] = Allele.lepiComma; + alleles[EnumButterflyChromosome.SPEED.ordinal()] = Allele.speedSlower; + return alleles; + } + + public static IAllele[] getBatesiaTemplate() { + IAllele[] alleles = getDefaultTemplate(); + alleles[EnumButterflyChromosome.SPECIES.ordinal()] = Allele.lepiBatesia; + alleles[EnumButterflyChromosome.SIZE.ordinal()] = Allele.sizeLarge; + return alleles; + } + + public static IAllele[] getBlueWingTemplate() { + IAllele[] alleles = getDefaultTemplate(); + alleles[EnumButterflyChromosome.SPECIES.ordinal()] = Allele.lepiBlueWing; + alleles[EnumButterflyChromosome.SIZE.ordinal()] = Allele.sizeAverage; + alleles[EnumButterflyChromosome.METABOLISM.ordinal()] = Allele.int5; + return alleles; + } + + public static IAllele[] getBlueDukeTemplate() { + IAllele[] alleles = getDefaultTemplate(); + alleles[EnumButterflyChromosome.SPECIES.ordinal()] = Allele.lepiBlueDuke; + alleles[EnumButterflyChromosome.TEMPERATURE_TOLERANCE.ordinal()] = Allele.toleranceBoth1; + return alleles; + } + + public static IAllele[] getGlassyTigerTemplate() { + IAllele[] alleles = getDefaultTemplate(); + alleles[EnumButterflyChromosome.SPECIES.ordinal()] = Allele.lepiGlassyTiger; + alleles[EnumButterflyChromosome.SIZE.ordinal()] = Allele.sizeAverage; + return alleles; + } + + public static IAllele[] getPostmanTemplate() { + IAllele[] alleles = getDefaultTemplate(); + alleles[EnumButterflyChromosome.SPECIES.ordinal()] = Allele.lepiPostman; + return alleles; + } + + public static IAllele[] getSpicebushTemplate() { + IAllele[] alleles = getDefaultTemplate(); + alleles[EnumButterflyChromosome.SPECIES.ordinal()] = Allele.lepiSpicebush; + alleles[EnumButterflyChromosome.SIZE.ordinal()] = Allele.sizeAverage; + return alleles; + } + + public static IAllele[] getMalachiteTemplate() { + IAllele[] alleles = getDefaultTemplate(); + alleles[EnumButterflyChromosome.SPECIES.ordinal()] = Allele.lepiMalachite; + alleles[EnumButterflyChromosome.SIZE.ordinal()] = Allele.sizeAverage; + alleles[EnumButterflyChromosome.TEMPERATURE_TOLERANCE.ordinal()] = Allele.toleranceDown1; + alleles[EnumButterflyChromosome.HUMIDITY_TOLERANCE.ordinal()] = Allele.toleranceDown1; + return alleles; + } + + public static IAllele[] getLeopardLacewingTemplate() { + IAllele[] alleles = getDefaultTemplate(); + alleles[EnumButterflyChromosome.SPECIES.ordinal()] = Allele.lepiLLacewing; + alleles[EnumButterflyChromosome.TEMPERATURE_TOLERANCE.ordinal()] = Allele.toleranceUp1; + alleles[EnumButterflyChromosome.HUMIDITY_TOLERANCE.ordinal()] = Allele.toleranceUp1; + return alleles; + } + + public static IAllele[] getMonarchTemplate() { + IAllele[] alleles = getDefaultTemplate(); + alleles[EnumButterflyChromosome.SPECIES.ordinal()] = Allele.lepiMonarch; + alleles[EnumButterflyChromosome.SIZE.ordinal()] = Allele.sizeAverage; + return alleles; + } + + public static IAllele[] getThoasSwallowTemplate() { + IAllele[] alleles = getDefaultTemplate(); + alleles[EnumButterflyChromosome.SPECIES.ordinal()] = Allele.lepiThoasSwallow; + alleles[EnumButterflyChromosome.SPEED.ordinal()] = Allele.speedSlower; + alleles[EnumButterflyChromosome.SIZE.ordinal()] = Allele.sizeLarge; + alleles[EnumButterflyChromosome.LIFESPAN.ordinal()] = Allele.lifespanShortest; + return alleles; + } + + public static IAllele[] getZebraSwallowTemplate() { + IAllele[] alleles = getDefaultTemplate(); + alleles[EnumButterflyChromosome.SPECIES.ordinal()] = Allele.lepiZebraSwallow; + alleles[EnumButterflyChromosome.SPEED.ordinal()] = Allele.speedSlower; + alleles[EnumButterflyChromosome.SIZE.ordinal()] = Allele.sizeAverage; + return alleles; + } + + public static IAllele[] getDianaFritTemplate() { + IAllele[] alleles = getDefaultTemplate(); + alleles[EnumButterflyChromosome.SPECIES.ordinal()] = Allele.lepiDianaFrit; + alleles[EnumButterflyChromosome.SPEED.ordinal()] = Allele.speedSlower; + alleles[EnumButterflyChromosome.SIZE.ordinal()] = Allele.sizeSmaller; + return alleles; + } + + public static IAllele[] getLatticedHeathTemplate() { + IAllele[] alleles = getDefaultTemplate(); + alleles[EnumButterflyChromosome.SPECIES.ordinal()] = Allele.mothLatticedHeath; + alleles[EnumButterflyChromosome.SIZE.ordinal()] = Allele.sizeSmallest; + return alleles; + } + + public static IAllele[] getAtlasMothTemplate() { + IAllele[] alleles = getDefaultTemplate(); + alleles[EnumButterflyChromosome.SPECIES.ordinal()] = Allele.mothAtlas; + alleles[EnumButterflyChromosome.SIZE.ordinal()] = Allele.sizeLargest; + return alleles; + } + + +} diff --git a/forestry_common/lepidopterology/forestry/lepidopterology/genetics/LepidopteristTracker.java b/forestry_common/lepidopterology/forestry/lepidopterology/genetics/LepidopteristTracker.java new file mode 100755 index 000000000..62a6e8a20 --- /dev/null +++ b/forestry_common/lepidopterology/forestry/lepidopterology/genetics/LepidopteristTracker.java @@ -0,0 +1,49 @@ +/******************************************************************************* + * Copyright 2011-2014 by SirSengir + * + * This work is licensed under a Creative Commons Attribution-NonCommercial-NoDerivs 3.0 Unported License. + * + * To view a copy of this license, visit http://creativecommons.org/licenses/by-nc-nd/3.0/. + ******************************************************************************/ +package forestry.lepidopterology.genetics; + +import net.minecraft.entity.player.EntityPlayer; + +import forestry.api.genetics.IBreedingTracker; +import forestry.api.genetics.IIndividual; +import forestry.api.lepidopterology.IButterfly; +import forestry.api.lepidopterology.ILepidopteristTracker; +import forestry.core.genetics.BreedingTracker; +import forestry.plugins.PluginLepidopterology; + +public class LepidopteristTracker extends BreedingTracker implements ILepidopteristTracker { + + public LepidopteristTracker(String s) { + this(s, ""); + } + + public LepidopteristTracker(String s, String player) { + super(s, player); + } + + @Override + protected IBreedingTracker getCommonTracker(EntityPlayer player) { + return PluginLepidopterology.butterflyInterface.getBreedingTracker(player.worldObj, "__COMMON_"); + } + + @Override + protected String getPacketTag() { + return ButterflyHelper.UID; + } + + @Override + public void registerPickup(IIndividual individual) { + } + + @Override + public void registerCatch(IButterfly butterfly) { + registerSpecies(butterfly.getGenome().getPrimary()); + registerSpecies(butterfly.getGenome().getSecondary()); + } + +} diff --git a/forestry_common/lepidopterology/forestry/lepidopterology/gui/ContainerFlutterlyzer.java b/forestry_common/lepidopterology/forestry/lepidopterology/gui/ContainerFlutterlyzer.java new file mode 100755 index 000000000..ca170dd2d --- /dev/null +++ b/forestry_common/lepidopterology/forestry/lepidopterology/gui/ContainerFlutterlyzer.java @@ -0,0 +1,81 @@ +/******************************************************************************* + * Copyright 2011-2014 by SirSengir + * + * This work is licensed under a Creative Commons Attribution-NonCommercial-NoDerivs 3.0 Unported License. + * + * To view a copy of this license, visit http://creativecommons.org/licenses/by-nc-nd/3.0/. + ******************************************************************************/ +package forestry.lepidopterology.gui; + +import net.minecraft.entity.player.EntityPlayer; +import net.minecraft.entity.player.InventoryPlayer; +import net.minecraft.init.Blocks; +import net.minecraft.item.ItemStack; + +import forestry.core.config.ForestryItem; +import forestry.core.gui.ContainerItemInventory; +import forestry.core.gui.slots.SlotCustom; +import forestry.core.proxy.Proxies; +import forestry.lepidopterology.items.ItemButterflyGE; +import forestry.lepidopterology.items.ItemFlutterlyzer.FlutterlyzerInventory; + +public class ContainerFlutterlyzer extends ContainerItemInventory { + + FlutterlyzerInventory inventory; + + public ContainerFlutterlyzer(InventoryPlayer inventoryplayer, FlutterlyzerInventory inventory) { + super(inventory, inventoryplayer.player); + + this.inventory = inventory; + + // Energy + this.addSlot(new SlotCustom(inventory, FlutterlyzerInventory.SLOT_ENERGY, 172, 8, new Object[] { ForestryItem.honeydew, ForestryItem.honeyDrop })); + + // Bee to analyze + this.addSlot(new SlotCustom(inventory, FlutterlyzerInventory.SLOT_SPECIMEN, 172, 26, new Object[] { ItemButterflyGE.class, Blocks.sapling })); + + // Analyzed bee + this.addSlot(new SlotCustom(inventory, FlutterlyzerInventory.SLOT_ANALYZE_1, 172, 57, new Object[] { ItemButterflyGE.class })); + this.addSlot(new SlotCustom(inventory, FlutterlyzerInventory.SLOT_ANALYZE_2, 172, 75, new Object[] { ItemButterflyGE.class })); + this.addSlot(new SlotCustom(inventory, FlutterlyzerInventory.SLOT_ANALYZE_3, 172, 93, new Object[] { ItemButterflyGE.class })); + this.addSlot(new SlotCustom(inventory, FlutterlyzerInventory.SLOT_ANALYZE_4, 172, 111, new Object[] { ItemButterflyGE.class })); + this.addSlot(new SlotCustom(inventory, FlutterlyzerInventory.SLOT_ANALYZE_5, 172, 129, new Object[] { ItemButterflyGE.class })); + + // Player inventory + for (int i1 = 0; i1 < 3; i1++) + for (int l1 = 0; l1 < 9; l1++) + addSecuredSlot(inventoryplayer, l1 + i1 * 9 + 9, 18 + l1 * 18, 156 + i1 * 18); + // Player hotbar + for (int j1 = 0; j1 < 9; j1++) + addSecuredSlot(inventoryplayer, j1, 18 + j1 * 18, 214); + + } + + @Override + public void onContainerClosed(EntityPlayer entityplayer) { + + if (!Proxies.common.isSimulating(entityplayer.worldObj)) + return; + + // Last slot is the energy slot, so we don't save that one. + for (int i = 0; i < inventory.getSizeInventory(); i++) { + if (i == FlutterlyzerInventory.SLOT_ENERGY) + continue; + ItemStack stack = inventory.getStackInSlot(i); + if (stack == null) + continue; + + Proxies.common.dropItemPlayer(entityplayer, stack); + inventory.setInventorySlotContents(i, null); + } + + inventory.onGuiSaved(entityplayer); + + } + + @Override + protected boolean isAcceptedItem(EntityPlayer player, ItemStack stack) { + return true; + } + +} diff --git a/forestry_common/lepidopterology/forestry/lepidopterology/gui/GuiFlutterlyzer.java b/forestry_common/lepidopterology/forestry/lepidopterology/gui/GuiFlutterlyzer.java new file mode 100755 index 000000000..7562d274b --- /dev/null +++ b/forestry_common/lepidopterology/forestry/lepidopterology/gui/GuiFlutterlyzer.java @@ -0,0 +1,332 @@ +/******************************************************************************* + * Copyright 2011-2014 by SirSengir + * + * This work is licensed under a Creative Commons Attribution-NonCommercial-NoDerivs 3.0 Unported License. + * + * To view a copy of this license, visit http://creativecommons.org/licenses/by-nc-nd/3.0/. + ******************************************************************************/ +package forestry.lepidopterology.gui; + +import java.util.ArrayList; +import java.util.HashMap; +import java.util.Map; + +import net.minecraft.client.renderer.RenderHelper; +import net.minecraft.entity.player.EntityPlayer; +import net.minecraft.item.ItemStack; + +import forestry.api.genetics.AlleleManager; +import forestry.api.genetics.IAllele; +import forestry.api.genetics.IAlleleEffect; +import forestry.api.genetics.IAlleleFlowers; +import forestry.api.genetics.IAlleleInteger; +import forestry.api.genetics.IMutation; +import forestry.api.lepidopterology.EnumButterflyChromosome; +import forestry.api.lepidopterology.IButterfly; +import forestry.core.config.ForestryItem; +import forestry.core.genetics.AlleleBoolean; +import forestry.core.genetics.AlleleTolerance; +import forestry.core.genetics.ClimateHelper; +import forestry.core.genetics.GenericRatings; +import forestry.core.gui.GuiAlyzer; +import forestry.core.utils.StackUtils; +import forestry.core.utils.StringUtil; +import forestry.lepidopterology.items.ItemButterflyGE; +import forestry.lepidopterology.items.ItemFlutterlyzer.FlutterlyzerInventory; +import forestry.plugins.PluginLepidopterology; + +public class GuiFlutterlyzer extends GuiAlyzer { + + private ItemStack[] tempProductList; + + public GuiFlutterlyzer(EntityPlayer player, FlutterlyzerInventory inventory) { + super(AlleleManager.alleleRegistry.getSpeciesRoot("rootButterflies"), player, + new ContainerFlutterlyzer(player.inventory, inventory), inventory, 1, inventory.getSizeInventory()); + + xSize = 196; + ySize = 238; + + ArrayList butterflyList = new ArrayList(); + ((ItemButterflyGE) ForestryItem.butterflyGE.item()).addCreativeItems(butterflyList, false); + for (ItemStack butterflyStack : butterflyList) + iconStacks.put(PluginLepidopterology.butterflyInterface.getMember(butterflyStack).getIdent(), butterflyStack); + + } + + @Override + protected void drawGuiContainerBackgroundLayer(float var1, int mouseX, int mouseY) { + super.drawGuiContainerBackgroundLayer(var1, mouseX, mouseY); + + int page = 0; + IButterfly butterfly = null; + for (int k = 1; k < FlutterlyzerInventory.SLOT_ANALYZE_5 + 1; k++) { + if (k == FlutterlyzerInventory.SLOT_ENERGY) + continue; + + if (inventory.getStackInSlot(k) == null) + continue; + butterfly = PluginLepidopterology.butterflyInterface.getMember(inventory.getStackInSlot(k)); + if (butterfly == null || !butterfly.isAnalyzed()) + continue; + + page = k; + break; + } + + switch (page) { + case 1: + drawAnalyticsPage1(butterfly); + break; + case 2: + drawAnalyticsPage2(butterfly); + break; + case 3: + drawAnalyticsPage3(butterfly); + break; + case 4: + drawAnalyticsPage4(butterfly); + break; + case 6: + drawAnalyticsPageClassification(butterfly); + break; + default: + drawAnalyticsOverview(); + } + + } + + private void drawAnalyticsOverview() { + + startPage(); + + newLine(); + String title = StringUtil.localize("item.flutterlyzer").toUpperCase(); + drawCenteredLine(title, 8, 158); + newLine(); + + fontRendererObj.drawSplitString(StringUtil.localize("gui.flutterlyzer.help"), (int) ((guiLeft + COLUMN_0 + 4) * (1 / factor)), + (int) ((guiTop + 42) * (1 / factor)), (int) (158 * (1 / factor)), fontColor.get("gui.screen")); + newLine(); + newLine(); + newLine(); + newLine(); + + drawLine(StringUtil.localize("gui.beealyzer.overview") + ":", COLUMN_0 + 4); + newLine(); + drawLine("I : " + StringUtil.localize("gui.general"), COLUMN_0 + 4); + newLine(); + drawLine("II : " + StringUtil.localize("gui.environment"), COLUMN_0 + 4); + newLine(); + drawLine("III: " + StringUtil.localize("gui.produce"), COLUMN_0 + 4); + newLine(); + drawLine("IV : " + StringUtil.localize("gui.evolution"), COLUMN_0 + 4); + + endPage(); + } + + private void drawAnalyticsPage1(IButterfly butterfly) { + startPage(COLUMN_0, COLUMN_1, COLUMN_2); + + drawLine(StringUtil.localize("gui.active"), COLUMN_1); + drawLine(StringUtil.localize("gui.inactive"), COLUMN_2); + + newLine(); + newLine(); + + drawSpeciesRow(StringUtil.localize("gui.species"), butterfly, EnumButterflyChromosome.SPECIES); + newLine(); + + drawRow(StringUtil.localize("gui.size"), butterfly.getGenome().getActiveAllele(EnumButterflyChromosome.SIZE.ordinal()).getName(), + butterfly.getGenome().getInactiveAllele(EnumButterflyChromosome.SIZE.ordinal()).getName(), butterfly, EnumButterflyChromosome.SPEED); + + drawRow(StringUtil.localize("gui.lifespan"), butterfly.getGenome().getActiveAllele(EnumButterflyChromosome.LIFESPAN.ordinal()).getName(), + butterfly.getGenome().getInactiveAllele(EnumButterflyChromosome.LIFESPAN.ordinal()).getName(), butterfly, + EnumButterflyChromosome.LIFESPAN); + + drawRow(StringUtil.localize("gui.speed"), butterfly.getGenome().getActiveAllele(EnumButterflyChromosome.SPEED.ordinal()).getName(), + butterfly.getGenome().getInactiveAllele(EnumButterflyChromosome.SPEED.ordinal()).getName(), butterfly, EnumButterflyChromosome.SPEED); + + drawRow(StringUtil.localize("gui.metabolism"), GenericRatings.rateMetabolism(butterfly.getGenome().getMetabolism()), + GenericRatings.rateMetabolism(((IAlleleInteger) butterfly.getGenome().getInactiveAllele(EnumButterflyChromosome.METABOLISM.ordinal())).getValue()), butterfly, EnumButterflyChromosome.METABOLISM); + + drawLine(StringUtil.localize("gui.fertility"), COLUMN_0); + drawFertilityInfo(butterfly.getGenome().getFertility(), COLUMN_1, getColorCoding(butterfly.getGenome().getActiveAllele(EnumButterflyChromosome.FERTILITY.ordinal()) + .isDominant()), 8); + drawFertilityInfo(((IAlleleInteger) butterfly.getGenome().getInactiveAllele(EnumButterflyChromosome.FERTILITY.ordinal())).getValue(), COLUMN_2, getColorCoding(butterfly + .getGenome().getInactiveAllele(EnumButterflyChromosome.FERTILITY.ordinal()).isDominant()), 8); + + newLine(); + + drawRow(StringUtil.localize("gui.flowers"), StringUtil.localize(butterfly.getGenome().getFlowerProvider().getDescription()), + StringUtil.localize(((IAlleleFlowers) butterfly.getGenome().getInactiveAllele(EnumButterflyChromosome.FLOWER_PROVIDER.ordinal())).getProvider() + .getDescription()), butterfly, EnumButterflyChromosome.FLOWER_PROVIDER); + + drawRow(StringUtil.localize("gui.effect"), StringUtil.localize(butterfly.getGenome().getEffect().getName()), + StringUtil.localize(((IAlleleEffect) butterfly.getGenome().getInactiveAllele(EnumButterflyChromosome.EFFECT.ordinal())).getName()), butterfly, + EnumButterflyChromosome.EFFECT); + + newLine(); + + + endPage(); + + } + private void drawAnalyticsPage2(IButterfly butterfly) { + startPage(COLUMN_0, COLUMN_1, COLUMN_2); + + drawLine(StringUtil.localize("gui.active"), COLUMN_1); + drawLine(StringUtil.localize("gui.inactive"), COLUMN_2); + + newLine(); + newLine(); + + drawRow(StringUtil.localize("gui.climate"), ClimateHelper.toDisplay(butterfly.getGenome().getPrimary().getTemperature()), + ClimateHelper.toDisplay(butterfly.getGenome().getPrimary().getTemperature()), butterfly, EnumButterflyChromosome.SPECIES); + + drawLine(StringUtil.localize("gui.temptol"), COLUMN_0); + drawToleranceInfo(butterfly.getGenome().getToleranceTemp(), COLUMN_1, + getColorCoding(butterfly.getGenome().getActiveAllele(EnumButterflyChromosome.TEMPERATURE_TOLERANCE.ordinal()).isDominant())); + drawToleranceInfo(((AlleleTolerance) butterfly.getGenome().getInactiveAllele(EnumButterflyChromosome.TEMPERATURE_TOLERANCE.ordinal())).getValue(), COLUMN_2, + getColorCoding(butterfly.getGenome().getInactiveAllele(EnumButterflyChromosome.TEMPERATURE_TOLERANCE.ordinal()).isDominant())); + + newLine(); + + drawRow(StringUtil.localize("gui.humidity"), ClimateHelper.toDisplay(butterfly.getGenome().getPrimary().getHumidity()), + ClimateHelper.toDisplay(butterfly.getGenome().getPrimary().getHumidity()), butterfly, EnumButterflyChromosome.SPECIES); + + drawLine(StringUtil.localize("gui.humidtol"), COLUMN_0); + drawToleranceInfo(butterfly.getGenome().getToleranceHumid(), COLUMN_1, + getColorCoding(butterfly.getGenome().getActiveAllele(EnumButterflyChromosome.HUMIDITY_TOLERANCE.ordinal()).isDominant())); + drawToleranceInfo(((AlleleTolerance) butterfly.getGenome().getInactiveAllele(EnumButterflyChromosome.HUMIDITY_TOLERANCE.ordinal())).getValue(), COLUMN_2, + getColorCoding(butterfly.getGenome().getInactiveAllele(EnumButterflyChromosome.HUMIDITY_TOLERANCE.ordinal()).isDominant())); + + newLine(); + newLine(); + + String yes = StringUtil.localize("yes"); + String no = StringUtil.localize("no"); + + String diurnal0, diurnal1, nocturnal0, nocturnal1; + if(butterfly.getGenome().getNocturnal()) { + nocturnal0 = diurnal0 = yes; + } else { + nocturnal0 = butterfly.getGenome().getPrimary().isNocturnal() ? yes : no; + diurnal0 = !butterfly.getGenome().getPrimary().isNocturnal() ? yes : no; + } + if(((AlleleBoolean) butterfly.getGenome().getInactiveAllele(EnumButterflyChromosome.NOCTURNAL.ordinal())).getValue()) { + nocturnal1 = diurnal1 = yes; + } else { + nocturnal1 = butterfly.getGenome().getSecondary().isNocturnal() ? yes : no; + diurnal1 = !butterfly.getGenome().getSecondary().isNocturnal() ? yes : no; + } + + drawLine(StringUtil.localize("gui.diurnal"), COLUMN_0); + drawLine(diurnal0, COLUMN_1, getColorCoding(false)); + drawLine(diurnal1, COLUMN_2, getColorCoding(false)); + newLine(); + + drawLine(StringUtil.localize("gui.nocturnal"), COLUMN_0); + drawLine(nocturnal0, COLUMN_1, getColorCoding(false)); + drawLine(nocturnal1, COLUMN_2, getColorCoding(false)); + newLine(); + + String primary = StringUtil.readableBoolean(butterfly.getGenome().getTolerantFlyer(), yes, no); + String secondary = StringUtil.readableBoolean(((AlleleBoolean) butterfly.getGenome().getInactiveAllele(EnumButterflyChromosome.TOLERANT_FLYER.ordinal())).getValue(), yes, + no); + + drawRow(StringUtil.localize("gui.flyer"), primary, secondary, butterfly, EnumButterflyChromosome.TOLERANT_FLYER); + + primary = StringUtil.readableBoolean(butterfly.getGenome().getFireResist(), yes, no); + secondary = StringUtil.readableBoolean(((AlleleBoolean) butterfly.getGenome().getInactiveAllele(EnumButterflyChromosome.FIRE_RESIST.ordinal())).getValue(), yes, + no); + + drawRow(StringUtil.localize("gui.fireresist"), primary, secondary, butterfly, EnumButterflyChromosome.FIRE_RESIST); + + endPage(); + + } + private void drawAnalyticsPage3(IButterfly butterfly) { + + tempProductList = butterfly.getGenome().getPrimary().getButterflyLoot().keySet().toArray(StackUtils.EMPTY_STACK_ARRAY); + + startPage(COLUMN_0, COLUMN_1, COLUMN_2); + + drawLine(StringUtil.localize("gui.loot.butterfly") + ":", COLUMN_0); + newLine(); + + int x = COLUMN_0; + for (ItemStack stack : tempProductList) { + itemRender.renderItemIntoGUI(fontRendererObj, mc.renderEngine, stack, (int) ((guiLeft + x) * (1 / factor)), + (int) ((guiTop + getLineY()) * (1 / factor))); + x += 18; + if (x > adjustToFactor(148)) { + x = COLUMN_0; + newLine(); + } + } + + newLine(); + newLine(); + + drawLine(StringUtil.localize("gui.loot.caterpillar") + ":", COLUMN_0); + newLine(); + + x = COLUMN_0; + for (ItemStack stack : butterfly.getGenome().getPrimary().getCaterpillarLoot().keySet().toArray(StackUtils.EMPTY_STACK_ARRAY)) { + itemRender.renderItemIntoGUI(fontRendererObj, mc.renderEngine, stack, (int) ((guiLeft + x) * (1 / factor)), + (int) ((guiTop + getLineY()) * (1 / factor))); + x += 18; + if (x > adjustToFactor(148)) { + x = COLUMN_0; + newLine(); + } + } + + endPage(); + } + private void drawAnalyticsPage4(IButterfly butterfly) { + + startPage(COLUMN_0, COLUMN_1, COLUMN_2); + drawLine(StringUtil.localize("gui.beealyzer.mutations") + ":", COLUMN_0); + newLine(); + newLine(); + + RenderHelper.enableGUIStandardItemLighting(); + + HashMap combinations = new HashMap(); + + /* + for (IMutation mutation : TreeTemplates.getCombinations(butterfly.getGenome().getPrimary())) + combinations.put(mutation, butterfly.getGenome().getPrimary()); + + for (IMutation mutation : TreeTemplates.getCombinations(butterfly.getGenome().getSecondary())) + combinations.put(mutation, butterfly.getGenome().getSecondary()); + */ + + int columnWidth = 50; + int x = 0; + + for (Map.Entry mutation : combinations.entrySet()) { + + //if (breedingTracker.isDiscovered(mutation.getKey())) + drawMutationInfo(mutation.getKey(), mutation.getValue(), COLUMN_0 + x); + /*else { + // Do not display secret undiscovered mutations. + if (mutation.getKey().isSecret()) + continue; + + drawUnknownMutation(mutation.getKey(), mutation.getValue(), COLUMN_0 + x); + } */ + + x += columnWidth; + if (x > 150) { + x = 0; + newLine(); + newLine(); + } + } + + endPage(); + + } +} diff --git a/forestry_common/lepidopterology/forestry/lepidopterology/items/ItemButterflyGE.java b/forestry_common/lepidopterology/forestry/lepidopterology/items/ItemButterflyGE.java new file mode 100755 index 000000000..155736415 --- /dev/null +++ b/forestry_common/lepidopterology/forestry/lepidopterology/items/ItemButterflyGE.java @@ -0,0 +1,214 @@ +/******************************************************************************* + * Copyright 2011-2014 by SirSengir + * + * This work is licensed under a Creative Commons Attribution-NonCommercial-NoDerivs 3.0 Unported License. + * + * To view a copy of this license, visit http://creativecommons.org/licenses/by-nc-nd/3.0/. + ******************************************************************************/ +package forestry.lepidopterology.items; + +import java.util.List; + +import net.minecraft.client.renderer.texture.IIconRegister; +import net.minecraft.creativetab.CreativeTabs; +import net.minecraft.entity.item.EntityItem; +import net.minecraft.entity.player.EntityPlayer; +import net.minecraft.item.Item; +import net.minecraft.item.ItemStack; +import net.minecraft.tileentity.TileEntity; +import net.minecraft.util.IIcon; +import net.minecraft.world.World; + +import cpw.mods.fml.relauncher.Side; +import cpw.mods.fml.relauncher.SideOnly; + +import forestry.api.core.Tabs; +import forestry.api.genetics.AlleleManager; +import forestry.api.genetics.IAlleleSpecies; +import forestry.api.genetics.IIndividual; +import forestry.api.lepidopterology.EnumFlutterType; +import forestry.api.lepidopterology.IButterfly; +import forestry.api.lepidopterology.IButterflyNursery; +import forestry.core.config.Config; +import forestry.core.genetics.ItemGE; +import forestry.core.network.PacketFXSignal; +import forestry.core.proxy.Proxies; +import forestry.core.render.TextureManager; +import forestry.core.utils.Utils; +import forestry.lepidopterology.entities.EntityButterfly; +import forestry.plugins.PluginLepidopterology; + +public class ItemButterflyGE extends ItemGE { + + EnumFlutterType type; + + public ItemButterflyGE(EnumFlutterType type) { + super(); + setCreativeTab(Tabs.tabLepidopterology); + this.type = type; + } + + @Override + protected int getDefaultPrimaryColour() { + return 0; + } + + @Override + protected int getDefaultSecondaryColour() { + return 0; + } + + @Override + protected IIndividual getIndividual(ItemStack itemstack) { + return PluginLepidopterology.butterflyInterface.getMember(itemstack); + } + + @Override + public String getItemStackDisplayName(ItemStack itemstack) { + + if (itemstack.getTagCompound() == null) + return "???"; + + IButterfly butterfly = PluginLepidopterology.butterflyInterface.getMember(itemstack); + if(butterfly == null) + return "???"; + + return butterfly.getDisplayName(); + } + + @SuppressWarnings({ "rawtypes", "unchecked" }) + @Override + public void getSubItems(Item item, CreativeTabs par2CreativeTabs, List itemList) { + addCreativeItems(itemList, true); + } + + public void addCreativeItems(List itemList, boolean hideSecrets) { + + for (IIndividual individual : PluginLepidopterology.butterflyInterface.getIndividualTemplates()) { + // Don't show secret butterflies unless ordered to. + if (hideSecrets && individual.isSecret() && !Config.isDebug) + continue; + + itemList.add(PluginLepidopterology.butterflyInterface.getMemberStack(individual, type.ordinal())); + } + } + + @Override + public boolean onEntityItemUpdate(EntityItem entityItem) { + if(type != EnumFlutterType.BUTTERFLY) + return false; + if(!Proxies.common.isSimulating(entityItem.worldObj) || entityItem.ticksExisted < 80) + return false; + if(entityItem.worldObj.getTotalWorldTime() % 24 != 0) + return false; + + IButterfly butterfly = PluginLepidopterology.butterflyInterface.getMember(entityItem.getEntityItem()); + if(butterfly == null) + return false; + + if(!butterfly.canTakeFlight(entityItem.worldObj, entityItem.posX, entityItem.posY, entityItem.posZ)) + return false; + + if(entityItem.worldObj.countEntities(EntityButterfly.class) > PluginLepidopterology.entityConstraint) + return false; + + if(Utils.spawnEntity(entityItem.worldObj, new EntityButterfly(entityItem.worldObj, butterfly), entityItem.posX, entityItem.posY, entityItem.posZ) != null) { + if(entityItem.getEntityItem().stackSize > 1) + entityItem.getEntityItem().stackSize--; + else + entityItem.setDead(); + return true; + } + + return false; + } + + /* ICONS FOR SERUMS */ + @Override + public int getColorFromItemStack(ItemStack itemstack, int renderPass) { + if (!itemstack.hasTagCompound()) + return super.getColorFromItemStack(itemstack, renderPass); + + return getColourFromSpecies(AlleleManager.alleleRegistry.getIndividual(itemstack).getGenome().getPrimary(), renderPass); + } + + @Override + public int getColourFromSpecies(IAlleleSpecies species, int renderPass) { + if (species != null) + return species.getIconColour(renderPass); + else + return 0xffffff; + + } + + @Override + public boolean requiresMultipleRenderPasses() { + return true; + } + + @Override + public int getRenderPasses(int metadata) { + return 2; + } + + /* ICONS */ + @SideOnly(Side.CLIENT) + private IIcon[] icons; + + @SideOnly(Side.CLIENT) + @Override + public void registerIcons(IIconRegister register) { + icons = new IIcon[2]; + switch(this.type) { + case CATERPILLAR: + icons[0] = TextureManager.getInstance().registerTex(register, "caterpillar.body"); + icons[1] = TextureManager.getInstance().registerTex(register, "caterpillar.body2"); + break; + default: + icons[0] = TextureManager.getInstance().registerTex(register, "liquids/jar.contents"); + icons[1] = TextureManager.getInstance().registerTex(register, "liquids/jar.bottle"); + } + } + + @SideOnly(Side.CLIENT) + @Override + public IIcon getIconFromDamageForRenderPass(int i, int j) { + if (j > 0) + return icons[1]; + else + return icons[0]; + } + + @Override + public boolean onItemUse(ItemStack itemstack, EntityPlayer player, World world, int x, int y, int z, int par7, float facingX, float facingY, float facingZ) { + + if (!Proxies.common.isSimulating(world)) + return false; + + IButterfly flutter = PluginLepidopterology.butterflyInterface.getMember(itemstack); + if(flutter == null) + return false; + + if(type == EnumFlutterType.CATERPILLAR) { + + TileEntity target = world.getTileEntity(x, y, z); + if(!(target instanceof IButterflyNursery)) + return false; + + IButterflyNursery pollinatable = (IButterflyNursery)target; + if(!pollinatable.canNurse(flutter)) + return false; + + pollinatable.setCaterpillar(flutter); + Proxies.common.sendFXSignal(PacketFXSignal.VisualFXType.BLOCK_DESTROY, PacketFXSignal.SoundFXType.LEAF, world, x, y, z, + world.getBlock(x, y, z), 0); + if (!player.capabilities.isCreativeMode) + itemstack.stackSize--; + return true; + + } else + return false; + } + + +} diff --git a/forestry_common/lepidopterology/forestry/lepidopterology/items/ItemFlutterlyzer.java b/forestry_common/lepidopterology/forestry/lepidopterology/items/ItemFlutterlyzer.java new file mode 100755 index 000000000..5bbab580a --- /dev/null +++ b/forestry_common/lepidopterology/forestry/lepidopterology/items/ItemFlutterlyzer.java @@ -0,0 +1,162 @@ +/******************************************************************************* + * Copyright 2011-2014 by SirSengir + * + * This work is licensed under a Creative Commons Attribution-NonCommercial-NoDerivs 3.0 Unported License. + * + * To view a copy of this license, visit http://creativecommons.org/licenses/by-nc-nd/3.0/. + ******************************************************************************/ +package forestry.lepidopterology.items; + +import net.minecraft.entity.player.EntityPlayer; +import net.minecraft.item.ItemStack; +import net.minecraft.nbt.NBTTagCompound; +import net.minecraft.nbt.NBTTagList; +import net.minecraft.world.World; + +import forestry.api.core.ForestryAPI; +import forestry.api.core.Tabs; +import forestry.api.lepidopterology.IButterfly; +import forestry.core.EnumErrorCode; +import forestry.core.config.Config; +import forestry.core.config.ForestryItem; +import forestry.core.interfaces.IErrorSource; +import forestry.core.interfaces.IHintSource; +import forestry.core.items.ItemInventoried; +import forestry.core.network.GuiId; +import forestry.core.proxy.Proxies; +import forestry.core.utils.ItemInventory; +import forestry.plugins.PluginLepidopterology; + +public class ItemFlutterlyzer extends ItemInventoried { + + public static class FlutterlyzerInventory extends ItemInventory implements IErrorSource, IHintSource { + + public final static int SLOT_SPECIMEN = 0; + public final static int SLOT_ANALYZE_1 = 1; + public final static int SLOT_ANALYZE_2 = 2; + public final static int SLOT_ANALYZE_3 = 3; + public final static int SLOT_ANALYZE_4 = 4; + public final static int SLOT_ANALYZE_5 = 6; + public final static int SLOT_ENERGY = 5; + EntityPlayer player; + + public FlutterlyzerInventory(EntityPlayer player) { + super(ItemFlutterlyzer.class, 7); + this.player = player; + } + + public FlutterlyzerInventory(EntityPlayer player, ItemStack itemStack) { + super(ItemFlutterlyzer.class, 7, itemStack); + this.player = player; + } + + @Override + public void writeToNBT(NBTTagCompound nbttagcompound) { + + NBTTagList nbttaglist = new NBTTagList(); + for (int i = SLOT_ENERGY; i < SLOT_ENERGY + 1; i++) { + if (inventoryStacks[i] != null) { + NBTTagCompound nbttagcompound1 = new NBTTagCompound(); + nbttagcompound1.setByte("Slot", (byte) i); + inventoryStacks[i].writeToNBT(nbttagcompound1); + nbttaglist.appendTag(nbttagcompound1); + } + } + nbttagcompound.setTag("Items", nbttaglist); + + } + + private boolean isEnergy(ItemStack itemstack) { + if (itemstack == null || itemstack.stackSize <= 0) + return false; + + return ForestryItem.honeyDrop.isItemEqual(itemstack) || ForestryItem.honeydew.isItemEqual(itemstack); + } + + private void tryAnalyze() { + + // Analyzed slot occupied, abort + if (inventoryStacks[SLOT_ANALYZE_1] != null || inventoryStacks[SLOT_ANALYZE_2] != null || inventoryStacks[SLOT_ANALYZE_3] != null + || inventoryStacks[SLOT_ANALYZE_4] != null || inventoryStacks[SLOT_ANALYZE_5] != null) + return; + + // Source slot to analyze empty + if (getStackInSlot(SLOT_SPECIMEN) == null) + return; + + IButterfly butterfly = PluginLepidopterology.butterflyInterface.getMember(getStackInSlot(SLOT_SPECIMEN)); + // No tree, abort + if (butterfly == null) { + return; + } + + // Analyze if necessary + if (!butterfly.isAnalyzed()) { + + // Requires energy + if (!isEnergy(getStackInSlot(SLOT_ENERGY))) + return; + + butterfly.analyze(); + if (player != null) { + PluginLepidopterology.butterflyInterface.getBreedingTracker(player.worldObj, player.getGameProfile().getId()).registerSpecies(butterfly.getGenome().getPrimary()); + PluginLepidopterology.butterflyInterface.getBreedingTracker(player.worldObj, player.getGameProfile().getId()).registerSpecies(butterfly.getGenome().getSecondary()); + } + NBTTagCompound nbttagcompound = new NBTTagCompound(); + butterfly.writeToNBT(nbttagcompound); + getStackInSlot(SLOT_SPECIMEN).setTagCompound(nbttagcompound); + + // Decrease energy + decrStackSize(SLOT_ENERGY, 1); + } + + setInventorySlotContents(SLOT_ANALYZE_1, getStackInSlot(SLOT_SPECIMEN)); + setInventorySlotContents(SLOT_SPECIMEN, null); + } + + @Override + public void markDirty() { + tryAnalyze(); + } + + /* IHINTSOURCE */ + @Override + public boolean hasHints() { + return Config.hints.get("flutterlyzer") != null && Config.hints.get("flutterlyzer").length > 0; + } + + @Override + public String[] getHints() { + return Config.hints.get("flutterlyzer"); + } + + /* IERRORSOURCE */ + @Override + public boolean throwsErrors() { + return true; + } + + @Override + public EnumErrorCode getErrorState() { + if (PluginLepidopterology.butterflyInterface.isMember(inventoryStacks[SLOT_SPECIMEN]) && !isEnergy(getStackInSlot(SLOT_ENERGY))) + return EnumErrorCode.NOHONEY; + + return EnumErrorCode.OK; + } + } + + public ItemFlutterlyzer() { + super(); + setMaxStackSize(1); + setCreativeTab(Tabs.tabLepidopterology); + } + + @Override + public ItemStack onItemRightClick(ItemStack itemstack, World world, EntityPlayer entityplayer) { + if (Proxies.common.isSimulating(world)) + entityplayer.openGui(ForestryAPI.instance, GuiId.FlutterlyzerGUI.ordinal(), world, (int) entityplayer.posX, (int) entityplayer.posY, + (int) entityplayer.posZ); + + return itemstack; + } +} diff --git a/forestry_common/lepidopterology/forestry/lepidopterology/proxy/ClientProxyLepidopterology.java b/forestry_common/lepidopterology/forestry/lepidopterology/proxy/ClientProxyLepidopterology.java new file mode 100755 index 000000000..ad039ab06 --- /dev/null +++ b/forestry_common/lepidopterology/forestry/lepidopterology/proxy/ClientProxyLepidopterology.java @@ -0,0 +1,33 @@ +/******************************************************************************* + * Copyright 2011-2014 by SirSengir + * + * This work is licensed under a Creative Commons Attribution-NonCommercial-NoDerivs 3.0 Unported License. + * + * To view a copy of this license, visit http://creativecommons.org/licenses/by-nc-nd/3.0/. + ******************************************************************************/ +package forestry.lepidopterology.proxy; + +import cpw.mods.fml.client.registry.RenderingRegistry; + +import net.minecraftforge.client.MinecraftForgeClient; + +import forestry.core.config.ForestryItem; +import forestry.core.utils.Localization; +import forestry.lepidopterology.entities.EntityButterfly; +import forestry.lepidopterology.render.ButterflyItemRenderer; +import forestry.lepidopterology.render.RenderButterfly; + +public class ClientProxyLepidopterology extends ProxyLepidopterology { + + @Override + public void initializeRendering() { + RenderingRegistry.registerEntityRenderingHandler(EntityButterfly.class, new RenderButterfly()); + MinecraftForgeClient.registerItemRenderer(ForestryItem.butterflyGE.item(), new ButterflyItemRenderer()); + } + + @Override + public void addLocalizations() { + Localization.instance.addLocalization("/lang/forestry/lepidopterology/"); + } + +} diff --git a/forestry_common/lepidopterology/forestry/lepidopterology/proxy/ProxyLepidopterology.java b/forestry_common/lepidopterology/forestry/lepidopterology/proxy/ProxyLepidopterology.java new file mode 100755 index 000000000..9279faa5a --- /dev/null +++ b/forestry_common/lepidopterology/forestry/lepidopterology/proxy/ProxyLepidopterology.java @@ -0,0 +1,18 @@ +/******************************************************************************* + * Copyright 2011-2014 by SirSengir + * + * This work is licensed under a Creative Commons Attribution-NonCommercial-NoDerivs 3.0 Unported License. + * + * To view a copy of this license, visit http://creativecommons.org/licenses/by-nc-nd/3.0/. + ******************************************************************************/ +package forestry.lepidopterology.proxy; + +public class ProxyLepidopterology { + + public void initializeRendering() { + } + + public void addLocalizations() { + } + +} diff --git a/forestry_common/lepidopterology/forestry/lepidopterology/render/ButterflyItemRenderer.java b/forestry_common/lepidopterology/forestry/lepidopterology/render/ButterflyItemRenderer.java new file mode 100755 index 000000000..06ba00ba9 --- /dev/null +++ b/forestry_common/lepidopterology/forestry/lepidopterology/render/ButterflyItemRenderer.java @@ -0,0 +1,223 @@ +/******************************************************************************* + * Copyright 2011-2014 by SirSengir + * + * This work is licensed under a Creative Commons Attribution-NonCommercial-NoDerivs 3.0 Unported License. + * + * To view a copy of this license, visit http://creativecommons.org/licenses/by-nc-nd/3.0/. + ******************************************************************************/ +package forestry.lepidopterology.render; + +import net.minecraft.client.renderer.OpenGlHelper; +import net.minecraft.client.renderer.RenderHelper; +import net.minecraft.client.renderer.entity.RenderItem; +import net.minecraft.client.renderer.entity.RenderManager; +import net.minecraft.item.ItemStack; + +import net.minecraftforge.client.IItemRenderer; + +import org.lwjgl.opengl.GL11; +import org.lwjgl.opengl.GL12; + +import forestry.api.lepidopterology.IButterfly; +import forestry.core.proxy.Proxies; +import forestry.lepidopterology.entities.EntityButterfly; +import forestry.plugins.PluginLepidopterology; + +public class ButterflyItemRenderer implements IItemRenderer { + + ModelButterfly model; + EntityButterfly entity; + + public ButterflyItemRenderer() { + model = new ModelButterfly(); + } + + private static float getWingYaw(IButterfly butterfly) { + float wingYaw = 1f; + + if(butterfly.isAlive()) { + long systemTime = System.currentTimeMillis(); + long flapping = systemTime + butterfly.getIdent().hashCode(); + float flap = (float) (flapping % 1000) / 1000; // 0 to 1 + + wingYaw = getIrregularWingYaw(flapping, flap); + + } + + return wingYaw; + } + + public static float getIrregularWingYaw(long flapping, float flap) { + long irregular = (long)(flapping / 1000); + float wingYaw = 1f; + + if(irregular % 11 == 0) { + wingYaw = 0.75f; + } else { + if(irregular % 7 == 0) { + flap *= 4; + flap = flap % 1; + } else if(irregular % 19 == 0) { + flap *= 6; + flap = flap % 1; + } + wingYaw = getRegularWingYaw(flap); + } + + return wingYaw; + } + + public static float getRegularWingYaw(float flap) { + return flap < 0.5 ? 0.75f + flap : 1.75f - flap; + } + + private IButterfly initButterfly(ItemStack item, boolean scaled) { + IButterfly butterfly = PluginLepidopterology.butterflyInterface.getMember(item); + if(butterfly == null) + butterfly = PluginLepidopterology.butterflyInterface.templateAsIndividual(PluginLepidopterology.butterflyInterface.getDefaultTemplate()); + + if(entity == null) { + entity = new EntityButterfly(Proxies.common.getClientInstance().theWorld); + } + entity.setSpecies(butterfly.getGenome().getPrimary()); + if(scaled) + entity.setScale(butterfly.getSize()); + else + entity.setScale(EntityButterfly.DEFAULT_BUTTERFLY_SCALE); + + return butterfly; + } + + private void renderButterflyItem(IButterfly butterfly, float translateX, float translateY, float translateZ) { + float yaw = 1; + float pitch = 1; + + GL11.glPushAttrib(GL11.GL_ENABLE_BIT); + GL11.glEnable(GL11.GL_LIGHTING); + GL11.glEnable(GL11.GL_DEPTH_TEST); + GL11.glEnable(GL11.GL_COLOR_MATERIAL); + + GL11.glPushMatrix(); + + if(RenderItem.renderInFrame) { + //GL11.glScalef(-2.0f, 2.0f, 2.0f); + GL11.glColor4f(1.0F, 1.0F, 1.0F, 1.0F); + GL11.glRotatef(-90.0F, 0.0F, 1.0F, 0.0F); + GL11.glRotatef(-90.0F, 1.0F, 0.0F, 0.0F); + GL11.glScalef(1.1f, 1f, 1f); + + GL11.glTranslatef(0, -0.7f, 0.2f); + + entity.renderYawOffset = 0; + entity.rotationYaw = 0; + entity.rotationPitch = 0; + entity.rotationYawHead = entity.rotationYaw; + + RenderManager.instance.renderEntityWithPosYaw(entity, 0.0D, 0.0D, 0.0D, 0.0F, 1.0f); + + } else { + GL11.glTranslatef(translateX, translateY, translateZ); + + GL11.glScalef(-2.0f, 2.0f, 2.0f); + GL11.glColor4f(1.0F, 1.0F, 1.0F, 1.0F); + GL11.glRotatef(-135.0F, 0.0F, 1.0F, 0.0F); + GL11.glRotatef(-((float) Math.atan((double) (pitch / 40.0F))) * 20.0F, 1.0F, 0.0F, 0.0F); + + entity.renderYawOffset = (float) Math.atan((double) (yaw / 40.0F)) * 20.0F; + entity.rotationYaw = (float) Math.atan((double) (yaw / 40.0F)) * 40.0F; + entity.rotationPitch = -((float) Math.atan((double) (pitch / 40.0F))) * 20.0F; + entity.rotationYawHead = entity.rotationYaw; + + RenderManager.instance.renderEntityWithPosYaw(entity, 0.0D, 0.0D, 0.0D, 0.0F, getWingYaw(butterfly)); + + } + + GL11.glPopMatrix(); + + RenderHelper.disableStandardItemLighting(); + GL11.glDisable(GL12.GL_RESCALE_NORMAL); + OpenGlHelper.setActiveTexture(OpenGlHelper.lightmapTexUnit); + GL11.glDisable(GL11.GL_TEXTURE_2D); + OpenGlHelper.setActiveTexture(OpenGlHelper.defaultTexUnit); + GL11.glPopAttrib(); + + } + + private void renderButterflyInInventory(IButterfly butterfly) { + + GL11.glPushAttrib(GL11.GL_ENABLE_BIT); + GL11.glEnable(GL11.GL_LIGHTING); + GL11.glEnable(GL11.GL_DEPTH_TEST); + GL11.glEnable(GL11.GL_COLOR_MATERIAL); + RenderHelper.enableStandardItemLighting(); + GL11.glPushMatrix(); + + GL11.glTranslatef(0f, -0.75f, 0f); + GL11.glScalef(-2.0f, 2.0f, 2.0f); + GL11.glColor4f(1.0F, 1.0F, 1.0F, 1.0F); + GL11.glRotatef(135.0F, 0.0F, 1.0F, 0.0F); + GL11.glRotatef(-35.0F, 1.0F, 0.0F, 0.0F); + GL11.glScalef(1.1f, 1f, 1f); + + entity.renderYawOffset = 0; + entity.rotationYaw = 0; + entity.rotationPitch = 0; + entity.rotationYawHead = entity.rotationYaw; + + RenderManager.instance.renderEntityWithPosYaw(entity, 0.0D, 0.0D, 0.0D, 0.0F, getWingYaw(butterfly)); + + GL11.glPopMatrix(); + RenderHelper.disableStandardItemLighting(); + GL11.glDisable(GL12.GL_RESCALE_NORMAL); + OpenGlHelper.setActiveTexture(OpenGlHelper.lightmapTexUnit); + GL11.glDisable(GL11.GL_TEXTURE_2D); + OpenGlHelper.setActiveTexture(OpenGlHelper.defaultTexUnit); + GL11.glPopAttrib(); + + } + + @Override + public boolean handleRenderType(ItemStack item, ItemRenderType type) { + switch (type) { + case ENTITY: + case EQUIPPED: + case EQUIPPED_FIRST_PERSON: + case INVENTORY: + return true; + default: + return false; + } + } + + @Override + public boolean shouldUseRenderHelper(ItemRenderType type, ItemStack item, ItemRendererHelper helper) { + switch(helper) { + case ENTITY_BOBBING: + case ENTITY_ROTATION: + return false; + default: + return true; + } + } + + @Override + public void renderItem(ItemRenderType type, ItemStack item, Object... data) { + + switch (type) { + case ENTITY: + renderButterflyItem(initButterfly(item, true), 0f, -1.0f, 0f); + break; + case EQUIPPED: + renderButterflyItem(initButterfly(item, true), 0.5f, -0.9f, 1.0f); + break; + case EQUIPPED_FIRST_PERSON: + renderButterflyItem(initButterfly(item, true), 0.5f, -0.9f, 1.0f); + break; + case INVENTORY: + renderButterflyInInventory(initButterfly(item, false)); + break; + default: + } + } + +} diff --git a/forestry_common/lepidopterology/forestry/lepidopterology/render/ModelButterfly.java b/forestry_common/lepidopterology/forestry/lepidopterology/render/ModelButterfly.java new file mode 100755 index 000000000..9e1b01c86 --- /dev/null +++ b/forestry_common/lepidopterology/forestry/lepidopterology/render/ModelButterfly.java @@ -0,0 +1,99 @@ +/******************************************************************************* + * Copyright 2011-2014 by SirSengir + * + * This work is licensed under a Creative Commons Attribution-NonCommercial-NoDerivs 3.0 Unported License. + * + * To view a copy of this license, visit http://creativecommons.org/licenses/by-nc-nd/3.0/. + ******************************************************************************/ +package forestry.lepidopterology.render; + +import net.minecraft.client.model.ModelBase; +import net.minecraft.client.model.ModelRenderer; +import net.minecraft.entity.Entity; +import net.minecraft.util.MathHelper; + +import org.lwjgl.opengl.GL11; + +public class ModelButterfly extends ModelBase { + + ModelRenderer wingRight; + ModelRenderer eyeRight; + ModelRenderer eyeLeft; + ModelRenderer wingLeft; + ModelRenderer body; + + private float scale; + + public ModelButterfly() { + textureWidth = 64; + textureHeight = 32; + + wingRight = new ModelRenderer(this, 0, 0); + wingRight.addBox(-7F, 0F, -6F, 7, 1, 13); + wingRight.setRotationPoint(-0.5F, 0.5F, 0F); + wingRight.setTextureSize(64, 32); + wingRight.mirror = true; + setRotation(wingRight, 0F, 0F, 0F); + eyeRight = new ModelRenderer(this, 40, 9); + eyeRight.addBox(0F, 0F, 0F, 1, 1, 1); + eyeRight.setRotationPoint(-1.1F, -0.5F, -4.5F); + eyeRight.setTextureSize(64, 32); + eyeRight.mirror = true; + setRotation(eyeRight, 0F, 0F, 0F); + eyeLeft = new ModelRenderer(this, 40, 7); + eyeLeft.addBox(0F, 0F, 0F, 1, 1, 1); + eyeLeft.setRotationPoint(0.1F, -0.5F, -4.5F); + eyeLeft.setTextureSize(64, 32); + eyeLeft.mirror = true; + setRotation(eyeLeft, 0F, 0F, 0F); + wingLeft = new ModelRenderer(this, 0, 14); + wingLeft.addBox(0F, 0F, -6F, 7, 1, 13); + wingLeft.setRotationPoint(0.5F, 0.5F, 0F); + wingLeft.setTextureSize(64, 32); + wingLeft.mirror = true; + setRotation(wingLeft, 0F, 0F, 0F); + body = new ModelRenderer(this, 40, 0); + body.addBox(0F, 0F, -4F, 1, 1, 6); + body.setRotationPoint(0F, 0F, 0F); + body.setTextureSize(64, 32); + body.mirror = true; + setRotation(body, 0F, 0F, 0.7853982F); + } + + public void setScale(float scale) { + this.scale = scale; + } + + @Override + public void render(Entity entity, float f, float f1, float swing, float f3, float f4, float f5) { + super.render(entity, f, f1, swing, f3, f4, f5); + + //body.rotateAngleX = ((float)Math.PI / 4F) + MathHelper.cos(swing * 0.1F) * 0.15F; + //body.rotateAngleY = 0.0F; + wingRight.rotateAngleZ = MathHelper.cos(swing * 1.3F) * (float)Math.PI * 0.25F; + wingLeft.rotateAngleZ = -wingRight.rotateAngleZ; + + GL11.glPushMatrix(); + GL11.glScalef(scale, scale, scale); + GL11.glTranslatef(0.0F, (12.0f / scale) * f5, 0.0F); + wingRight.render(f5); + eyeRight.render(f5); + eyeLeft.render(f5); + wingLeft.render(f5); + body.render(f5); + GL11.glPopMatrix(); + + } + + private void setRotation(ModelRenderer model, float x, float y, float z) { + model.rotateAngleX = x; + model.rotateAngleY = y; + model.rotateAngleZ = z; + } + + @Override + 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); + } + +} diff --git a/forestry_common/lepidopterology/forestry/lepidopterology/render/RenderButterfly.java b/forestry_common/lepidopterology/forestry/lepidopterology/render/RenderButterfly.java new file mode 100755 index 000000000..0b9eda596 --- /dev/null +++ b/forestry_common/lepidopterology/forestry/lepidopterology/render/RenderButterfly.java @@ -0,0 +1,43 @@ +/******************************************************************************* + * Copyright 2011-2014 by SirSengir + * + * This work is licensed under a Creative Commons Attribution-NonCommercial-NoDerivs 3.0 Unported License. + * + * To view a copy of this license, visit http://creativecommons.org/licenses/by-nc-nd/3.0/. + ******************************************************************************/ +package forestry.lepidopterology.render; + +import net.minecraft.client.renderer.entity.RenderLiving; +import net.minecraft.entity.Entity; +import net.minecraft.util.ResourceLocation; + +import forestry.lepidopterology.entities.EntityButterfly; + +public class RenderButterfly extends RenderLiving { + + ModelButterfly butterflyModel; + + public RenderButterfly() { + super(new ModelButterfly(), 0.25f); + butterflyModel = (ModelButterfly)mainModel; + } + + public void renderButterfly(EntityButterfly entity, double x, double y, double z, float par8, float par9) { + if(!entity.isRenderable()) + return; + + butterflyModel.setScale(entity.getScale()); + super.doRender(entity, x, y, z, par8, entity.getWingFlap(par9)); + } + + @Override + public void doRender(Entity entity, double x, double y, double z, float par8, float par9) { + this.renderButterfly((EntityButterfly)entity, x, y, z, par8, par9); + } + + @Override + protected ResourceLocation getEntityTexture(Entity entity) { + return ((EntityButterfly)entity).getTexture(); + } + +} diff --git a/forestry_common/lepidopterology/forestry/plugins/PluginLepidopterology.java b/forestry_common/lepidopterology/forestry/plugins/PluginLepidopterology.java new file mode 100755 index 000000000..a4a4a39ff --- /dev/null +++ b/forestry_common/lepidopterology/forestry/plugins/PluginLepidopterology.java @@ -0,0 +1,325 @@ +/******************************************************************************* + * Copyright 2011-2014 by SirSengir + * + * This work is licensed under a Creative Commons Attribution-NonCommercial-NoDerivs 3.0 Unported License. + * + * To view a copy of this license, visit http://creativecommons.org/licenses/by-nc-nd/3.0/. + ******************************************************************************/ +package forestry.plugins; + +import java.util.Locale; + +import net.minecraft.block.material.Material; +import net.minecraft.init.Blocks; +import net.minecraft.init.Items; +import net.minecraft.item.ItemStack; +import net.minecraft.item.crafting.CraftingManager; + +import cpw.mods.fml.common.SidedProxy; +import cpw.mods.fml.common.network.IGuiHandler; + +import forestry.api.arboriculture.ITreeRoot; +import forestry.api.core.EnumHumidity; +import forestry.api.core.EnumTemperature; +import forestry.api.core.PluginInfo; +import forestry.api.core.Tabs; +import forestry.api.genetics.AlleleManager; +import forestry.api.genetics.IClassification; +import forestry.api.genetics.IClassification.EnumClassLevel; +import forestry.api.lepidopterology.EnumFlutterType; +import forestry.api.lepidopterology.IButterflyRoot; +import forestry.api.recipes.RecipeManagers; +import forestry.core.config.Configuration; +import forestry.core.config.Defaults; +import forestry.core.config.ForestryBlock; +import forestry.core.config.ForestryItem; +import forestry.core.config.Property; +import forestry.core.gadgets.BlockBase; +import forestry.core.gadgets.MachineDefinition; +import forestry.core.genetics.Allele; +import forestry.core.genetics.Branch; +import forestry.core.items.ItemForestryBlock; +import forestry.core.proxy.Proxies; +import forestry.core.utils.LiquidHelper; +import forestry.core.utils.ShapedRecipeCustom; +import forestry.core.utils.Utils; +import forestry.lepidopterology.ButterflySpawner; +import forestry.lepidopterology.GuiHandlerLepidopterology; +import forestry.lepidopterology.MatingRecipe; +import forestry.lepidopterology.entities.EntityButterfly; +import forestry.lepidopterology.gadgets.TileLepidopteristChest; +import forestry.lepidopterology.genetics.AlleleButterflySpecies; +import forestry.lepidopterology.genetics.AlleleEffectNone; +import forestry.lepidopterology.genetics.ButterflyHelper; +import forestry.lepidopterology.genetics.ButterflyTemplates; +import forestry.lepidopterology.items.ItemButterflyGE; +import forestry.lepidopterology.items.ItemFlutterlyzer; +import forestry.lepidopterology.proxy.ProxyLepidopterology; + +@PluginInfo(pluginID = "Lepidopterology", name = "Lepidopterology", author = "SirSengir", url = Defaults.URL, description = "Butterflies. Shiny.") +public class PluginLepidopterology extends NativePlugin { + + @SidedProxy(clientSide = "forestry.lepidopterology.proxy.ClientProxyLepidopterology", serverSide = "forestry.lepidopterology.proxy.ProxyLepidopterology") + public static ProxyLepidopterology proxy; + private static final String CONFIG_CATEGORY = "lepidopterology"; + private Configuration config; + public static int spawnConstraint = 100; + public static int entityConstraint = 1000; + public static IClassification geometridae; + public static IClassification saturniidae; + public static IClassification pieridae; + public static IClassification nymphalidae; + public static IClassification lycaenidae; + public static IClassification papilionidae; + public static IClassification notchidae; + /** + * See {@link IButterflyRoot} for details. + */ + public static IButterflyRoot butterflyInterface; + public static MachineDefinition definitionChest; + + @Override + public boolean isAvailable() { + return true; + } + + @Override + public void preInit() { + super.preInit(); + + proxy.addLocalizations(); + + ForestryBlock.lepidopterology = new BlockBase(Material.iron); + ForestryBlock.lepidopterology.setBlockName("for.lepidopterology").setCreativeTab(Tabs.tabLepidopterology); + Proxies.common.registerBlock(ForestryBlock.lepidopterology, ItemForestryBlock.class); + + definitionChest = ForestryBlock.lepidopterology.addDefinition((new MachineDefinition(Defaults.DEFINITION_LEPICHEST_META, "forestry.LepiChest", TileLepidopteristChest.class, + ShapedRecipeCustom.createShapedRecipe(new ItemStack(ForestryBlock.lepidopterology, 1, Defaults.DEFINITION_LEPICHEST_META), new Object[] { " # ", "XYX", "XXX", Character.valueOf('#'), Blocks.glass, Character.valueOf('X'), + ForestryItem.butterflyGE.getItemStack(1, Defaults.WILDCARD), Character.valueOf('Y'), Blocks.chest })) + .setFaces(0, 1, 2, 3, 4, 4, 0, 7))); + + + AlleleManager.alleleRegistry.registerSpeciesRoot(PluginLepidopterology.butterflyInterface = new ButterflyHelper()); + createAlleles(); + } + + @Override + public void doInit() { + super.doInit(); + + config = new Configuration(); + + Property property = config.get("entities.spawn.limit", CONFIG_CATEGORY, spawnConstraint); + property.Comment = "determines the global butterfly entity count above which natural spawning of butterflies ceases."; + spawnConstraint = Integer.parseInt(property.Value); + + property = config.get("entities.maximum.allowed", CONFIG_CATEGORY, entityConstraint); + property.Comment = "determines the global butterfly entity count above which butterflies will stay in item form and will not take flight anymore."; + entityConstraint = Integer.parseInt(property.Value); + + config.save(); + + Utils.registerEntity(EntityButterfly.class, "butterflyGE", 0, 0x000000, 0xffffff, 50, 1, true); + proxy.initializeRendering(); + registerTemplates(); + + definitionChest.register(); + + ((ITreeRoot) AlleleManager.alleleRegistry.getSpeciesRoot("rootTrees")).registerLeafTickHandler(new ButterflySpawner()); + } + + @Override + protected void registerItems() { + ForestryItem.flutterlyzer.registerItem(new ItemFlutterlyzer(), "flutterlyzer"); + ForestryItem.butterflyGE.registerItem(new ItemButterflyGE(EnumFlutterType.BUTTERFLY), "butterflyGE"); + ForestryItem.serumGE.registerItem(new ItemButterflyGE(EnumFlutterType.SERUM), "serumGE"); + ForestryItem.caterpillarGE.registerItem(new ItemButterflyGE(EnumFlutterType.CATERPILLAR), "caterpillarGE"); + } + + @Override + protected void registerBackpackItems() { + } + + @Override + protected void registerCrates() { + } + + @SuppressWarnings("unchecked") + @Override + protected void registerRecipes() { + CraftingManager.getInstance().getRecipeList().add(new MatingRecipe()); + + RecipeManagers.carpenterManager.addRecipe(100, LiquidHelper.getLiquid(Defaults.LIQUID_WATER, 2000), null, ForestryItem.flutterlyzer.getItemStack(), + new Object[] { "X#X", "X#X", "RDR", Character.valueOf('#'), Blocks.glass_pane, Character.valueOf('X'), "ingotBronze", Character.valueOf('R'), + Items.redstone, Character.valueOf('D'), Items.diamond }); + } + + private void createAlleles() { + + IClassification lepidoptera = AlleleManager.alleleRegistry.createAndRegisterClassification(EnumClassLevel.ORDER, "lepidoptera", "Lepidoptera"); + AlleleManager.alleleRegistry.getClassification("class.insecta").addMemberGroup(lepidoptera); + + geometridae = AlleleManager.alleleRegistry.createAndRegisterClassification(EnumClassLevel.FAMILY, "geometridae", "Geometridae"); + lepidoptera.addMemberGroup(geometridae); + saturniidae = AlleleManager.alleleRegistry.createAndRegisterClassification(EnumClassLevel.FAMILY, "saturniidae", "Saturniidae"); + lepidoptera.addMemberGroup(saturniidae); + + pieridae = AlleleManager.alleleRegistry.createAndRegisterClassification(EnumClassLevel.FAMILY, "pieridae", "Pieridae"); + lepidoptera.addMemberGroup(pieridae); + nymphalidae = AlleleManager.alleleRegistry.createAndRegisterClassification(EnumClassLevel.FAMILY, "nymphalidae", "Nymphalidae"); + lepidoptera.addMemberGroup(nymphalidae); + lycaenidae = AlleleManager.alleleRegistry.createAndRegisterClassification(EnumClassLevel.FAMILY, "lycaenidae", "Lycaenidae"); + lepidoptera.addMemberGroup(lycaenidae); + papilionidae = AlleleManager.alleleRegistry.createAndRegisterClassification(EnumClassLevel.FAMILY, "papilionidae", "Papilionidae"); + lepidoptera.addMemberGroup(papilionidae); + notchidae = AlleleManager.alleleRegistry.createAndRegisterClassification(EnumClassLevel.FAMILY, "notchidae", "Notchidae"); + lepidoptera.addMemberGroup(notchidae); + + /* GEOMETRIDAE */ + IClassification opisthograptis = createButterflyBranch(geometridae, "Opisthograptis"); + IClassification chiasmia = createButterflyBranch(geometridae, "Chiasmia"); + + Allele.mothBrimstone = new AlleleButterflySpecies("mothBrimstone", true, "Brimstone", opisthograptis, "luteolata", 0xffea40).setNocturnal(true).setRarity(1.0f); + Allele.mothLatticedHeath = new AlleleButterflySpecies("mothLatticedHeath", true, "Latticed Heath", chiasmia, "clathrata", 0xf2f0be).setNocturnal(true).setRarity(0.5f); + + /* SATURNIIDAE */ + IClassification attacus = createButterflyBranch(saturniidae, "Attacus"); + + Allele.mothAtlas = new AlleleButterflySpecies("mothAtlas", false, "Atlas", attacus, "atlas", 0xd96e3d).setNocturnal(true); + + /* PIERIDAE */ + IClassification pieris = createButterflyBranch(pieridae, "Pieris"); + IClassification gonepteryx = createButterflyBranch(pieridae, "Gonepteryx"); + IClassification anthocharis = createButterflyBranch(pieridae, "Anthocharis"); + IClassification colias = createButterflyBranch(pieridae, "Colias"); + IClassification pontia = createButterflyBranch(pieridae, "Pontia"); + IClassification celastrina = createButterflyBranch(pieridae, "Celastrina"); + + Allele.lepiCabbageWhite = new AlleleButterflySpecies("lepiCabbageWhite", true, "Cabbage White", pieris, "rapae", 0xccffee).setRarity(1.0f); + Allele.lepiBrimstone = new AlleleButterflySpecies("lepiBrimstone", true, "Brimstone", gonepteryx, "rhamni", 0xf0ee38).setRarity(1.0f); + Allele.lepiAurora = new AlleleButterflySpecies("lepiAurora", true, "Orange Tip", anthocharis, "cardamines", 0xe34f05).setRarity(0.5f); + Allele.lepiPostillion = new AlleleButterflySpecies("lepiPostillion", true, "Postillion", colias, "croceus", 0xd77e04).setRarity(0.5f); + Allele.lepiPalaenoSulphur = new AlleleButterflySpecies("lepiPalaenoSulphur", true, "Palaeno Sulphur", colias, "palaeno", 0xf8fba3).setRarity(0.4f); + Allele.lepiReseda = new AlleleButterflySpecies("lepiReseda", true, "Reseda", pontia, "edusa", 0x747d48).setRarity(0.3f); + + Allele.lepiSpringAzure = new AlleleButterflySpecies("lepiSpringAzure", true, "Spring Azure", celastrina, "argiolus", 0xb8cae2).setRarity(0.3f); + Allele.lepiGozoraAzure = new AlleleButterflySpecies("lepiGozoraAzure", true, "Gozora Azure", celastrina, "gozora", 0x6870e7).setRarity(0.2f); + + /* PAPILIONIDAE */ + IClassification papilio = createButterflyBranch(papilionidae, "Papilio"); + IClassification protographium = createButterflyBranch(papilionidae, "Protographium"); + + Allele.lepiCitrusSwallow = new AlleleButterflySpecies("lepiCitrusSwallow", false, "Citrus Swallowtail", papilio, "demodocus", 0xeae389).setRarity(1.0f) + .setTemperature(EnumTemperature.WARM).setHumidity(EnumHumidity.DAMP); + Allele.lepiEmeraldPeacock = new AlleleButterflySpecies("lepiEmeraldPeacock", true, "Emerald Peacock", papilio, "palinurus", 0x7cfe80) + .setTemperature(EnumTemperature.WARM).setHumidity(EnumHumidity.DAMP); + Allele.lepiThoasSwallow = new AlleleButterflySpecies("lepiThoasSwallow", false, "Thoas Swallowtail", papilio, "thoas", 0xeac783).setRarity(0.2f) + .setTemperature(EnumTemperature.WARM).setHumidity(EnumHumidity.DAMP); + Allele.lepiSpicebush = new AlleleButterflySpecies("lepiSpicebush", true, "Spicebush Swallowtail", papilio, "troilus", 0xeefeff).setRarity(0.5f); + Allele.lepiBlackSwallow = new AlleleButterflySpecies("lepiBlackSwallow", true, "Black Swallowtail", papilio, "polyxenes", 0xeac783).setRarity(1.0f); + + Allele.lepiZebraSwallow = new AlleleButterflySpecies("lepiZebraSwallow", true, "Zebra Swallowtail", protographium, "marcellus", 0xeafeff).setRarity(0.5f); + Allele.lepiDianaFrit = new AlleleButterflySpecies("lepiDianaFrit", true, "Diana Fritillary", protographium, "diana", 0xffac05).setRarity(0.6f); + + /* NYMPHALIDAE */ + IClassification pararge = createButterflyBranch(nymphalidae, "Pararge"); + IClassification polygonia = createButterflyBranch(nymphalidae, "Polygonia"); + IClassification morpho = createButterflyBranch(nymphalidae, "Morpho"); + IClassification greta = createButterflyBranch(nymphalidae, "Greta"); + IClassification batesia = createButterflyBranch(nymphalidae, "Batesia"); + IClassification myscelia = createButterflyBranch(nymphalidae, "Myscelia"); + IClassification danaus = createButterflyBranch(nymphalidae, "Danaus"); + IClassification bassarona = createButterflyBranch(nymphalidae, "Bassarona"); + IClassification parantica = createButterflyBranch(nymphalidae, "Parantica"); + IClassification heliconius = createButterflyBranch(nymphalidae, "Heliconius"); + IClassification siproeta = createButterflyBranch(nymphalidae, "Siproeta"); + IClassification cethosia = createButterflyBranch(nymphalidae, "Cethosia"); + + Allele.lepiGlasswing = new AlleleButterflySpecies("lepiGlasswing", true, "Glasswing", greta, "oto", 0x583732) + .setTemperature(EnumTemperature.WARM); + + Allele.lepiSpeckledWood = new AlleleButterflySpecies("lepiSpeckledWood", true, "Speckled Wood", pararge, "aegeria", 0x947245).setRarity(1.0f); + Allele.lepiMadeiranSpeckledWood = new AlleleButterflySpecies("lepiMSpeckledWood", true, "Madeiran Speckled Wood", pararge, "xiphia", 0x402919).setRarity(0.5f); + Allele.lepiCanarySpeckledWood = new AlleleButterflySpecies("lepiCSpeckledWood", true, "Canary Speckled Wood", pararge, "xiphioides", 0x51372a).setRarity(0.5f); + + Allele.lepiMenelausBlueMorpho = new AlleleButterflySpecies("lepiMBlueMorpho", true, "Menelaus Blue Morpho", morpho, "menelaus", 0x72e1fd).setRarity(0.5f) + .setTemperature(EnumTemperature.WARM).setHumidity(EnumHumidity.DAMP); + Allele.lepiPeleidesBlueMorpho = new AlleleButterflySpecies("lepiPBlueMorpho", true, "Peleides Blue Morpho", morpho, "peleides", 0x6ecce8).setRarity(0.25f) + .setTemperature(EnumTemperature.WARM).setHumidity(EnumHumidity.DAMP); + Allele.lepiRhetenorBlueMorpho = new AlleleButterflySpecies("lepiRBlueMorpho", true, "Rhetenor Blue Morpho", morpho, "rhetenor", 0x00bef8) + .setTemperature(EnumTemperature.WARM).setHumidity(EnumHumidity.DAMP); + + Allele.lepiComma = new AlleleButterflySpecies("lepiComma", true, "Comma", polygonia, "c-album", 0xf89505).setRarity(0.3f); + Allele.lepiBatesia = new AlleleButterflySpecies("lepiBatesia", true, "Painted Beauty", batesia, "hypochlora", 0xfe7763).setRarity(0.3f) + .setTemperature(EnumTemperature.WARM).setHumidity(EnumHumidity.DAMP); + Allele.lepiBlueWing = new AlleleButterflySpecies("lepiBlueWing", true, "Blue Wing", myscelia, "ethusa", 0x3a93cc).setRarity(0.3f); + + Allele.lepiMonarch = new AlleleButterflySpecies("lepiMonarch", true, "Monarch", danaus, "plexippus", 0xffa722).setRarity(0.2f); + Allele.lepiBlueDuke = new AlleleButterflySpecies("lepiBlueDuke", true, "Blue Duke", bassarona, "durga", 0x304240).setRarity(0.5f) + .setTemperature(EnumTemperature.COLD); + Allele.lepiGlassyTiger = new AlleleButterflySpecies("lepiGlassyTiger", true, "Glassy Tiger", parantica, "aglea", 0x5b3935).setRarity(0.3f); + Allele.lepiPostman = new AlleleButterflySpecies("lepiPostman", true, "Postman", heliconius, "melpmene", 0xf7302d).setRarity(0.3f); + Allele.lepiMalachite = new AlleleButterflySpecies("lepiMalachite", true, "Malachite", siproeta, "stelenes", 0xbdff53).setRarity(0.5f) + .setTemperature(EnumTemperature.WARM).setHumidity(EnumHumidity.DAMP); + Allele.lepiLLacewing = new AlleleButterflySpecies("lepiLLacewing", true, "Leopard Lacewing", cethosia, "cyane", 0xfb8a06).setRarity(0.7f); + + Allele.butterflyNone = new AlleleEffectNone("bfNone", false); + } + + private void registerTemplates() { + butterflyInterface.registerTemplate(ButterflyTemplates.getBrimstoneMothTemplate()); + butterflyInterface.registerTemplate(ButterflyTemplates.getLatticedHeathTemplate()); + butterflyInterface.registerTemplate(ButterflyTemplates.getAtlasMothTemplate()); + + butterflyInterface.registerTemplate(ButterflyTemplates.getCabbageWhiteTemplate()); + butterflyInterface.registerTemplate(ButterflyTemplates.getGlasswingTemplate()); + + butterflyInterface.registerTemplate(ButterflyTemplates.getEmeraldPeacockTemplate()); + butterflyInterface.registerTemplate(ButterflyTemplates.getThoasSwallowTemplate()); + butterflyInterface.registerTemplate(ButterflyTemplates.getCitrusSwallowTemplate()); + butterflyInterface.registerTemplate(ButterflyTemplates.getBlackSwallowTemplate()); + butterflyInterface.registerTemplate(ButterflyTemplates.getZebraSwallowTemplate()); + butterflyInterface.registerTemplate(ButterflyTemplates.getDianaFritTemplate()); + + butterflyInterface.registerTemplate(ButterflyTemplates.getSpeckledWoodTemplate()); + butterflyInterface.registerTemplate(ButterflyTemplates.getMadeiranSpeckledWoodTemplate()); + butterflyInterface.registerTemplate(ButterflyTemplates.getCanarySpeckledWoodTemplate()); + + butterflyInterface.registerTemplate(ButterflyTemplates.getMenelausBlueMorphoTemplate()); + butterflyInterface.registerTemplate(ButterflyTemplates.getRhetenorBlueMorphoTemplate()); + butterflyInterface.registerTemplate(ButterflyTemplates.getPeleidesBlueMorphoTemplate()); + + butterflyInterface.registerTemplate(ButterflyTemplates.getBrimstoneTemplate()); + butterflyInterface.registerTemplate(ButterflyTemplates.getAuroraTemplate()); + butterflyInterface.registerTemplate(ButterflyTemplates.getPostillionTemplate()); + butterflyInterface.registerTemplate(ButterflyTemplates.getPalaenoSulphurTemplate()); + + butterflyInterface.registerTemplate(ButterflyTemplates.getResedaTemplate()); + butterflyInterface.registerTemplate(ButterflyTemplates.getSpringAzureTemplate()); + butterflyInterface.registerTemplate(ButterflyTemplates.getGozoraAzureTemplate()); + + butterflyInterface.registerTemplate(ButterflyTemplates.getCommaTemplate()); + butterflyInterface.registerTemplate(ButterflyTemplates.getBatesiaTemplate()); + butterflyInterface.registerTemplate(ButterflyTemplates.getBlueWingTemplate()); + + butterflyInterface.registerTemplate(ButterflyTemplates.getBlueDukeTemplate()); + butterflyInterface.registerTemplate(ButterflyTemplates.getGlassyTigerTemplate()); + butterflyInterface.registerTemplate(ButterflyTemplates.getMonarchTemplate()); + butterflyInterface.registerTemplate(ButterflyTemplates.getPostmanTemplate()); + butterflyInterface.registerTemplate(ButterflyTemplates.getSpicebushTemplate()); + butterflyInterface.registerTemplate(ButterflyTemplates.getMalachiteTemplate()); + butterflyInterface.registerTemplate(ButterflyTemplates.getLeopardLacewingTemplate()); + + } + + private IClassification createButterflyBranch(IClassification family, String scientific) { + IClassification branch = new Branch("moth." + scientific.toLowerCase(Locale.ENGLISH), scientific); + branch.setParent(family); + return branch; + } + + @Override + public IGuiHandler getGuiHandler() { + return new GuiHandlerLepidopterology(); + } +} diff --git a/forestry_common/mail/forestry/mail/CommandMail.java b/forestry_common/mail/forestry/mail/CommandMail.java new file mode 100755 index 000000000..14a8d45b9 --- /dev/null +++ b/forestry_common/mail/forestry/mail/CommandMail.java @@ -0,0 +1,115 @@ +/******************************************************************************* + * Copyright 2011-2014 by SirSengir + * + * This work is licensed under a Creative Commons Attribution-NonCommercial-NoDerivs 3.0 Unported License. + * + * To view a copy of this license, visit http://creativecommons.org/licenses/by-nc-nd/3.0/. + ******************************************************************************/ +package forestry.mail; + +import java.util.List; + +import net.minecraft.command.ICommand; +import net.minecraft.command.ICommandSender; +import net.minecraft.command.WrongUsageException; +import net.minecraft.entity.player.EntityPlayer; +import net.minecraft.item.ItemStack; +import net.minecraft.world.World; + +import forestry.api.mail.ITradeStation; +import forestry.api.mail.PostManager; +import forestry.api.mail.TradeStationInfo; +import forestry.core.proxy.Proxies; +import forestry.core.utils.CommandMC; +import forestry.core.utils.StringUtil; + +public class CommandMail extends CommandMC { + + @Override + public int compareTo(Object arg0) { + return this.getCommandName().compareTo(((ICommand) arg0).getCommandName()); + } + + @Override + public String getCommandName() { + return "mail"; + } + + @Override + public String getCommandUsage(ICommandSender sender) { + return "/" + this.getCommandName() + " help"; + } + + @SuppressWarnings("rawtypes") + @Override + public List getCommandAliases() { + return null; + } + + @Override + public void processCommand(ICommandSender sender, String[] arguments) { + if (arguments.length <= 0) + throw new WrongUsageException("Type '" + this.getCommandUsage(sender) + "' for help."); + + if (arguments[0].matches("trades")) { + commandTrades(sender, arguments); + return; + } else if (arguments[0].matches("virtualize")) { + commandVirtualize(sender, arguments); + return; + } else if (arguments[0].matches("help")) { + sendChatMessage(sender, "Format: '" + this.getCommandName() + " '"); + sendChatMessage(sender, "Available commands:"); + sendChatMessage(sender, "- trades : A list of all trade stations."); + sendChatMessage(sender, "- virtualize : Toggle virtual mode on specified trade station."); + return; + } + + throw new WrongUsageException(this.getCommandUsage(sender)); + } + + private void commandTrades(ICommandSender sender, String[] arguments) { + if (!(sender instanceof EntityPlayer)) + return; + for (ITradeStation trade : PostManager.postRegistry.getPostOffice(((EntityPlayer) sender).worldObj).getActiveTradeStations(((EntityPlayer) sender).worldObj).values()) + sendChatMessage(sender, makeTradeListEntry(trade.getTradeInfo())); + } + + private String makeTradeListEntry(TradeStationInfo info) { + String entry = "\u00A7c"; + if (info.state == EnumStationState.OK) + entry = "\u00A7a"; + + String tradegood = "[ ? ]"; + if (info.tradegood != null) + tradegood = info.tradegood.stackSize + "x" + info.tradegood.getDisplayName(); + String demand = "[ ? ]"; + if (info.required.length > 0) { + demand = ""; + for (ItemStack dmd : info.required) + demand = StringUtil.append(", ", demand, dmd.stackSize + "x" + dmd.getDisplayName()); + } + + return String.format("%s%-12s | %-20s | %s", entry, info.moniker, tradegood, demand); + } + + private void commandVirtualize(ICommandSender sender, String[] arguments) { + if ((sender instanceof EntityPlayer && !Proxies.common.isOp((EntityPlayer) sender)) || (!sender.canCommandSenderUseCommand(4, getCommandName()))) { + sendChatMessage(sender, "\u00a7cYou do not have permission to use this command."); + return; + } + + if (arguments.length <= 1) + throw new WrongUsageException("/" + getCommandName() + " virtualize "); + + World world = getWorld(sender, arguments); + ITradeStation trade = PostManager.postRegistry.getTradeStation(world, arguments[1]); + if (trade == null) { + sendChatMessage(sender, String.format("\u00a7cNo tradestation by the name of '%s' was found.", arguments[1])); + return; + } + + trade.setVirtual(!trade.isVirtual()); + sendChatMessage(sender, String.format("\u00A7aSet virtualization for '%s' to %s.", trade.getMoniker(), trade.isVirtual())); + } +} diff --git a/forestry_common/mail/forestry/mail/EnumAddressee.java b/forestry_common/mail/forestry/mail/EnumAddressee.java new file mode 100755 index 000000000..82a57f90a --- /dev/null +++ b/forestry_common/mail/forestry/mail/EnumAddressee.java @@ -0,0 +1,21 @@ +/******************************************************************************* + * Copyright 2011-2014 by SirSengir + * + * This work is licensed under a Creative Commons Attribution-NonCommercial-NoDerivs 3.0 Unported License. + * + * To view a copy of this license, visit http://creativecommons.org/licenses/by-nc-nd/3.0/. + ******************************************************************************/ +package forestry.mail; + +public enum EnumAddressee { + PLAYER, TRADER; + + public static EnumAddressee fromString(String ident) { + for(EnumAddressee addr : values()) { + if(addr.toString().equals(ident)) + return addr; + } + + return null; + } +} diff --git a/forestry_common/mail/forestry/mail/EnumDeliveryState.java b/forestry_common/mail/forestry/mail/EnumDeliveryState.java new file mode 100755 index 000000000..d04bd6d23 --- /dev/null +++ b/forestry_common/mail/forestry/mail/EnumDeliveryState.java @@ -0,0 +1,26 @@ +/******************************************************************************* + * Copyright 2011-2014 by SirSengir + * + * This work is licensed under a Creative Commons Attribution-NonCommercial-NoDerivs 3.0 Unported License. + * + * To view a copy of this license, visit http://creativecommons.org/licenses/by-nc-nd/3.0/. + ******************************************************************************/ +package forestry.mail; + +import java.util.Locale; + +import forestry.api.mail.IPostalState; + +public enum EnumDeliveryState implements IPostalState { + OK, NO_MAILBOX, NOT_MAILABLE, ALREADY_MAILED, NOT_POSTPAID, MAILBOX_FULL, RESPONSE_NOT_MAILABLE; + + @Override + public boolean isOk() { + return this == OK; + } + + @Override + public String getIdentifier() { + return this.toString().toLowerCase(Locale.ENGLISH); + } +} diff --git a/forestry_common/mail/forestry/mail/EnumStationState.java b/forestry_common/mail/forestry/mail/EnumStationState.java new file mode 100755 index 000000000..8685584be --- /dev/null +++ b/forestry_common/mail/forestry/mail/EnumStationState.java @@ -0,0 +1,26 @@ +/******************************************************************************* + * Copyright 2011-2014 by SirSengir + * + * This work is licensed under a Creative Commons Attribution-NonCommercial-NoDerivs 3.0 Unported License. + * + * To view a copy of this license, visit http://creativecommons.org/licenses/by-nc-nd/3.0/. + ******************************************************************************/ +package forestry.mail; + +import java.util.Locale; + +import forestry.api.mail.IPostalState; + +public enum EnumStationState implements IPostalState { + OK, INSUFFICIENT_OFFER, INSUFFICIENT_TRADE_GOOD, INSUFFICIENT_BUFFER, INSUFFICIENT_PAPER, INSUFFICIENT_STAMPS; + + @Override + public boolean isOk() { + return this == OK; + } + + @Override + public String getIdentifier() { + return this.toString().toLowerCase(Locale.ENGLISH); + } +} diff --git a/forestry_common/mail/forestry/mail/GuiHandlerMail.java b/forestry_common/mail/forestry/mail/GuiHandlerMail.java new file mode 100755 index 000000000..7bfb76584 --- /dev/null +++ b/forestry_common/mail/forestry/mail/GuiHandlerMail.java @@ -0,0 +1,119 @@ +/******************************************************************************* + * Copyright 2011-2014 by SirSengir + * + * This work is licensed under a Creative Commons Attribution-NonCommercial-NoDerivs 3.0 Unported License. + * + * To view a copy of this license, visit http://creativecommons.org/licenses/by-nc-nd/3.0/. + ******************************************************************************/ +package forestry.mail; + +import net.minecraft.entity.player.EntityPlayer; +import net.minecraft.item.ItemStack; +import net.minecraft.world.World; + +import forestry.core.GuiHandlerBase; +import forestry.core.network.GuiId; +import forestry.mail.gadgets.MachineMailbox; +import forestry.mail.gadgets.MachinePhilatelist; +import forestry.mail.gadgets.MachineTrader; +import forestry.mail.gui.ContainerCatalogue; +import forestry.mail.gui.ContainerLetter; +import forestry.mail.gui.ContainerMailbox; +import forestry.mail.gui.ContainerPhilatelist; +import forestry.mail.gui.ContainerTradeName; +import forestry.mail.gui.ContainerTrader; +import forestry.mail.gui.GuiCatalogue; +import forestry.mail.gui.GuiLetter; +import forestry.mail.gui.GuiMailbox; +import forestry.mail.gui.GuiPhilatelist; +import forestry.mail.gui.GuiTradeName; +import forestry.mail.gui.GuiTrader; +import forestry.mail.items.ItemCatalogue; +import forestry.mail.items.ItemLetter; +import forestry.mail.items.ItemLetter.LetterInventory; + +public class GuiHandlerMail extends GuiHandlerBase { + + @Override + public Object getClientGuiElement(int id, EntityPlayer player, World world, int x, int y, int z) { + + if (id >= GuiId.values().length) + return null; + + switch (GuiId.values()[id]) { + case CatalogueGUI: + ItemStack cata = getEquippedItem(player); + if (cata == null) + return null; + + if (cata.getItem() instanceof ItemCatalogue) + return new GuiCatalogue(player); + else + return null; + + case LetterGUI: + ItemStack equipped = getEquippedItem(player); + if (equipped == null) + return null; + + if (equipped.getItem() instanceof ItemLetter) + return new GuiLetter(player, new LetterInventory(equipped)); + else + return null; + + case MailboxGUI: + return new GuiMailbox(player.inventory, (MachineMailbox) getTileForestry(world, x, y, z)); + case PhilatelistGUI: + return new GuiPhilatelist(player.inventory, (MachinePhilatelist) getTileForestry(world, x, y, z)); + case TraderGUI: + return new GuiTrader(player.inventory, (MachineTrader) getTileForestry(world, x, y, z)); + case TraderNameGUI: + return new GuiTradeName(player.inventory, (MachineTrader) getTileForestry(world, x, y, z)); + default: + return null; + + } + } + + @Override + public Object getServerGuiElement(int id, EntityPlayer player, World world, int x, int y, int z) { + + if (id >= GuiId.values().length) + return null; + + switch (GuiId.values()[id]) { + case CatalogueGUI: + ItemStack cata = getEquippedItem(player); + if (cata == null) + return null; + + if (cata.getItem() instanceof ItemCatalogue) + return new ContainerCatalogue(player); + else + return null; + + case LetterGUI: + ItemStack equipped = getEquippedItem(player); + if (equipped == null) + return null; + + if (equipped.getItem() instanceof ItemLetter) + return new ContainerLetter(player, new LetterInventory(getEquippedItem(player))); + else + return null; + + case MailboxGUI: + return new ContainerMailbox(player.inventory, (MachineMailbox) getTileForestry(world, x, y, z)); + case PhilatelistGUI: + return new ContainerPhilatelist(player.inventory, (MachinePhilatelist) getTileForestry(world, x, y, z)); + case TraderGUI: + return new ContainerTrader(player.inventory, (MachineTrader) getTileForestry(world, x, y, z)); + case TraderNameGUI: + return new ContainerTradeName(player.inventory, (MachineTrader) getTileForestry(world, x, y, z)); + default: + return null; + + } + } + +} diff --git a/forestry_common/mail/forestry/mail/IMailContainer.java b/forestry_common/mail/forestry/mail/IMailContainer.java new file mode 100755 index 000000000..b36006ac6 --- /dev/null +++ b/forestry_common/mail/forestry/mail/IMailContainer.java @@ -0,0 +1,12 @@ +/******************************************************************************* + * Copyright 2011-2014 by SirSengir + * + * This work is licensed under a Creative Commons Attribution-NonCommercial-NoDerivs 3.0 Unported License. + * + * To view a copy of this license, visit http://creativecommons.org/licenses/by-nc-nd/3.0/. + ******************************************************************************/ +package forestry.mail; + +public interface IMailContainer { + boolean hasMail(); +} diff --git a/forestry_common/mail/forestry/mail/Letter.java b/forestry_common/mail/forestry/mail/Letter.java new file mode 100755 index 000000000..5e69d3cb6 --- /dev/null +++ b/forestry_common/mail/forestry/mail/Letter.java @@ -0,0 +1,323 @@ +/******************************************************************************* + * Copyright 2011-2014 by SirSengir + * + * This work is licensed under a Creative Commons Attribution-NonCommercial-NoDerivs 3.0 Unported License. + * + * To view a copy of this license, visit http://creativecommons.org/licenses/by-nc-nd/3.0/. + ******************************************************************************/ +package forestry.mail; + +import java.util.List; + +import net.minecraft.entity.player.EntityPlayer; +import net.minecraft.item.ItemStack; +import net.minecraft.nbt.NBTTagCompound; + +import forestry.api.core.INBTTagable; +import forestry.api.mail.ILetter; +import forestry.api.mail.IStamps; +import forestry.api.mail.MailAddress; +import forestry.core.utils.InventoryAdapter; +import forestry.core.utils.StringUtil; + +public class Letter implements ILetter, INBTTagable { + + // CONSTANTS + public static short SLOT_ATTACHMENT_1 = 0; + public static short SLOT_POSTAGE_1 = 18; + + private boolean isProcessed = false; + + private MailAddress sender; + private MailAddress[] recipient; + + private String text; + private InventoryAdapter inventory = new InventoryAdapter(22, "INV"); + + public Letter(MailAddress sender, MailAddress recipient) { + this.sender = sender; + this.recipient = new MailAddress[] { recipient }; + } + + public Letter(NBTTagCompound nbttagcompound) { + if (nbttagcompound != null) + readFromNBT(nbttagcompound); + } + + @Override + public void readFromNBT(NBTTagCompound nbttagcompound) { + + this.isProcessed = nbttagcompound.getBoolean("PRC"); + this.sender = MailAddress.loadFromNBT(nbttagcompound.getCompoundTag("SDR")); + + int recipientCount = nbttagcompound.getShort("CRC"); + this.recipient = new MailAddress[recipientCount]; + for (int i = 0; i < recipientCount; i++) + this.recipient[i] = MailAddress.loadFromNBT(nbttagcompound.getCompoundTag("RC" + i)); + + this.text = nbttagcompound.getString("TXT"); + + this.inventory.readFromNBT(nbttagcompound); + + } + + @Override + public void writeToNBT(NBTTagCompound nbttagcompound) { + + nbttagcompound.setBoolean("PRC", isProcessed); + + NBTTagCompound subcompound = new NBTTagCompound(); + this.sender.writeToNBT(subcompound); + nbttagcompound.setTag("SDR", subcompound); + + nbttagcompound.setShort("CRC", (short) recipient.length); + for (int i = 0; i < recipient.length; i++) { + subcompound = new NBTTagCompound(); + this.recipient[i].writeToNBT(subcompound); + nbttagcompound.setTag("RC" + i, subcompound); + } + + nbttagcompound.setString("TXT", this.text); + + inventory.writeToNBT(nbttagcompound); + } + + @Override + public ItemStack[] getPostage() { + return inventory.getStacks(SLOT_POSTAGE_1, 4); + } + + @Override + public ItemStack[] getAttachments() { + return inventory.getStacks(SLOT_ATTACHMENT_1, 18); + } + + @Override + public int countAttachments() { + + int count = 0; + for (ItemStack stack : getAttachments()) + if (stack != null) + count++; + + return count; + + } + + @Override + public void addAttachment(ItemStack itemstack) { + inventory.tryAddStack(itemstack, false); + } + + @Override + public void addAttachments(ItemStack[] itemstacks) { + for (ItemStack stack : itemstacks) + addAttachment(stack); + } + + @Override + public void invalidatePostage() { + for (int i = SLOT_POSTAGE_1; i < SLOT_POSTAGE_1 + 4; i++) + inventory.setInventorySlotContents(i, null); + } + + public void setInventory(InventoryAdapter inventory) { + this.inventory = inventory; + } + + @Override + public void setProcessed(boolean flag) { + this.isProcessed = flag; + } + + @Override + public boolean isProcessed() { + return this.isProcessed; + } + + @Override + public boolean isMailable() { + + // Can't resend an already sent letter + if (this.isProcessed) + return false; + + // Requires at least one recipient + if (this.recipient != null && this.recipient.length > 0) + return true; + + return false; + } + + @Override + public boolean isPostPaid() { + + int posted = 0; + + for (ItemStack stamp : getPostage()) { + if (stamp == null) + continue; + if (!(stamp.getItem() instanceof IStamps)) + continue; + + posted += ((IStamps) stamp.getItem()).getPostage(stamp).getValue() * stamp.stackSize; + } + + return posted >= requiredPostage(); + } + + @Override + public int requiredPostage() { + + int required = 1; + for (ItemStack attach : getAttachments()) + if (attach != null) + required++; + + return required; + } + + @Override + public void addStamps(ItemStack stamps) { + this.inventory.tryAddStack(stamps, SLOT_POSTAGE_1, 4, false); + } + + @Override + public boolean hasRecipient() { + if (getRecipients().length <= 0) + return false; + + MailAddress recipient = getRecipients()[0]; + if (recipient == null) + return false; + + if (recipient.getIdentifier().isEmpty()) + return false; + + return true; + } + + @Override + public void setSender(MailAddress address) { + this.sender = address; + } + + @Override + public MailAddress getSender() { + return sender; + } + + public void setRecipients(MailAddress[] recipients) { + this.recipient = recipients; + } + + @Override + public void setRecipient(MailAddress address) { + if (address == null) + this.recipient = new MailAddress[] {}; + else + this.recipient = new MailAddress[] { address }; + } + + @Override + public MailAddress[] getRecipients() { + return recipient; + } + + @Override + public String getRecipientString() { + String recipientString = ""; + for (MailAddress address : recipient) { + if (recipientString.length() > 0) + recipientString += ", "; + recipientString += address.getIdentifier(); + } + + return recipientString; + } + + @Override + public void setText(String text) { + this.text = text; + } + + @Override + public String getText() { + return text; + } + + @SuppressWarnings({ "rawtypes", "unchecked" }) + @Override + public void addTooltip(List list) { + if (this.sender != null) + list.add(StringUtil.localize("gui.mail.from") + ": " + this.sender.getIdentifier()); + if (this.recipient != null && this.recipient.length > 0) + list.add(StringUtil.localize("gui.mail.to") + ": " + this.getRecipientString()); + } + + // / IINVENTORY + @Override + public int getSizeInventory() { + return inventory.getSizeInventory(); + } + + @Override + public ItemStack getStackInSlot(int var1) { + return inventory.getStackInSlot(var1); + } + + @Override + public ItemStack decrStackSize(int var1, int var2) { + return inventory.decrStackSize(var1, var2); + } + + @Override + public ItemStack getStackInSlotOnClosing(int var1) { + return inventory.getStackInSlotOnClosing(var1); + } + + @Override + public void setInventorySlotContents(int var1, ItemStack var2) { + inventory.setInventorySlotContents(var1, var2); + } + + @Override + public String getInventoryName() { + return inventory.getInventoryName(); + } + + @Override + public int getInventoryStackLimit() { + return inventory.getInventoryStackLimit(); + } + + @Override + public void markDirty() { + inventory.markDirty(); + } + + @Override + public boolean isUseableByPlayer(EntityPlayer var1) { + return true; + } + + @Override + public void openInventory() { + inventory.openInventory(); + } + + @Override + public void closeInventory() { + inventory.closeInventory(); + } + + @Override + public boolean hasCustomInventoryName() { + return inventory.hasCustomInventoryName(); + } + + @Override + public boolean isItemValidForSlot(int i, ItemStack itemstack) { + return inventory.isItemValidForSlot(i, itemstack); + } +} diff --git a/forestry_common/mail/forestry/mail/POBox.java b/forestry_common/mail/forestry/mail/POBox.java new file mode 100755 index 000000000..76f4eed1b --- /dev/null +++ b/forestry_common/mail/forestry/mail/POBox.java @@ -0,0 +1,149 @@ +/******************************************************************************* + * Copyright 2011-2014 by SirSengir + * + * This work is licensed under a Creative Commons Attribution-NonCommercial-NoDerivs 3.0 Unported License. + * + * To view a copy of this license, visit http://creativecommons.org/licenses/by-nc-nd/3.0/. + ******************************************************************************/ +package forestry.mail; + +import net.minecraft.entity.player.EntityPlayer; +import net.minecraft.inventory.IInventory; +import net.minecraft.item.ItemStack; +import net.minecraft.nbt.NBTTagCompound; +import net.minecraft.world.WorldSavedData; + +import forestry.api.mail.ILetter; +import forestry.api.mail.PostManager; +import forestry.core.utils.InventoryAdapter; + +public class POBox extends WorldSavedData implements IInventory { + + public static final String SAVE_NAME = "POBox_"; + public static final short SLOT_SIZE = 84; + + private String owner; + private InventoryAdapter letters = new InventoryAdapter(SLOT_SIZE, "Letters"); + + public POBox(String owner, boolean isUser) { + super(SAVE_NAME + owner); + this.owner = owner; + } + + public POBox(String savename) { + super(savename); + } + + @Override + public void readFromNBT(NBTTagCompound nbttagcompound) { + owner = nbttagcompound.getString("Owner"); + letters.readFromNBT(nbttagcompound); + } + + @Override + public void writeToNBT(NBTTagCompound nbttagcompound) { + nbttagcompound.setString("Owner", owner); + letters.writeToNBT(nbttagcompound); + } + + public String getOwnerName() { + return this.owner; + } + + public boolean storeLetter(ItemStack letterstack) { + ILetter letter = PostManager.postRegistry.getLetter(letterstack); + + // Mark letter as processed + letter.setProcessed(true); + letter.invalidatePostage(); + NBTTagCompound nbttagcompound = new NBTTagCompound(); + letter.writeToNBT(nbttagcompound); + letterstack.setTagCompound(nbttagcompound); + + this.markDirty(); + return this.letters.tryAddStack(letterstack, true); + } + + public POBoxInfo getPOBoxInfo() { + int playerLetters = 0; + int tradeLetters = 0; + for (int i = 0; i < letters.getSizeInventory(); i++) { + if (letters.getStackInSlot(i) == null) + continue; + ILetter letter = new Letter(letters.getStackInSlot(i).getTagCompound()); + if (letter.getSender().isPlayer()) + playerLetters++; + else + tradeLetters++; + } + + return new POBoxInfo(playerLetters, tradeLetters); + } + + /* IINVENTORY */ + @Override + public void markDirty() { + this.markDirty(); + letters.markDirty(); + } + + @Override + public void setInventorySlotContents(int var1, ItemStack var2) { + this.markDirty(); + letters.setInventorySlotContents(var1, var2); + } + + @Override + public int getSizeInventory() { + return letters.getSizeInventory(); + } + + @Override + public ItemStack getStackInSlot(int var1) { + return letters.getStackInSlot(var1); + } + + @Override + public ItemStack decrStackSize(int var1, int var2) { + return letters.decrStackSize(var1, var2); + } + + @Override + public ItemStack getStackInSlotOnClosing(int var1) { + return letters.getStackInSlotOnClosing(var1); + } + + @Override + public String getInventoryName() { + return letters.getInventoryName(); + } + + @Override + public int getInventoryStackLimit() { + return letters.getInventoryStackLimit(); + } + + @Override + public boolean isUseableByPlayer(EntityPlayer var1) { + return letters.isUseableByPlayer(var1); + } + + @Override + public void openInventory() { + } + + @Override + public void closeInventory() { + } + + @Override + public boolean hasCustomInventoryName() { + return true; + } + + @Override + public boolean isItemValidForSlot(int i, ItemStack itemstack) { + return true; + } + +} diff --git a/forestry_common/mail/forestry/mail/POBoxInfo.java b/forestry_common/mail/forestry/mail/POBoxInfo.java new file mode 100755 index 000000000..f28677e3e --- /dev/null +++ b/forestry_common/mail/forestry/mail/POBoxInfo.java @@ -0,0 +1,22 @@ +/******************************************************************************* + * Copyright 2011-2014 by SirSengir + * + * This work is licensed under a Creative Commons Attribution-NonCommercial-NoDerivs 3.0 Unported License. + * + * To view a copy of this license, visit http://creativecommons.org/licenses/by-nc-nd/3.0/. + ******************************************************************************/ +package forestry.mail; + +public class POBoxInfo { + public final int playerLetters; + public final int tradeLetters; + + public POBoxInfo(int playerLetters, int tradeLetters) { + this.playerLetters = playerLetters; + this.tradeLetters = tradeLetters; + } + + public boolean hasMail() { + return playerLetters > 0 || tradeLetters > 0; + } +} diff --git a/forestry_common/mail/forestry/mail/PacketHandlerMail.java b/forestry_common/mail/forestry/mail/PacketHandlerMail.java new file mode 100755 index 000000000..c68e0c855 --- /dev/null +++ b/forestry_common/mail/forestry/mail/PacketHandlerMail.java @@ -0,0 +1,113 @@ +/******************************************************************************* + * Copyright 2011-2014 by SirSengir + * + * This work is licensed under a Creative Commons Attribution-NonCommercial-NoDerivs 3.0 Unported License. + * + * To view a copy of this license, visit http://creativecommons.org/licenses/by-nc-nd/3.0/. + ******************************************************************************/ +package forestry.mail; + +import java.io.DataInputStream; + +import net.minecraft.entity.player.EntityPlayer; +import net.minecraft.inventory.Container; + +import forestry.core.interfaces.IPacketHandler; +import forestry.core.network.PacketIds; +import forestry.core.network.PacketUpdate; +import forestry.core.proxy.Proxies; +import forestry.mail.gui.ContainerCatalogue; +import forestry.mail.gui.ContainerLetter; +import forestry.mail.gui.ContainerTradeName; +import forestry.mail.network.PacketPOBoxInfo; +import forestry.mail.network.PacketTradeInfo; +import forestry.plugins.PluginMail; + +public class PacketHandlerMail implements IPacketHandler { + + @Override + public void onPacketData(int packetID, DataInputStream data, EntityPlayer player) { + + try { + + PacketUpdate packet; + switch (packetID) { + case PacketIds.TRADING_INFO: + PacketTradeInfo packetT = new PacketTradeInfo(); + packetT.readData(data); + onTradeInfo(packetT); + break; + case PacketIds.POBOX_INFO: + PacketPOBoxInfo packetP = new PacketPOBoxInfo(); + packetP.readData(data); + onPOBoxInfo(packetP); + break; + case PacketIds.LETTER_RECIPIENT: + packet = new PacketUpdate(); + packet.readData(data); + onLetterRecipient(player, packet); + break; + case PacketIds.LETTER_TEXT: + packet = new PacketUpdate(); + packet.readData(data); + onLetterText(player, packet); + break; + case PacketIds.TRADING_MONIKER_SET: + packet = new PacketUpdate(); + packet.readData(data); + onMonikerSet(player, packet); + break; + case PacketIds.POBOX_INFO_REQUEST: + onPOBoxInfoRequest(player); + break; + } + } catch (Exception ex) { + ex.printStackTrace(); + } + } + + private void onTradeInfo(PacketTradeInfo packet) { + + Container container = Proxies.common.getClientInstance().thePlayer.openContainer; + if (container instanceof ContainerLetter) { + ((ContainerLetter) container).handleTradeInfoUpdate(packet); + } else if(container instanceof ContainerCatalogue) { + ((ContainerCatalogue) container).handleTradeInfoUpdate(packet); + } + + } + + private void onPOBoxInfo(PacketPOBoxInfo packet) { + PluginMail.proxy.setPOBoxInfo(Proxies.common.getRenderWorld(), Proxies.common.getClientInstance().thePlayer.getGameProfile().getId(), packet.poboxInfo); + } + + private void onMonikerSet(EntityPlayer player, PacketUpdate packet) { + if (!(player.openContainer instanceof ContainerTradeName)) + return; + + ((ContainerTradeName) player.openContainer).handleSetMoniker(packet); + } + + private void onLetterText(EntityPlayer player, PacketUpdate packet) { + if (!(player.openContainer instanceof ContainerLetter)) + return; + + ((ContainerLetter) player.openContainer).handleSetText(packet); + } + + private void onLetterRecipient(EntityPlayer player, PacketUpdate packet) { + if (!(player.openContainer instanceof ContainerLetter)) + return; + + ((ContainerLetter) player.openContainer).handleSetRecipient(player, packet); + } + + private void onPOBoxInfoRequest(EntityPlayer player) { + POBox pobox = PostRegistry.getPOBox(player.worldObj, player.getGameProfile().getId()); + if (pobox == null) + return; + + Proxies.net.sendToPlayer(new PacketPOBoxInfo(PacketIds.POBOX_INFO, pobox.getPOBoxInfo()), player); + } + +} diff --git a/forestry_common/mail/forestry/mail/PostOffice.java b/forestry_common/mail/forestry/mail/PostOffice.java new file mode 100755 index 000000000..798d12e0a --- /dev/null +++ b/forestry_common/mail/forestry/mail/PostOffice.java @@ -0,0 +1,201 @@ +/******************************************************************************* + * Copyright 2011-2014 by SirSengir + * + * This work is licensed under a Creative Commons Attribution-NonCommercial-NoDerivs 3.0 Unported License. + * + * To view a copy of this license, visit http://creativecommons.org/licenses/by-nc-nd/3.0/. + ******************************************************************************/ +package forestry.mail; + +import java.io.File; +import java.util.LinkedHashMap; + +import net.minecraft.item.ItemStack; +import net.minecraft.nbt.NBTTagCompound; +import net.minecraft.world.World; +import net.minecraft.world.WorldSavedData; + +import forestry.api.mail.EnumPostage; +import forestry.api.mail.ILetter; +import forestry.api.mail.IPostOffice; +import forestry.api.mail.IPostalCarrier; +import forestry.api.mail.IPostalState; +import forestry.api.mail.IStamps; +import forestry.api.mail.ITradeStation; +import forestry.api.mail.MailAddress; +import forestry.api.mail.PostManager; +import forestry.core.config.ForestryItem; + +public class PostOffice extends WorldSavedData implements IPostOffice { + + // / CONSTANTS + public static final String SAVE_NAME = "ForestryMail"; + private int[] collectedPostage = new int[EnumPostage.values().length]; + + // / CONSTRUCTOR + public PostOffice(String s) { + super(s); + } + + public PostOffice() { + super(SAVE_NAME); + } + + @Override + public void readFromNBT(NBTTagCompound nbttagcompound) { + for (int i = 0; i < collectedPostage.length; i++) { + if (nbttagcompound.hasKey("CPS" + i)) + collectedPostage[i] = nbttagcompound.getInteger("CPS" + i); + } + } + + @Override + public void writeToNBT(NBTTagCompound nbttagcompound) { + for (int i = 0; i < collectedPostage.length; i++) { + nbttagcompound.setInteger("CPS" + i, collectedPostage[i]); + } + } + + /* TRADE STATION MANAGMENT */ + private LinkedHashMap activeTradeStations; + + @Override + public LinkedHashMap getActiveTradeStations(World world) { + if (activeTradeStations == null) + refreshActiveTradeStations(world); + + return this.activeTradeStations; + } + + private void refreshActiveTradeStations(World world) { + activeTradeStations = new LinkedHashMap(); + if (world == null || world.getSaveHandler() == null) + return; + File worldSave = world.getSaveHandler().getMapFileFromName("dummy"); + if (worldSave == null) + return; + File file = worldSave.getParentFile(); + if (!file.exists() || !file.isDirectory()) + return; + + for (String str : file.list()) { + if (!str.startsWith(TradeStation.SAVE_NAME)) + continue; + if (!str.endsWith(".dat")) + continue; + + ITradeStation trade = PostManager.postRegistry.getTradeStation(world, str.replace(TradeStation.SAVE_NAME, "").replace(".dat", "")); + if (trade == null) + continue; + + registerTradeStation(trade); + } + } + + @Override + public void registerTradeStation(ITradeStation trade) { + if (activeTradeStations == null) + return; + + if (!activeTradeStations.containsKey(trade.getMoniker())) + activeTradeStations.put(trade.getMoniker(), trade); + + } + + @Override + public void deregisterTradeStation(ITradeStation trade) { + if (activeTradeStations == null) + return; + + activeTradeStations.remove(trade.getMoniker()); + } + + // / STAMP MANAGMENT + @Override + public ItemStack getAnyStamp(int max) { + return getAnyStamp(EnumPostage.values(), max); + } + + @Override + public ItemStack getAnyStamp(EnumPostage postage, int max) { + return getAnyStamp(new EnumPostage[] { postage }, max); + } + + @Override + public ItemStack getAnyStamp(EnumPostage[] postages, int max) { + + for (EnumPostage postage : postages) { + + int collected = 0; + if (collectedPostage[postage.ordinal()] <= 0) + continue; + + if (max >= collectedPostage[postage.ordinal()]) { + collected = collectedPostage[postage.ordinal()]; + collectedPostage[postage.ordinal()] = 0; + } else { + collected = max; + collectedPostage[postage.ordinal()] -= max; + } + + if (collected > 0) + return ForestryItem.stamps.getItemStack(collected, postage.ordinal() - 1); + } + + return null; + } + + // / DELIVERY + @Override + public IPostalState lodgeLetter(World world, ItemStack itemstack, boolean doLodge) { + ILetter letter = PostManager.postRegistry.getLetter(itemstack); + + if (letter.isProcessed()) + return EnumDeliveryState.ALREADY_MAILED; + + if (!letter.isPostPaid()) + return EnumDeliveryState.NOT_POSTPAID; + + if (!letter.isMailable()) + return EnumDeliveryState.NOT_MAILABLE; + + IPostalState state = EnumDeliveryState.NOT_MAILABLE; + for (MailAddress address : letter.getRecipients()) { + IPostalCarrier carrier = PostManager.postRegistry.getCarrier(address.getType()); + if (carrier == null) + continue; + state = carrier.deliverLetter(world, this, address.getIdentifier(), itemstack, doLodge); + if (!state.isOk()) + break; + } + /* + for (MailAddress address : letter.getRecipients()) + if (address.isPlayer()) + state = storeInPOBox(world, address, itemstack, doLodge); + else if (address.getType().equals(EnumAddressee.TRADER.toString())) + state = handleTradeLetter(world, address, itemstack, doLodge); + */ + + if (!state.isOk()) + return state; + + collectPostage(letter.getPostage()); + + markDirty(); + return EnumDeliveryState.OK; + + } + + @Override + public void collectPostage(ItemStack[] stamps) { + for (ItemStack stamp : stamps) { + if (stamp == null) + continue; + + if (stamp.getItem() instanceof IStamps) { + EnumPostage postage = ((IStamps) stamp.getItem()).getPostage(stamp); + collectedPostage[postage.ordinal()] += stamp.stackSize; + } + } + } +} diff --git a/forestry_common/mail/forestry/mail/PostRegistry.java b/forestry_common/mail/forestry/mail/PostRegistry.java new file mode 100755 index 000000000..d34a2d236 --- /dev/null +++ b/forestry_common/mail/forestry/mail/PostRegistry.java @@ -0,0 +1,215 @@ +/******************************************************************************* + * Copyright 2011-2014 by SirSengir + * + * This work is licensed under a Creative Commons Attribution-NonCommercial-NoDerivs 3.0 Unported License. + * + * To view a copy of this license, visit http://creativecommons.org/licenses/by-nc-nd/3.0/. + ******************************************************************************/ +package forestry.mail; + +import java.io.File; +import java.util.HashMap; +import java.util.Locale; +import java.util.Map; + +import net.minecraft.item.ItemStack; +import net.minecraft.nbt.NBTTagCompound; +import net.minecraft.world.World; + +import forestry.api.mail.ILetter; +import forestry.api.mail.IPostOffice; +import forestry.api.mail.IPostRegistry; +import forestry.api.mail.IPostalCarrier; +import forestry.api.mail.ITradeStation; +import forestry.api.mail.MailAddress; +import forestry.api.mail.PostManager; +import forestry.core.config.ForestryItem; +import forestry.mail.items.ItemLetter; +import forestry.plugins.PluginMail; + +public class PostRegistry implements IPostRegistry { + + public static PostOffice cachedPostOffice; + public static HashMap cachedPOBoxes = new HashMap(); + public static HashMap cachedTradeStations = new HashMap(); + + /** + * @param world + * @param username + * @return true if the passed username is valid for poboxes. + */ + @Override + public boolean isValidPOBox(World world, String username) { + if (!username.matches("^[a-zA-Z0-9]+$")) + return false; + + return true; + } + + public static POBox getPOBox(World world, String username) { + + if (cachedPOBoxes.containsKey(username.toLowerCase(Locale.ENGLISH))) + return cachedPOBoxes.get(username.toLowerCase(Locale.ENGLISH)); + + POBox pobox = (POBox) world.loadItemData(POBox.class, POBox.SAVE_NAME + username.toLowerCase(Locale.ENGLISH)); + if (pobox != null) + cachedPOBoxes.put(username.toLowerCase(Locale.ENGLISH), pobox); + return pobox; + } + + public static POBox getOrCreatePOBox(World world, String username) { + POBox pobox = getPOBox(world, username); + + if (pobox == null) { + pobox = new POBox(username.toLowerCase(Locale.ENGLISH), true); + world.setItemData(POBox.SAVE_NAME + username.toLowerCase(Locale.ENGLISH), pobox); + pobox.markDirty(); + cachedPOBoxes.put(username.toLowerCase(Locale.ENGLISH), pobox); + PluginMail.proxy.setPOBoxInfo(world, username, pobox.getPOBoxInfo()); + } + + return pobox; + } + + /** + * @param world + * @param moniker + * @return true if the passed moniker can be a moniker for a trade station + */ + @Override + public boolean isValidTradeMoniker(World world, String moniker) { + if (!moniker.matches("^[a-zA-Z0-9]+$")) + return false; + + return true; + } + + /** + * @param world + * @param moniker + * @return true if the trade moniker has not yet been used before. + */ + @Override + public boolean isAvailableTradeMoniker(World world, String moniker) { + return getTradeStation(world, moniker) == null; + } + + @Override + public TradeStation getTradeStation(World world, String moniker) { + if (cachedTradeStations.containsKey(moniker)) + return (TradeStation)cachedTradeStations.get(moniker); + + TradeStation trade = (TradeStation) world.loadItemData(TradeStation.class, TradeStation.SAVE_NAME + moniker); + + // Only existing and valid mail orders are returned + if (trade != null && trade.isValid()) { + cachedTradeStations.put(moniker, trade); + getPostOffice(world).registerTradeStation(trade); + return trade; + } + + return null; + } + + @Override + public TradeStation getOrCreateTradeStation(World world, String owner, String moniker) { + TradeStation trade = getTradeStation(world, moniker); + + if (trade == null) { + trade = new TradeStation(owner, moniker, true); + world.setItemData(TradeStation.SAVE_NAME + moniker, trade); + trade.markDirty(); + cachedTradeStations.put(moniker, trade); + getPostOffice(world).registerTradeStation(trade); + } + + return trade; + } + + @Override + public void deleteTradeStation(World world, String moniker) { + TradeStation trade = (TradeStation)getTradeStation(world, moniker); + if (trade == null) + return; + + // Need to be marked as invalid since WorldSavedData seems to do some caching of its own. + trade.invalidate(); + cachedTradeStations.remove(moniker); + getPostOffice(world).deregisterTradeStation(trade); + File file = world.getSaveHandler().getMapFileFromName(trade.mapName); + file.delete(); + } + + @Override + public IPostOffice getPostOffice(World world) { + if (cachedPostOffice != null) + return cachedPostOffice; + + PostOffice office = (PostOffice) world.loadItemData(PostOffice.class, PostOffice.SAVE_NAME); + + // Create office if there is none yet + if (office == null) { + office = new PostOffice(); + world.setItemData(PostOffice.SAVE_NAME, office); + } + + cachedPostOffice = office; + return office; + } + + /* CARRIER */ + private HashMap carriers = new HashMap(); + + @Override + public Map getRegisteredCarriers() { + return carriers; + } + + @Override + public void registerCarrier(IPostalCarrier carrier) { + carriers.put(carrier.getUID(), carrier); + } + + @Override + public IPostalCarrier getCarrier(String uid) { + return carriers.get(uid); + } + + /* LETTERS */ + @Override + public ILetter createLetter(MailAddress sender, MailAddress recipient) { + return new Letter(sender, recipient); + } + + @Override + public ItemStack createLetterStack(ILetter letter) { + NBTTagCompound nbttagcompound = new NBTTagCompound(); + letter.writeToNBT(nbttagcompound); + + ItemStack mailstack = ForestryItem.letters.getItemStack(1, ItemLetter.encodeMeta(1, ItemLetter.getType(letter))); + mailstack.setTagCompound(nbttagcompound); + + return mailstack; + } + + @Override + public ILetter getLetter(ItemStack itemstack) { + if (itemstack == null) + return null; + + if (!PostManager.postRegistry.isLetter(itemstack)) + return null; + + if (itemstack.getTagCompound() == null) + return null; + + return new Letter(itemstack.getTagCompound()); + } + + @Override + public boolean isLetter(ItemStack itemstack) { + return ForestryItem.letters.isItemEqual(itemstack); + } + + +} diff --git a/forestry_common/mail/forestry/mail/PostalCarrier.java b/forestry_common/mail/forestry/mail/PostalCarrier.java new file mode 100755 index 000000000..f2b7f4e0b --- /dev/null +++ b/forestry_common/mail/forestry/mail/PostalCarrier.java @@ -0,0 +1,90 @@ +/******************************************************************************* + * Copyright 2011-2014 by SirSengir + * + * This work is licensed under a Creative Commons Attribution-NonCommercial-NoDerivs 3.0 Unported License. + * + * To view a copy of this license, visit http://creativecommons.org/licenses/by-nc-nd/3.0/. + ******************************************************************************/ +package forestry.mail; + +import java.util.Locale; + +import net.minecraft.item.ItemStack; +import net.minecraft.util.IIcon; +import net.minecraft.world.World; + +import cpw.mods.fml.relauncher.Side; +import cpw.mods.fml.relauncher.SideOnly; + +import forestry.api.mail.IPostOffice; +import forestry.api.mail.IPostalCarrier; +import forestry.api.mail.IPostalState; +import forestry.api.mail.ITradeStation; +import forestry.api.mail.PostManager; +import forestry.core.render.TextureManager; +import forestry.core.utils.StringUtil; +import forestry.plugins.PluginMail; + +public class PostalCarrier implements IPostalCarrier { + + private String uid; + private String iconID; + private EnumAddressee type; + + public PostalCarrier(EnumAddressee type) { + uid = type.toString().toLowerCase(Locale.ENGLISH); + iconID = "mail/carrier." + uid; + this.type = type; + } + + @Override + public String getUID() { + return uid; + } + + @Override + public String getName() { + return StringUtil.localize("gui.addressee." + uid); + } + + @Override + @SideOnly(Side.CLIENT) + public IIcon getIcon() { + return TextureManager.getInstance().getDefault(iconID); + } + + @Override + public IPostalState deliverLetter(World world, IPostOffice office, String recipient, ItemStack letterstack, boolean doDeliver) { + if(type == EnumAddressee.TRADER) + return handleTradeLetter(world, office, recipient, letterstack, doDeliver); + else + return storeInPOBox(world, office, recipient, letterstack, doDeliver); + } + + private IPostalState handleTradeLetter(World world, IPostOffice office, String recipient, ItemStack letterstack, boolean doLodge) { + IPostalState state = EnumDeliveryState.NOT_MAILABLE; + + ITradeStation trade = PostManager.postRegistry.getTradeStation(world, recipient); + if (trade == null) + return EnumDeliveryState.NO_MAILBOX; + + state = trade.handleLetter(world, recipient, letterstack, doLodge); + + return state; + } + + private EnumDeliveryState storeInPOBox(World world, IPostOffice office, String recipient, ItemStack letterstack, boolean doLodge) { + + POBox pobox = PostRegistry.getPOBox(world, recipient); + if (pobox == null) + return EnumDeliveryState.NO_MAILBOX; + + if (!pobox.storeLetter(letterstack.copy())) + return EnumDeliveryState.MAILBOX_FULL; + else + PluginMail.proxy.setPOBoxInfo(world, recipient, pobox.getPOBoxInfo()); + + return EnumDeliveryState.OK; + } + +} diff --git a/forestry_common/mail/forestry/mail/SaveEventHandlerMail.java b/forestry_common/mail/forestry/mail/SaveEventHandlerMail.java new file mode 100755 index 000000000..610d935dd --- /dev/null +++ b/forestry_common/mail/forestry/mail/SaveEventHandlerMail.java @@ -0,0 +1,33 @@ +/******************************************************************************* + * Copyright 2011-2014 by SirSengir + * + * This work is licensed under a Creative Commons Attribution-NonCommercial-NoDerivs 3.0 Unported License. + * + * To view a copy of this license, visit http://creativecommons.org/licenses/by-nc-nd/3.0/. + ******************************************************************************/ +package forestry.mail; + +import net.minecraft.world.World; + +import forestry.core.interfaces.ISaveEventHandler; +import forestry.plugins.PluginMail; + +public class SaveEventHandlerMail implements ISaveEventHandler { + + @Override + public void onWorldLoad(World world) { + PostRegistry.cachedPostOffice = null; + PostRegistry.cachedPOBoxes.clear(); + PostRegistry.cachedTradeStations.clear(); + PluginMail.proxy.clearMailboxInfo(); + } + + @Override + public void onWorldSave(World world) { + } + + @Override + public void onWorldUnload(World world) { + } + +} diff --git a/forestry_common/mail/forestry/mail/TickHandlerMailClient.java b/forestry_common/mail/forestry/mail/TickHandlerMailClient.java new file mode 100755 index 000000000..96aca6b8e --- /dev/null +++ b/forestry_common/mail/forestry/mail/TickHandlerMailClient.java @@ -0,0 +1,32 @@ +/******************************************************************************* + * Copyright 2011-2014 by SirSengir + * + * This work is licensed under a Creative Commons Attribution-NonCommercial-NoDerivs 3.0 Unported License. + * + * To view a copy of this license, visit http://creativecommons.org/licenses/by-nc-nd/3.0/. + ******************************************************************************/ +package forestry.mail; + +import cpw.mods.fml.common.FMLCommonHandler; +import cpw.mods.fml.common.eventhandler.SubscribeEvent; +import cpw.mods.fml.common.gameevent.TickEvent.Phase; +import cpw.mods.fml.common.gameevent.TickEvent.RenderTickEvent; + +import forestry.mail.gui.GuiMailboxInfo; +import forestry.plugins.PluginMail; + +public class TickHandlerMailClient { + public TickHandlerMailClient() { + FMLCommonHandler.instance().bus().register(this); + } + + @SubscribeEvent + public void onRenderTick(RenderTickEvent event) { + if (event.phase != Phase.END) return; + + if (GuiMailboxInfo.instance != null) + GuiMailboxInfo.instance.render(0, 0); + else + PluginMail.proxy.resetMailboxInfo(); + } +} diff --git a/forestry_common/mail/forestry/mail/TradeStation.java b/forestry_common/mail/forestry/mail/TradeStation.java new file mode 100755 index 000000000..fe812a567 --- /dev/null +++ b/forestry_common/mail/forestry/mail/TradeStation.java @@ -0,0 +1,492 @@ +/******************************************************************************* + * Copyright 2011-2014 by SirSengir + * + * This work is licensed under a Creative Commons Attribution-NonCommercial-NoDerivs 3.0 Unported License. + * + * To view a copy of this license, visit http://creativecommons.org/licenses/by-nc-nd/3.0/. + ******************************************************************************/ +package forestry.mail; + +import java.util.ArrayList; +import java.util.Locale; + +import net.minecraft.entity.player.EntityPlayer; +import net.minecraft.init.Items; +import net.minecraft.inventory.IInventory; +import net.minecraft.item.ItemStack; +import net.minecraft.nbt.NBTTagCompound; +import net.minecraft.world.World; +import net.minecraft.world.WorldSavedData; + +import forestry.api.mail.EnumPostage; +import forestry.api.mail.ILetter; +import forestry.api.mail.IPostalState; +import forestry.api.mail.IStamps; +import forestry.api.mail.ITradeStation; +import forestry.api.mail.MailAddress; +import forestry.api.mail.PostManager; +import forestry.api.mail.TradeStationInfo; +import forestry.core.config.ForestryItem; +import forestry.core.utils.InventoryAdapter; +import forestry.core.utils.StackUtils; +import forestry.mail.items.ItemLetter; + +public class TradeStation extends WorldSavedData implements ITradeStation, IInventory { + + // / CONSTANTS + public static final String SAVE_NAME = "TradePO_"; + public static final short SLOT_SIZE = 39; + public static final short SLOT_TRADEGOOD = 0; + public static final short SLOT_EXCHANGE_1 = 1; + public static final short SLOT_EXCHANGE_COUNT = 4; + public static final short SLOT_LETTERS_1 = 5; + public static final short SLOT_LETTERS_COUNT = 6; + public static final short SLOT_STAMPS_1 = 11; + public static final short SLOT_STAMPS_COUNT = 4; + public static final short SLOT_INPUTBUF_1 = 15; + public static final short SLOT_OUTPUTBUF_1 = 27; + public static final short SLOT_BUFFER_COUNT = 12; + // / MEMBER + private String owner; + private String moniker; + private boolean isVirtual = false; + private boolean isInvalid = false; + private final InventoryAdapter inventory = new InventoryAdapter(SLOT_SIZE, "INV"); + + // / CONSTRUCTORS + public TradeStation(String owner, String moniker, boolean isMoniker) { + super(SAVE_NAME + moniker); + this.owner = owner; + this.moniker = moniker; + } + + public TradeStation(String savename) { + super(savename); + } + + @Override + public String getMoniker() { + return this.moniker; + } + + // / SAVING & LOADING + @Override + public void readFromNBT(NBTTagCompound nbttagcompound) { + this.owner = nbttagcompound.getString("OWN"); + this.moniker = nbttagcompound.getString("MNK"); + this.isVirtual = nbttagcompound.getBoolean("VRT"); + this.isInvalid = nbttagcompound.getBoolean("IVL"); + inventory.readFromNBT(nbttagcompound); + } + + @Override + public void writeToNBT(NBTTagCompound nbttagcompound) { + if (this.owner != null && !this.owner.isEmpty()) + nbttagcompound.setString("OWN", this.owner); + nbttagcompound.setString("MNK", this.moniker); + nbttagcompound.setBoolean("VRT", this.isVirtual); + nbttagcompound.setBoolean("IVL", this.isInvalid); + inventory.writeToNBT(nbttagcompound); + } + + /* INVALIDATING */ + @Override + public boolean isValid() { + return !this.isInvalid; + } + + @Override + public void invalidate() { + this.isInvalid = true; + } + + /* INFORMATION */ + @Override + public void setVirtual(boolean isVirtual) { + this.isVirtual = isVirtual; + markDirty(); + } + + @Override + public boolean isVirtual() { + return isVirtual; + } + + @Override + public TradeStationInfo getTradeInfo() { + ItemStack[] condensedRequired = StackUtils.condenseStacks(inventory.getStacks(SLOT_EXCHANGE_1, SLOT_EXCHANGE_COUNT)); + + // Set current state + EnumStationState state = EnumStationState.OK; + + // Virtual trade stations are always ready for service + if (!isVirtual()) { + if (!hasPaper()) + state = EnumStationState.INSUFFICIENT_PAPER; + if (!canPayPostage(2)) + state = EnumStationState.INSUFFICIENT_STAMPS; + if (countFillableOrders(1, inventory.getStackInSlot(SLOT_TRADEGOOD)) <= 0) + state = EnumStationState.INSUFFICIENT_TRADE_GOOD; + } + + return new TradeStationInfo(moniker, owner, inventory.getStackInSlot(SLOT_TRADEGOOD), condensedRequired, state); + } + + /* ILETTERHANDLER */ + @Override + public IPostalState handleLetter(World world, String recipient, ItemStack letterstack, boolean doLodge) { + + ILetter letter = PostManager.postRegistry.getLetter(letterstack); + + if (!isVirtual() && !hasPaper()) + return EnumStationState.INSUFFICIENT_PAPER; + + int ordersToFill = StackUtils.containsSets(inventory.getStacks(SLOT_EXCHANGE_1, SLOT_EXCHANGE_COUNT), letter.getAttachments()); + // Not a single match. + if (ordersToFill <= 0) + return EnumStationState.INSUFFICIENT_OFFER; + + if (!isVirtual()) { + int fillable = countFillableOrders(ordersToFill, inventory.getStackInSlot(SLOT_TRADEGOOD)); + // Nothing can be filled. + if (fillable <= 0) + return EnumStationState.INSUFFICIENT_TRADE_GOOD; + if (fillable < ordersToFill) + ordersToFill = fillable; + + // Check for sufficient output buffer + int storable = countStorablePayment(ordersToFill, inventory.getStacks(SLOT_EXCHANGE_1, SLOT_EXCHANGE_COUNT)); + if (storable <= 0) + return EnumStationState.INSUFFICIENT_BUFFER; + if (storable < ordersToFill) + ordersToFill = storable; + } + + // Prepare and send letter + ILetter mail = new Letter(new MailAddress(this.moniker, EnumAddressee.TRADER.toString().toLowerCase(Locale.ENGLISH)), letter.getSender()); + mail.setText("Please find your order attached."); + for (int i = 0; i < ordersToFill; i++) { + mail.addAttachment(inventory.getStackInSlot(SLOT_TRADEGOOD).copy()); + } + mail.addAttachments(getSurplusAttachments(ordersToFill, letter.getAttachments())); + + // Attach necessary postage + int requiredPostage = mail.requiredPostage(); + if (!isVirtual()) + if (!canPayPostage(requiredPostage)) + return EnumStationState.INSUFFICIENT_STAMPS; + + int[] stampCount = getPostage(requiredPostage, isVirtual()); + for (int i = 0; i < stampCount.length; i++) { + if (stampCount[i] > 0) + mail.addStamps(ForestryItem.stamps.getItemStack(stampCount[i], EnumPostage.values()[i].ordinal())); + } + + NBTTagCompound nbttagcompound = new NBTTagCompound(); + mail.writeToNBT(nbttagcompound); + + ItemStack mailstack = ForestryItem.letters.getItemStack(1, ItemLetter.encodeMeta(1, ItemLetter.getType(mail))); + mailstack.setTagCompound(nbttagcompound); + + IPostalState responseState = PostManager.postRegistry.getPostOffice(world).lodgeLetter(world, mailstack, doLodge); + if (!responseState.isOk()) { + return EnumDeliveryState.RESPONSE_NOT_MAILABLE; + } + + // Store received items + for (int i = 0; i < ordersToFill; i++) { + for (ItemStack stack : inventory.getStacks(SLOT_EXCHANGE_1, SLOT_EXCHANGE_COUNT)) { + if (stack == null) + continue; + inventory.tryAddStack(stack.copy(), SLOT_OUTPUTBUF_1, SLOT_BUFFER_COUNT, false); + } + } + + // Remove resources + removePaper(); + removeStamps(stampCount); + removeTradegood(ordersToFill); + markDirty(); + + // Send confirmation message to seller + if (doLodge && owner != null && !owner.isEmpty()) { + ILetter confirm = new Letter(new MailAddress(this.moniker, EnumAddressee.TRADER.toString().toLowerCase(Locale.ENGLISH)), new MailAddress(this.owner)); + confirm.setText(ordersToFill + " order(s) from " + letter.getSender().getIdentifier() + " were filled."); + confirm.addStamps(ForestryItem.stamps.getItemStack(1, EnumPostage.P_1.ordinal())); + nbttagcompound = new NBTTagCompound(); + confirm.writeToNBT(nbttagcompound); + ItemStack confirmstack = ForestryItem.letters.getItemStack(1, ItemLetter.encodeMeta(1, ItemLetter.getType(confirm))); + confirmstack.setTagCompound(nbttagcompound); + PostManager.postRegistry.getPostOffice(world).lodgeLetter(world, confirmstack, doLodge); + } + + return EnumDeliveryState.OK; + } + + /* TRADE LOGIC */ + private int countFillableOrders(int max, ItemStack tradegood) { + + if (tradegood == null) + return 0; + + // How many orders are fillable? + int itemCount = 0; + for (ItemStack stack : inventory.getStacks(SLOT_INPUTBUF_1, SLOT_BUFFER_COUNT)) { + if (stack != null && stack.isItemEqual(tradegood) && ItemStack.areItemStackTagsEqual(stack, tradegood)) + itemCount += stack.stackSize; + } + + return (int) Math.floor(itemCount / tradegood.stackSize); + } + + private int countStorablePayment(int max, ItemStack[] exchange) { + + InventoryAdapter test = inventory.copy(); + int count = 0; + + for (int i = 0; i < max; i++) { + if (test.tryAddStacksCopy(exchange, true)) + count++; + else + break; + } + + return count; + } + + private void removeTradegood(int filled) { + + for (int j = 0; j < filled; j++) { + int toRemove = inventory.getStackInSlot(SLOT_TRADEGOOD).stackSize; + for (int i = SLOT_INPUTBUF_1; i < SLOT_INPUTBUF_1 + SLOT_BUFFER_COUNT; i++) { + ItemStack buffer = inventory.getStackInSlot(i); + if (buffer == null) + continue; + + if (!buffer.isItemEqual(inventory.getStackInSlot(SLOT_TRADEGOOD))) + continue; + + if (!ItemStack.areItemStackTagsEqual(buffer, inventory.getStackInSlot(SLOT_TRADEGOOD))) + continue; + + ItemStack decrease = inventory.decrStackSize(i, toRemove); + toRemove -= decrease.stackSize; + + if (toRemove <= 0) + break; + } + } + } + + // Checks if at least one scrap of paper is available + private boolean hasPaper() { + for (ItemStack stack : inventory.getStacks(SLOT_LETTERS_1, SLOT_LETTERS_COUNT)) { + if (stack != null && stack.stackSize > 0) + return true; + } + + return false; + } + + // Removes a single paper from the inventory + private void removePaper() { + for (int i = SLOT_LETTERS_1; i < SLOT_LETTERS_1 + SLOT_LETTERS_COUNT; i++) { + ItemStack stack = inventory.getStackInSlot(i); + if (stack != null && stack.getItem() == Items.paper && stack.stackSize > 0) { + inventory.decrStackSize(i, 1); + break; + } + } + } + + private boolean canPayPostage(int postage) { + + int posted = 0; + for (ItemStack stamp : inventory.getStacks(SLOT_STAMPS_1, SLOT_STAMPS_COUNT)) { + if (stamp == null) + continue; + if (!(stamp.getItem() instanceof IStamps)) + continue; + + posted += ((IStamps) stamp.getItem()).getPostage(stamp).getValue() * stamp.stackSize; + if (posted >= postage) + return true; + } + + return false; + } + + private int[] getPostage(int postage, boolean virtual) { + int[] stamps = new int[EnumPostage.values().length]; + + for (int i = EnumPostage.values().length - 1; i > 0; i--) { + if (postage <= 0) + break; + + EnumPostage postValue = EnumPostage.values()[i]; + + if (postValue.getValue() > postage) + continue; + + int num = 99; + if (!virtual) + num = getNumStamps(postValue); + int max = (int) Math.floor(postage / postValue.getValue()); + if (max < num) + num = max; + + stamps[i] = num; + postage -= num * postValue.getValue(); + + } + + return stamps; + } + + private int getNumStamps(EnumPostage postage) { + int count = 0; + for (ItemStack stamp : inventory.getStacks(SLOT_STAMPS_1, SLOT_STAMPS_COUNT)) { + if (stamp == null) + continue; + if (!(stamp.getItem() instanceof IStamps)) + continue; + + if (((IStamps) stamp.getItem()).getPostage(stamp) == postage) + count += stamp.stackSize; + + } + + return count; + } + + private void removeStamps(int[] stampCount) { + for (int i = 1; i < stampCount.length; i++) { + + if (stampCount[i] <= 0) + continue; + + for (int j = SLOT_STAMPS_1; j < SLOT_STAMPS_1 + SLOT_STAMPS_COUNT; j++) { + if (stampCount[i] <= 0) + continue; + + ItemStack stamp = inventory.getStackInSlot(j); + if (stamp == null) + continue; + if (!(stamp.getItem() instanceof IStamps)) + continue; + + if (((IStamps) stamp.getItem()).getPostage(stamp) == EnumPostage.values()[i]) { + ItemStack decrease = inventory.decrStackSize(j, stampCount[i]); + stampCount[i] -= decrease.stackSize; + } + + } + } + } + + private ItemStack[] getSurplusAttachments(int filled, ItemStack[] attachments) { + ArrayList surplus = new ArrayList(); + + // Get a copy of the attachments to play with + ItemStack[] pool = new ItemStack[attachments.length]; + for (int i = 0; i < attachments.length; i++) { + if (attachments[i] != null) + pool[i] = attachments[i].copy(); + } + + // Remove stuff until we are only left with the remants + for (int i = 0; i < filled; i++) { + ItemStack[] condensedRequired = StackUtils.condenseStacks(inventory.getStacks(SLOT_EXCHANGE_1, SLOT_EXCHANGE_COUNT)); + for (ItemStack req : condensedRequired) { + for (int j = 0; j < pool.length; j++) { + ItemStack pol = pool[j]; + if (pol == null) + continue; + if (!pol.isItemEqual(req)) + continue; + + if (req.stackSize >= pol.stackSize) { + req.stackSize -= pol.stackSize; + pool[j] = null; + } else { + pol.stackSize -= req.stackSize; + req.stackSize = 0; + } + } + } + } + + for (ItemStack stack : pool) { + if (stack != null) + surplus.add(stack); + } + + return surplus.toArray(new ItemStack[0]); + } + + /* IINVENTORY */ + @Override + public void markDirty() { + this.markDirty(); + inventory.markDirty(); + } + + @Override + public void setInventorySlotContents(int var1, ItemStack var2) { + this.markDirty(); + inventory.setInventorySlotContents(var1, var2); + } + + @Override + public int getSizeInventory() { + return inventory.getSizeInventory(); + } + + @Override + public ItemStack getStackInSlot(int var1) { + return inventory.getStackInSlot(var1); + } + + @Override + public ItemStack decrStackSize(int var1, int var2) { + return inventory.decrStackSize(var1, var2); + } + + @Override + public ItemStack getStackInSlotOnClosing(int var1) { + return inventory.getStackInSlotOnClosing(var1); + } + + @Override + public String getInventoryName() { + return inventory.getInventoryName(); + } + + @Override + public int getInventoryStackLimit() { + return inventory.getInventoryStackLimit(); + } + + @Override + public boolean isUseableByPlayer(EntityPlayer var1) { + return inventory.isUseableByPlayer(var1); + } + + @Override + public void openInventory() { + } + + @Override + public void closeInventory() { + } + + @Override + public boolean hasCustomInventoryName() { + return true; + } + + @Override + public boolean isItemValidForSlot(int i, ItemStack itemstack) { + return true; + } +} diff --git a/forestry_common/mail/forestry/mail/gadgets/MachineMailbox.java b/forestry_common/mail/forestry/mail/gadgets/MachineMailbox.java new file mode 100755 index 000000000..632bd6e02 --- /dev/null +++ b/forestry_common/mail/forestry/mail/gadgets/MachineMailbox.java @@ -0,0 +1,275 @@ +/******************************************************************************* + * Copyright 2011-2014 by SirSengir + * + * This work is licensed under a Creative Commons Attribution-NonCommercial-NoDerivs 3.0 Unported License. + * + * To view a copy of this license, visit http://creativecommons.org/licenses/by-nc-nd/3.0/. + ******************************************************************************/ +package forestry.mail.gadgets; + +import java.util.LinkedList; + +import net.minecraft.entity.player.EntityPlayer; +import net.minecraft.inventory.IInventory; +import net.minecraft.inventory.ISidedInventory; +import net.minecraft.item.ItemStack; +import net.minecraft.nbt.NBTTagCompound; +import net.minecraft.util.ChatComponentTranslation; + +import net.minecraftforge.common.util.ForgeDirection; + +import buildcraft.api.gates.ITrigger; +import buildcraft.api.inventory.ISpecialInventory; + +import forestry.api.core.ForestryAPI; +import forestry.api.mail.ILetter; +import forestry.api.mail.IPostalState; +import forestry.api.mail.PostManager; +import forestry.core.config.Config; +import forestry.core.gadgets.TileBase; +import forestry.core.network.GuiId; +import forestry.core.proxy.Proxies; +import forestry.core.utils.InventoryAdapter; +import forestry.mail.EnumDeliveryState; +import forestry.mail.IMailContainer; +import forestry.mail.POBox; +import forestry.mail.PostRegistry; +import forestry.plugins.PluginMail; + +public class MachineMailbox extends TileBase implements IMailContainer, ISpecialInventory, ISidedInventory { + + private boolean isLinked = false; + + public MachineMailbox() { + setHints(Config.hints.get("mailbox")); + } + + @Override + public String getInventoryName() { + return "mail.0"; + } + + /* GUI */ + @Override + public void openGui(EntityPlayer player, TileBase tile) { + + if (!Proxies.common.isSimulating(worldObj)) + return; + + ItemStack held = player.getCurrentEquippedItem(); + + // Handle letter sending + if (PostManager.postRegistry.isLetter(held)) { + IPostalState result = this.tryDispatchLetter(held, true); + if (!result.isOk()) + player.addChatMessage(new ChatComponentTranslation("chat.mail." + result.getIdentifier())); + else + held.stackSize--; + } else + player.openGui(ForestryAPI.instance, GuiId.MailboxGUI.ordinal(), player.worldObj, xCoord, yCoord, zCoord); + } + + /* SAVING & LOADING */ + @Override + public void writeToNBT(NBTTagCompound nbttagcompound) { + super.writeToNBT(nbttagcompound); + + nbttagcompound.setBoolean("LNK", this.isLinked); + } + + @Override + public void readFromNBT(NBTTagCompound nbttagcompound) { + super.readFromNBT(nbttagcompound); + + this.isLinked = nbttagcompound.getBoolean("LNK"); + } + + /* UPDATING */ + @Override + public void updateServerSide() { + if (!isLinked) { + getOrCreateMailInventory(); + isLinked = true; + } + } + + /* MAIL HANDLING */ + public IInventory getOrCreateMailInventory() { + + // Handle client side + if (!Proxies.common.isSimulating(worldObj)) + return new InventoryAdapter(POBox.SLOT_SIZE, "Letters"); + + if (getOwnerName() == null || getOwnerName().isEmpty()) + return new InventoryAdapter(POBox.SLOT_SIZE, "Letters"); + + return PostRegistry.getOrCreatePOBox(worldObj, getOwnerName()); + } + + private IPostalState tryDispatchLetter(ItemStack letterstack, boolean dispatchLetter) { + ILetter letter = PostManager.postRegistry.getLetter(letterstack); + IPostalState result; + + if (letter != null) + result = PostManager.postRegistry.getPostOffice(worldObj).lodgeLetter(worldObj, letterstack, dispatchLetter); + else + result = EnumDeliveryState.NOT_MAILABLE; + + return result; + } + + /* IMAILCONTAINER */ + @Override + public boolean hasMail() { + + IInventory mailInventory = getOrCreateMailInventory(); + for (int i = 0; i < mailInventory.getSizeInventory(); i++) + if (mailInventory.getStackInSlot(i) != null) + return true; + + return false; + } + + /* ITRIGGERPROVIDER */ + @Override + public LinkedList getCustomTriggers() { + LinkedList res = new LinkedList(); + res.add(PluginMail.triggerHasMail); + return res; + } + + /* ISIDEDINVENTORY */ + private static int[] slotIndices; + + public int[] getSizeInventorySide(int side) { + IInventory inventory = getOrCreateMailInventory(); + if(slotIndices == null) { + slotIndices = new int[inventory.getSizeInventory()]; + for(int i = 0; i < inventory.getSizeInventory(); i++) + slotIndices[i] = i; + } + return slotIndices; + } + + /* ISPECIALINVENTORY */ + @Override + public int addItem(ItemStack stack, boolean doAdd, ForgeDirection from) { + if (!PostManager.postRegistry.isLetter(stack)) + return 0; + + IPostalState result = tryDispatchLetter(stack, doAdd); + + if (!result.isOk()) + return 0; + else + return 1; + } + + @Override + public ItemStack[] extractItem(boolean doRemove, ForgeDirection from, int maxItemCount) { + + ItemStack product = null; + IInventory mailInventory = getOrCreateMailInventory(); + + for (int i = 0; i < mailInventory.getSizeInventory(); i++) { + ItemStack slotStack = mailInventory.getStackInSlot(i); + if (slotStack == null) + continue; + + product = slotStack; + if (doRemove) + mailInventory.setInventorySlotContents(i, null); + break; + } + + if (product != null) + return new ItemStack[] { product }; + else + return new ItemStack[0]; + } + + @Override + public int getSizeInventory() { + return 0; + } + + @Override + public ItemStack getStackInSlot(int var1) { + return null; + } + + @Override + public ItemStack decrStackSize(int var1, int var2) { + return null; + } + + @Override + public ItemStack getStackInSlotOnClosing(int var1) { + return null; + } + + @Override + public void setInventorySlotContents(int var1, ItemStack var2) { + } + + @Override + public int getInventoryStackLimit() { + return 0; + } + + /** + * TODO: just a specialsource workaround + */ + @Override + public boolean isUseableByPlayer(EntityPlayer player) { + return super.isUseableByPlayer(player); + } + + /** + * TODO: just a specialsource workaround + */ + @Override + public boolean hasCustomInventoryName() { + return super.hasCustomInventoryName(); + } + + /** + * TODO: just a specialsource workaround + */ + @Override + public boolean isItemValidForSlot(int slotIndex, ItemStack itemstack) { + return super.isItemValidForSlot(slotIndex, itemstack); + } + + /** + * TODO: just a specialsource workaround + */ + @Override + public boolean canInsertItem(int i, ItemStack itemstack, int j) { + return super.canInsertItem(i, itemstack, j); + } + + /** + * TODO: just a specialsource workaround + */ + @Override + public boolean canExtractItem(int i, ItemStack itemstack, int j) { + return super.canExtractItem(i, itemstack, j); + } + + /** + * TODO: just a specialsource workaround + */ + @Override + public int[] getAccessibleSlotsFromSide(int side) { + return super.getAccessibleSlotsFromSide(side); + } + + @Override + public void openInventory() { + } + + @Override + public void closeInventory() { + } +} diff --git a/forestry_common/mail/forestry/mail/gadgets/MachinePhilatelist.java b/forestry_common/mail/forestry/mail/gadgets/MachinePhilatelist.java new file mode 100755 index 000000000..e83413db3 --- /dev/null +++ b/forestry_common/mail/forestry/mail/gadgets/MachinePhilatelist.java @@ -0,0 +1,151 @@ +/******************************************************************************* + * Copyright 2011-2014 by SirSengir + * + * This work is licensed under a Creative Commons Attribution-NonCommercial-NoDerivs 3.0 Unported License. + * + * To view a copy of this license, visit http://creativecommons.org/licenses/by-nc-nd/3.0/. + ******************************************************************************/ +package forestry.mail.gadgets; + +import net.minecraft.entity.player.EntityPlayer; +import net.minecraft.inventory.IInventory; +import net.minecraft.item.ItemStack; +import net.minecraft.nbt.NBTTagCompound; + +import forestry.api.core.ForestryAPI; +import forestry.api.mail.IStamps; +import forestry.api.mail.PostManager; +import forestry.core.gadgets.TileBase; +import forestry.core.network.GuiId; +import forestry.core.utils.InventoryAdapter; +import forestry.core.utils.StackUtils; + +public class MachinePhilatelist extends TileBase implements IInventory { + + // / CONSTANTS + public static final short SLOT_FILTER = 0; + public static final short SLOT_BUFFER_1 = 1; + public static final short SLOT_BUFFER_COUNT = 27; + + private final InventoryAdapter inventory = new InventoryAdapter(28, "INV"); + + public MachinePhilatelist() { + } + + @Override + public String getInventoryName() { + return "mail.2"; + } + + @Override + public void openGui(EntityPlayer player, TileBase tile) { + player.openGui(ForestryAPI.instance, GuiId.PhilatelistGUI.ordinal(), worldObj, xCoord, yCoord, zCoord); + } + + /* SAVING & LOADING */ + @Override + public void writeToNBT(NBTTagCompound nbttagcompound) { + super.writeToNBT(nbttagcompound); + + inventory.writeToNBT(nbttagcompound); + } + + @Override + public void readFromNBT(NBTTagCompound nbttagcompound) { + super.readFromNBT(nbttagcompound); + + inventory.readFromNBT(nbttagcompound); + } + + // / UPDATING + @Override + public void updateServerSide() { + if (worldObj.getTotalWorldTime() % 20 * 10 != 0) + return; + + ItemStack stamp = null; + + if (inventory.getStackInSlot(SLOT_FILTER) == null) + stamp = PostManager.postRegistry.getPostOffice(worldObj).getAnyStamp(1); + else { + ItemStack filter = inventory.getStackInSlot(SLOT_FILTER); + if (filter.getItem() instanceof IStamps) + stamp = PostManager.postRegistry.getPostOffice(worldObj).getAnyStamp(((IStamps) filter.getItem()).getPostage(filter), 1); + } + + if (stamp == null) + return; + + // Store it. + StackUtils.stowInInventory(stamp, inventory, true, SLOT_BUFFER_1, SLOT_BUFFER_COUNT); + } + + /* IINVENTORY */ + @Override + public int getSizeInventory() { + return inventory.getSizeInventory(); + } + + @Override + public ItemStack getStackInSlot(int i) { + return inventory.getStackInSlot(i); + } + + @Override + public ItemStack decrStackSize(int i, int j) { + return inventory.decrStackSize(i, j); + } + + @Override + public void setInventorySlotContents(int i, ItemStack itemstack) { + inventory.setInventorySlotContents(i, itemstack); + } + + @Override + public ItemStack getStackInSlotOnClosing(int slot) { + return inventory.getStackInSlotOnClosing(slot); + } + + @Override + public void markDirty() { + inventory.markDirty(); + } + + @Override + public int getInventoryStackLimit() { + return inventory.getInventoryStackLimit(); + } + + @Override + public void openInventory() { + } + + @Override + public void closeInventory() { + } + + /** + * TODO: just a specialsource workaround + */ + @Override + public boolean isUseableByPlayer(EntityPlayer player) { + return super.isUseableByPlayer(player); + } + + /** + * TODO: just a specialsource workaround + */ + @Override + public boolean hasCustomInventoryName() { + return super.hasCustomInventoryName(); + } + + /** + * TODO: just a specialsource workaround + */ + @Override + public boolean isItemValidForSlot(int slotIndex, ItemStack itemstack) { + return super.isItemValidForSlot(slotIndex, itemstack); + } + +} diff --git a/forestry_common/mail/forestry/mail/gadgets/MachineTrader.java b/forestry_common/mail/forestry/mail/gadgets/MachineTrader.java new file mode 100755 index 000000000..8b91314ce --- /dev/null +++ b/forestry_common/mail/forestry/mail/gadgets/MachineTrader.java @@ -0,0 +1,402 @@ +/******************************************************************************* + * Copyright 2011-2014 by SirSengir + * + * This work is licensed under a Creative Commons Attribution-NonCommercial-NoDerivs 3.0 Unported License. + * + * To view a copy of this license, visit http://creativecommons.org/licenses/by-nc-nd/3.0/. + ******************************************************************************/ +package forestry.mail.gadgets; + +import java.util.LinkedList; + +import net.minecraft.entity.player.EntityPlayer; +import net.minecraft.init.Items; +import net.minecraft.inventory.IInventory; +import net.minecraft.inventory.ISidedInventory; +import net.minecraft.item.ItemStack; +import net.minecraft.nbt.NBTTagCompound; + +import net.minecraftforge.common.util.ForgeDirection; + +import buildcraft.api.gates.ITrigger; +import buildcraft.api.inventory.ISpecialInventory; + +import forestry.api.core.ForestryAPI; +import forestry.api.mail.IStamps; +import forestry.api.mail.PostManager; +import forestry.core.EnumErrorCode; +import forestry.core.gadgets.TileBase; +import forestry.core.network.EntityNetData; +import forestry.core.network.GuiId; +import forestry.core.proxy.Proxies; +import forestry.core.utils.InventoryAdapter; +import forestry.core.utils.StackUtils; +import forestry.mail.TradeStation; +import forestry.plugins.PluginMail; + +public class MachineTrader extends TileBase implements ISpecialInventory, ISidedInventory { + + @EntityNetData + public String moniker = ""; + + @Override + public String getInventoryName() { + return "mail.1"; + } + + @Override + public void openGui(EntityPlayer player, TileBase tile) { + if (isLinked()) + player.openGui(ForestryAPI.instance, GuiId.TraderGUI.ordinal(), worldObj, xCoord, yCoord, zCoord); + else + player.openGui(ForestryAPI.instance, GuiId.TraderNameGUI.ordinal(), worldObj, xCoord, yCoord, zCoord); + } + + @Override + public void onRemoval() { + if (isLinked()) + PostManager.postRegistry.deleteTradeStation(worldObj, moniker); + } + + /* SAVING & LOADING */ + @Override + public void writeToNBT(NBTTagCompound nbttagcompound) { + super.writeToNBT(nbttagcompound); + + if (moniker != null) + nbttagcompound.setString("MNK", moniker); + } + + @Override + public void readFromNBT(NBTTagCompound nbttagcompound) { + super.readFromNBT(nbttagcompound); + + if (nbttagcompound.hasKey("MNK")) + this.moniker = nbttagcompound.getString("MNK"); + } + + /* UPDATING */ + @Override + public void updateServerSide() { + + if (worldObj.getTotalWorldTime() % 40 * 10 != 0) + return; + + setErrorState(EnumErrorCode.OK); + + if (!hasPaperMin(0.0f) || !hasInputBufMin(0.0f)) { + setErrorState(EnumErrorCode.NORESOURCE); + return; + } + if (!hasPostageMin(2)) { + setErrorState(EnumErrorCode.NOSTAMPS); + return; + } + + } + + /* STATE INFORMATION */ + + public boolean isLinked() { + return getMoniker() != null && !getMoniker().isEmpty(); + } + + private float percentOccupied(int startSlot, int countSlots) { + int max = 0; + int avail = 0; + + IInventory tradeInventory = this.getOrCreateTradeInventory(); + for (int i = startSlot; i < startSlot + countSlots; i++) { + max += 64; + if (tradeInventory.getStackInSlot(i) == null) + continue; + avail += tradeInventory.getStackInSlot(i).stackSize; + } + + return ((float) avail / (float) max); + } + + public boolean hasPaperMin(float percentage) { + return percentOccupied(TradeStation.SLOT_LETTERS_1, TradeStation.SLOT_LETTERS_COUNT) > percentage; + } + + public boolean hasInputBufMin(float percentage) { + return percentOccupied(TradeStation.SLOT_INPUTBUF_1, TradeStation.SLOT_BUFFER_COUNT) > percentage; + } + + public boolean hasOutputBufMin(float percentage) { + return percentOccupied(TradeStation.SLOT_OUTPUTBUF_1, TradeStation.SLOT_BUFFER_COUNT) > percentage; + } + + public boolean hasPostageMin(int postage) { + + int posted = 0; + + IInventory tradeInventory = this.getOrCreateTradeInventory(); + for (int i = TradeStation.SLOT_STAMPS_1; i < TradeStation.SLOT_STAMPS_1 + TradeStation.SLOT_STAMPS_COUNT; i++) { + ItemStack stamp = tradeInventory.getStackInSlot(i); + if (stamp == null) + continue; + if (!(stamp.getItem() instanceof IStamps)) + continue; + + posted += ((IStamps) stamp.getItem()).getPostage(stamp).getValue() * stamp.stackSize; + } + + return posted >= postage; + } + + /* MONIKER */ + public String getMoniker() { + return this.moniker; + } + + public void setMoniker(String moniker) { + + if (Proxies.common.isSimulating(worldObj)) { + if (!PostManager.postRegistry.isValidTradeMoniker(worldObj, moniker)) { + setErrorState(EnumErrorCode.NOTALPHANUMERIC); + return; + } + + if (!PostManager.postRegistry.isAvailableTradeMoniker(worldObj, moniker)) { + setErrorState(EnumErrorCode.NOTUNIQUE); + return; + } + + this.moniker = moniker; + PostManager.postRegistry.getOrCreateTradeStation(worldObj, getOwnerName(), this.moniker); + setErrorState(EnumErrorCode.OK); + sendNetworkUpdate(); + } else + this.moniker = moniker; + } + + /* TRADING */ + public IInventory getOrCreateTradeInventory() { + + // Handle client side + if (!Proxies.common.isSimulating(worldObj)) + return new InventoryAdapter(TradeStation.SLOT_SIZE, "INV"); + + if (this.moniker == null || this.moniker.isEmpty()) + return new InventoryAdapter(TradeStation.SLOT_SIZE, "INV"); + + return PostManager.postRegistry.getOrCreateTradeStation(worldObj, getOwnerName(), this.moniker); + } + + /* ISPECIALINVENTORY */ + @Override + public int addItem(ItemStack stack, boolean doAdd, ForgeDirection from) { + + if (!this.isLinked()) + return 0; + + IInventory inventory = getOrCreateTradeInventory(); + ItemStack tradegood = inventory.getStackInSlot(TradeStation.SLOT_TRADEGOOD); + + // Special handling for paper + if (stack.getItem() == Items.paper) + // Handle paper as resource if its not the trade good or pumped in from above or below + if ((tradegood != null && tradegood.getItem() != Items.paper) || from == ForgeDirection.DOWN || from == ForgeDirection.UP) + return StackUtils.addToInventory(stack, inventory, doAdd, TradeStation.SLOT_LETTERS_1, TradeStation.SLOT_LETTERS_COUNT); + + // Special handling for stamps + if (stack.getItem() instanceof IStamps) + // Handle stamps as resource if its not the trade good or pumped in from above or below + if ((tradegood != null && !(tradegood.getItem() instanceof IStamps)) || from == ForgeDirection.DOWN || from == ForgeDirection.UP) + return StackUtils.addToInventory(stack, inventory, doAdd, TradeStation.SLOT_STAMPS_1, TradeStation.SLOT_STAMPS_COUNT); + + // Everything else + if (tradegood == null) + return 0; + + if (!tradegood.isItemEqual(stack)) + return 0; + + return StackUtils.addToInventory(stack, inventory, doAdd, TradeStation.SLOT_INPUTBUF_1, TradeStation.SLOT_BUFFER_COUNT); + } + + @Override + public ItemStack[] extractItem(boolean doRemove, ForgeDirection from, int maxItemCount) { + + if (!this.isLinked()) + return new ItemStack[0]; + + ItemStack product = null; + IInventory inventory = getOrCreateTradeInventory(); + for (int i = TradeStation.SLOT_OUTPUTBUF_1; i < TradeStation.SLOT_OUTPUTBUF_1 + TradeStation.SLOT_BUFFER_COUNT; i++) { + ItemStack stackSlot = inventory.getStackInSlot(i); + if (stackSlot == null) + continue; + if (stackSlot.stackSize <= 0) + continue; + + product = inventory.decrStackSize(i, 1); + break; + } + + if (product != null) + return new ItemStack[] { product }; + else + return new ItemStack[0]; + } + + /* ISIDEDINVENTORY */ + private static int[] slotIndices; + + public int[] getSizeInventorySide(int side) { + IInventory inventory = getOrCreateTradeInventory(); + if(slotIndices == null) { + slotIndices = new int[inventory.getSizeInventory()]; + for(int i = 0; i < inventory.getSizeInventory(); i++) + slotIndices[i] = i; + } + return slotIndices; + } + + @Override + protected boolean canTakeStackFromSide(int slotIndex, ItemStack itemstack, int side) { + + if(!super.canTakeStackFromSide(slotIndex, itemstack, side)) + return false; + + if(slotIndex >= TradeStation.SLOT_OUTPUTBUF_1 && slotIndex < TradeStation.SLOT_OUTPUTBUF_1 + TradeStation.SLOT_BUFFER_COUNT) + return true; + + return false; + } + + @Override + protected boolean canPutStackFromSide(int slotIndex, ItemStack itemstack, int side) { + if(!super.canPutStackFromSide(slotIndex, itemstack, side)) + return false; + + if (slotIndex >= TradeStation.SLOT_LETTERS_1 && slotIndex < TradeStation.SLOT_LETTERS_1 + TradeStation.SLOT_LETTERS_COUNT + && itemstack.getItem() == Items.paper) { + return true; + } + + if (slotIndex >= TradeStation.SLOT_STAMPS_1 && slotIndex < TradeStation.SLOT_STAMPS_COUNT) { + return itemstack.getItem() instanceof IStamps; + } + + if (slotIndex >= TradeStation.SLOT_INPUTBUF_1 && slotIndex < TradeStation.SLOT_BUFFER_COUNT) { + IInventory inventory = getOrCreateTradeInventory(); + ItemStack tradegood = inventory.getStackInSlot(TradeStation.SLOT_TRADEGOOD); + if(tradegood == null) + return false; + return StackUtils.isIdenticalItem(tradegood, itemstack); + } + + return false; + } + + /* IINVENTORY */ + @Override + public int getSizeInventory() { + return getOrCreateTradeInventory().getSizeInventory(); + } + + @Override + public ItemStack getStackInSlot(int i) { + return getOrCreateTradeInventory().getStackInSlot(i); + } + + @Override + public ItemStack decrStackSize(int i, int j) { + return getOrCreateTradeInventory().decrStackSize(i, j); + } + + @Override + public void setInventorySlotContents(int i, ItemStack itemstack) { + getOrCreateTradeInventory().setInventorySlotContents(i, itemstack); + } + + @Override + public ItemStack getStackInSlotOnClosing(int slot) { + return getOrCreateTradeInventory().getStackInSlotOnClosing(slot); + } + + @Override + public void markDirty() { + getOrCreateTradeInventory().markDirty(); + } + + @Override + public int getInventoryStackLimit() { + return getOrCreateTradeInventory().getInventoryStackLimit(); + } + + @Override + public void openInventory() { + } + + @Override + public void closeInventory() { + } + + /** + * TODO: just a specialsource workaround + */ + @Override + public boolean isUseableByPlayer(EntityPlayer player) { + return super.isUseableByPlayer(player); + } + + /** + * TODO: just a specialsource workaround + */ + @Override + public boolean hasCustomInventoryName() { + return super.hasCustomInventoryName(); + } + + /** + * TODO: just a specialsource workaround + */ + @Override + public boolean isItemValidForSlot(int slotIndex, ItemStack itemstack) { + return super.isItemValidForSlot(slotIndex, itemstack); + } + + /** + * TODO: just a specialsource workaround + */ + @Override + public boolean canInsertItem(int i, ItemStack itemstack, int j) { + return super.canInsertItem(i, itemstack, j); + } + + /** + * TODO: just a specialsource workaround + */ + @Override + public boolean canExtractItem(int i, ItemStack itemstack, int j) { + return super.canExtractItem(i, itemstack, j); + } + + /** + * TODO: just a specialsource workaround + */ + @Override + public int[] getAccessibleSlotsFromSide(int side) { + return super.getAccessibleSlotsFromSide(side); + } + + /* ITRIGGERPROVIDER */ + @Override + public LinkedList getCustomTriggers() { + LinkedList res = new LinkedList(); + res.add(PluginMail.lowPaper25); + res.add(PluginMail.lowPaper10); + res.add(PluginMail.lowInput25); + res.add(PluginMail.lowInput10); + res.add(PluginMail.lowPostage40); + res.add(PluginMail.lowPostage20); + res.add(PluginMail.highBuffer90); + res.add(PluginMail.highBuffer75); + return res; + } + +} diff --git a/forestry_common/mail/forestry/mail/gui/ContainerCatalogue.java b/forestry_common/mail/forestry/mail/gui/ContainerCatalogue.java new file mode 100755 index 000000000..09e9a1854 --- /dev/null +++ b/forestry_common/mail/forestry/mail/gui/ContainerCatalogue.java @@ -0,0 +1,243 @@ +/******************************************************************************* + * Copyright 2011-2014 by SirSengir + * + * This work is licensed under a Creative Commons Attribution-NonCommercial-NoDerivs 3.0 Unported License. + * + * To view a copy of this license, visit http://creativecommons.org/licenses/by-nc-nd/3.0/. + ******************************************************************************/ +package forestry.mail.gui; + +import java.util.EnumSet; +import java.util.Iterator; +import java.util.LinkedHashMap; +import java.util.Set; + +import net.minecraft.entity.player.EntityPlayer; +import net.minecraft.inventory.ICrafting; + +import forestry.api.mail.ITradeStation; +import forestry.api.mail.PostManager; +import forestry.api.mail.TradeStationInfo; +import forestry.core.gui.ContainerForestry; +import forestry.core.gui.IGuiSelectable; +import forestry.core.network.PacketIds; +import forestry.core.network.PacketPayload; +import forestry.core.network.PacketUpdate; +import forestry.core.proxy.Proxies; +import forestry.mail.EnumStationState; +import forestry.mail.network.PacketTradeInfo; + +public class ContainerCatalogue extends ContainerForestry implements IGuiSelectable { + + private final EntityPlayer player; + private final LinkedHashMap stations; + private TradeStationInfo currentTrade = null; + private Iterator iterator = null; + + private int maxItPos = 0; + private int currentItPos = 0; + + private boolean needsSynch = true; + private int currentFilter = 1; + + private static final String[] FILTER_NAMES = new String[] { "all", "online", "offline" }; + @SuppressWarnings("unchecked") + private static final Set[] FILTERS = new EnumSet[] { + EnumSet.noneOf(EnumStationState.class), + EnumSet.of(EnumStationState.OK), + EnumSet.of(EnumStationState.INSUFFICIENT_OFFER, EnumStationState.INSUFFICIENT_TRADE_GOOD, EnumStationState.INSUFFICIENT_BUFFER, EnumStationState.INSUFFICIENT_PAPER, EnumStationState.INSUFFICIENT_STAMPS) + }; + + public ContainerCatalogue(EntityPlayer player) { + super(player.inventory); + this.player = player; + + // Filter out any trade stations which do not actually offer anything. + stations = new LinkedHashMap(); + rebuildStationsList(); + } + + public int getMaxCount() { return maxItPos; } + public int getCurrentPos() { return currentItPos; } + + public String getFilterIdent() { return FILTER_NAMES[currentFilter]; } + + private void rebuildStationsList() { + stations.clear(); + for(ITradeStation station : PostManager.postRegistry.getPostOffice(player.worldObj).getActiveTradeStations(player.worldObj).values()) { + TradeStationInfo info = station.getTradeInfo(); + if(info.tradegood == null) + continue; + + if(!FILTERS[currentFilter].isEmpty()) { + if(!FILTERS[currentFilter].contains(info.state)) + continue; + } + + stations.put(station.getMoniker(), station); + } + maxItPos = stations.size(); + resetIteration(); + + } + + private void resetIteration() { + if(!stations.isEmpty()) { + iterator = stations.values().iterator(); + updateTradeInfo(iterator.next()); + } else + updateTradeInfo(null); + + currentItPos = 1; + } + + public void advanceIteration() { + + if(!Proxies.common.isSimulating(player.worldObj)) { + sendSelection(true); + return; + } + + if(stations.isEmpty()) + return; + + if(iterator.hasNext()) { + currentItPos++; + updateTradeInfo(iterator.next()); + } else + resetIteration(); + } + + public void regressIteration() { + + if(!Proxies.common.isSimulating(player.worldObj)) { + sendSelection(false); + return; + } + + if(stations.isEmpty()) + return; + + iterator = stations.values().iterator(); + ITradeStation previous = null; + currentItPos = 0; + + while(iterator.hasNext()) { + ITradeStation current = iterator.next(); + if(!current.getMoniker().equals(currentTrade.moniker)) { + currentItPos++; + previous = current; + continue; + } + + if(previous == null) { + Iterator it = stations.values().iterator(); + currentItPos = stations.size(); + while(it.hasNext()) + previous = it.next(); + + } + updateTradeInfo(previous); + break; + } + } + + public void cycleFilter() { + if(!Proxies.common.isSimulating(player.worldObj)) { + PacketPayload payload = new PacketPayload(1, 0, 0); + payload.intPayload[0] = 2; + PacketUpdate packet = new PacketUpdate(PacketIds.GUI_SELECTION_CHANGE, payload); + Proxies.net.sendToServer(packet); + return; + } + + if(currentFilter < FILTERS.length -1) + currentFilter++; + else + currentFilter = 0; + + rebuildStationsList(); + } + + private void sendSelection(boolean advance) { + PacketPayload payload = new PacketPayload(1, 0, 0); + payload.intPayload[0] = advance ? 0 : 1; + PacketUpdate packet = new PacketUpdate(PacketIds.GUI_SELECTION_CHANGE, payload); + Proxies.net.sendToServer(packet); + } + + /* Managing Trade info */ + public void updateTradeInfo(ITradeStation station) { + // Updating is done by the server. + if (!Proxies.common.isSimulating(player.worldObj)) + return; + + if(station != null) + setTradeInfo(station.getTradeInfo()); + else + setTradeInfo(null); + needsSynch = true; + } + + public void handleTradeInfoUpdate(PacketTradeInfo packet) { + setTradeInfo(packet.tradeInfo); + } + + public TradeStationInfo getTradeInfo() { + return currentTrade; + } + + private void setTradeInfo(TradeStationInfo info) { + currentTrade = info; + } + + @Override + public void detectAndSendChanges() { + super.detectAndSendChanges(); + + if(needsSynch) { + for (int i = 0; i < crafters.size(); i++) { + ICrafting crafter = (ICrafting)crafters.get(i); + crafter.sendProgressBarUpdate(this, 0, currentItPos); + crafter.sendProgressBarUpdate(this, 1, maxItPos); + crafter.sendProgressBarUpdate(this, 2, currentFilter); + } + + Proxies.net.sendToPlayer(new PacketTradeInfo(PacketIds.TRADING_INFO, currentTrade), player); + needsSynch = false; + } + } + + @Override + public void updateProgressBar(int i, int j) { + switch(i) { + case 0: + currentItPos = j; + break; + case 1: + maxItPos = j; + break; + case 2: + currentFilter = j; + break; + } + } + + @Override + public void handleSelectionChange(EntityPlayer player, PacketUpdate packet) { + + if (packet.payload.intPayload[0] == 0) { + advanceIteration(); + } else if(packet.payload.intPayload[0] == 1) + regressIteration(); + else if(packet.payload.intPayload[0] == 2) + cycleFilter(); + + needsSynch = true; + } + + @Override + public void setSelection(PacketUpdate packet) { + } + +} diff --git a/forestry_common/mail/forestry/mail/gui/ContainerLetter.java b/forestry_common/mail/forestry/mail/gui/ContainerLetter.java new file mode 100755 index 000000000..6e0db3e34 --- /dev/null +++ b/forestry_common/mail/forestry/mail/gui/ContainerLetter.java @@ -0,0 +1,208 @@ +/******************************************************************************* + * Copyright 2011-2014 by SirSengir + * + * This work is licensed under a Creative Commons Attribution-NonCommercial-NoDerivs 3.0 Unported License. + * + * To view a copy of this license, visit http://creativecommons.org/licenses/by-nc-nd/3.0/. + ******************************************************************************/ +package forestry.mail.gui; + +import java.util.Iterator; +import java.util.Locale; + +import net.minecraft.entity.player.EntityPlayer; +import net.minecraft.item.ItemStack; +import net.minecraft.world.World; + +import forestry.api.mail.ILetter; +import forestry.api.mail.IPostalCarrier; +import forestry.api.mail.ITradeStation; +import forestry.api.mail.MailAddress; +import forestry.api.mail.PostManager; +import forestry.api.mail.TradeStationInfo; +import forestry.core.gui.ContainerItemInventory; +import forestry.core.gui.slots.SlotClosed; +import forestry.core.gui.slots.SlotCustom; +import forestry.core.network.PacketIds; +import forestry.core.network.PacketPayload; +import forestry.core.network.PacketUpdate; +import forestry.core.proxy.Proxies; +import forestry.mail.EnumAddressee; +import forestry.mail.Letter; +import forestry.mail.items.ItemLetter; +import forestry.mail.items.ItemLetter.LetterInventory; +import forestry.mail.items.ItemStamps; +import forestry.mail.network.PacketTradeInfo; + +public class ContainerLetter extends ContainerItemInventory { + + private final LetterInventory letterInventory; + private String carrier = EnumAddressee.PLAYER.toString().toLowerCase(Locale.ENGLISH); + private TradeStationInfo tradeInfo = null; + + public ContainerLetter(EntityPlayer player, LetterInventory inventory) { + super(inventory, player); + + letterInventory = inventory; + + // Rip open delivered mails + if (Proxies.common.isSimulating(player.worldObj) && letterInventory.getLetter().isProcessed() && inventory.parent != null + && ItemLetter.getState(inventory.parent.getItemDamage()) < 2) + inventory.parent.setItemDamage(ItemLetter.encodeMeta(2, ItemLetter.getSize(inventory.parent.getItemDamage()))); + + // Init slots + Object[] validStamps = new Object[] { ItemStamps.class }; + if (letterInventory.getLetter().isProcessed()) + validStamps = new Object[] {}; + + // Stamps + for (int i = 0; i < 4; i++) + addSlot(new SlotCustom(inventory, Letter.SLOT_POSTAGE_1 + i, 150, 14 + i * 19, validStamps).setStackLimit(1)); + + // Attachments + if (!letterInventory.getLetter().isProcessed()) + for (int i = 0; i < 2; i++) + for (int j = 0; j < 9; j++) + addSlot(new SlotCustom(inventory, Letter.SLOT_ATTACHMENT_1 + j + i * 9, 17 + j * 18, 98 + i * 18, true, new Object[] { ItemLetter.class })); + else + for (int i = 0; i < 2; i++) + for (int j = 0; j < 9; j++) + addSlot(new SlotClosed(inventory, Letter.SLOT_ATTACHMENT_1 + j + i * 9, 17 + j * 18, 98 + i * 18)); + + // Player inventory + for (int i = 0; i < 3; i++) + for (int j = 0; j < 9; j++) + addSecuredSlot(player.inventory, j + i * 9 + 9, 17 + j * 18, 145 + i * 18); + // Player hotbar + for (int i = 0; i < 9; i++) + addSecuredSlot(player.inventory, i, 17 + i * 18, 203); + + // Set recipient type + if (letterInventory.getLetter() != null) + if (letterInventory.getLetter().getRecipients() != null) + if (letterInventory.getLetter().getRecipients().length > 0) + this.carrier = letterInventory.getLetter().getRecipients()[0].getType(); + } + + @Override + public void onContainerClosed(EntityPlayer entityplayer) { + + if (Proxies.common.isSimulating(entityplayer.worldObj)) { + ILetter letter = letterInventory.getLetter(); + if (!letter.isProcessed()) + letter.setSender(new MailAddress(entityplayer.getGameProfile().getId())); + } + + super.onContainerClosed(entityplayer); + } + + @Override + protected boolean isAcceptedItem(EntityPlayer player, ItemStack stack) { + return true; + } + + public ILetter getLetter() { + return letterInventory.getLetter(); + } + + public void setCarrierType(String type) { + this.carrier = type; + } + + public String getCarrierType() { + return this.carrier; + } + + public void advanceCarrierType() { + Iterator it = PostManager.postRegistry.getRegisteredCarriers().values().iterator(); + while(it.hasNext()) { + if(it.next().getUID().equals(carrier)) + break; + } + + IPostalCarrier postal = null; + if(it.hasNext()) + postal = it.next(); + else + postal = PostManager.postRegistry.getRegisteredCarriers().values().iterator().next(); + + setCarrierType(postal.getUID()); + } + + public void setRecipient(MailAddress address) { + getLetter().setRecipient(address); + carrier = address.getType(); + + // / Send to server + PacketPayload payload = new PacketPayload(0, 0, 2); + payload.stringPayload[0] = this.getRecipient().getIdentifier(); + payload.stringPayload[1] = this.carrier; + + PacketUpdate packet = new PacketUpdate(PacketIds.LETTER_RECIPIENT, payload); + Proxies.net.sendToServer(packet); + } + + public void handleSetRecipient(EntityPlayer player, PacketUpdate packet) { + MailAddress recipient = new MailAddress(packet.payload.stringPayload[0], packet.payload.stringPayload[1]); + getLetter().setRecipient(recipient); + // Update the trading info + updateTradeInfo(player.worldObj, recipient); + // Update trade info on client + Proxies.net.sendToPlayer(new PacketTradeInfo(PacketIds.TRADING_INFO, tradeInfo), player); + } + + public MailAddress getRecipient() { + if (getLetter().getRecipients().length > 0) + return getLetter().getRecipients()[0]; + else + return null; + } + + public String getText() { + return getLetter().getText(); + } + + public void setText(String text) { + getLetter().setText(text); + + // / Send to server + PacketPayload payload = new PacketPayload(0, 0, 1); + payload.stringPayload[0] = text; + + PacketUpdate packet = new PacketUpdate(PacketIds.LETTER_TEXT, payload); + Proxies.net.sendToServer(packet); + + } + + public void handleSetText(PacketUpdate packet) { + getLetter().setText(packet.payload.stringPayload[0]); + } + + /* Managing Trade info */ + public void updateTradeInfo(World world, MailAddress address) { + // Updating is done by the server. + if (!Proxies.common.isSimulating(world)) + return; + + if (!address.getType().equals(EnumAddressee.TRADER.toString().toLowerCase(Locale.ENGLISH))) + return; + + ITradeStation station = PostManager.postRegistry.getTradeStation(world, address.getIdentifier()); + if (station == null) + return; + + setTradeInfo(station.getTradeInfo()); + } + + public void handleTradeInfoUpdate(PacketTradeInfo packet) { + this.setTradeInfo(packet.tradeInfo); + } + + public TradeStationInfo getTradeInfo() { + return this.tradeInfo; + } + + private void setTradeInfo(TradeStationInfo info) { + this.tradeInfo = info; + } +} diff --git a/forestry_common/mail/forestry/mail/gui/ContainerMailbox.java b/forestry_common/mail/forestry/mail/gui/ContainerMailbox.java new file mode 100755 index 000000000..6c66a7c5c --- /dev/null +++ b/forestry_common/mail/forestry/mail/gui/ContainerMailbox.java @@ -0,0 +1,61 @@ +/******************************************************************************* + * Copyright 2011-2014 by SirSengir + * + * This work is licensed under a Creative Commons Attribution-NonCommercial-NoDerivs 3.0 Unported License. + * + * To view a copy of this license, visit http://creativecommons.org/licenses/by-nc-nd/3.0/. + ******************************************************************************/ +package forestry.mail.gui; + +import net.minecraft.entity.player.EntityPlayer; +import net.minecraft.entity.player.InventoryPlayer; +import net.minecraft.inventory.IInventory; +import net.minecraft.inventory.Slot; +import net.minecraft.item.ItemStack; + +import forestry.core.gui.ContainerForestry; +import forestry.core.gui.slots.SlotClosed; +import forestry.core.proxy.Proxies; +import forestry.mail.POBox; +import forestry.mail.gadgets.MachineMailbox; +import forestry.plugins.PluginMail; + +public class ContainerMailbox extends ContainerForestry { + + MachineMailbox mailbox; + POBox mailinventory; + + public ContainerMailbox(InventoryPlayer player, MachineMailbox tile) { + super(tile); + + // Mailbox contents + this.mailbox = tile; + + IInventory inv = mailbox.getOrCreateMailInventory(); + if (inv instanceof POBox) + mailinventory = (POBox) inv; + + for (int i = 0; i < 7; i++) + for (int j = 0; j < 12; j++) + addSlot(new SlotClosed(inv, j + i * 9, 8 + j * 18, 8 + i * 18)); + + // Player inventory + for (int i = 0; i < 3; i++) + for (int j = 0; j < 9; j++) + addSlot(new Slot(player, j + i * 9 + 9, 35 + j * 18, 145 + i * 18)); + // Player hotbar + for (int i = 0; i < 9; i++) + addSlot(new Slot(player, i, 35 + i * 18, 203)); + + } + + @Override + public ItemStack slotClick(int slotIndex, int button, int par3, EntityPlayer player) { + ItemStack stack = super.slotClick(slotIndex, button, par3, player); + + if (Proxies.common.isSimulating(player.worldObj) && mailinventory != null) + PluginMail.proxy.setPOBoxInfo(mailbox.getWorldObj(), mailbox.getOwnerName(), mailinventory.getPOBoxInfo()); + + return stack; + } +} diff --git a/forestry_common/mail/forestry/mail/gui/ContainerPhilatelist.java b/forestry_common/mail/forestry/mail/gui/ContainerPhilatelist.java new file mode 100755 index 000000000..7420a4234 --- /dev/null +++ b/forestry_common/mail/forestry/mail/gui/ContainerPhilatelist.java @@ -0,0 +1,42 @@ +/******************************************************************************* + * Copyright 2011-2014 by SirSengir + * + * This work is licensed under a Creative Commons Attribution-NonCommercial-NoDerivs 3.0 Unported License. + * + * To view a copy of this license, visit http://creativecommons.org/licenses/by-nc-nd/3.0/. + ******************************************************************************/ +package forestry.mail.gui; + +import net.minecraft.entity.player.InventoryPlayer; +import net.minecraft.inventory.Slot; + +import forestry.core.gui.ContainerForestry; +import forestry.core.gui.slots.SlotClosed; +import forestry.core.gui.slots.SlotCustom; +import forestry.mail.gadgets.MachinePhilatelist; +import forestry.mail.items.ItemStamps; + +public class ContainerPhilatelist extends ContainerForestry { + + public ContainerPhilatelist(InventoryPlayer player, MachinePhilatelist tile) { + super(tile); + + // Filter + addSlot(new SlotCustom(tile, MachinePhilatelist.SLOT_FILTER, 80, 19, new Object[] { ItemStamps.class })); + + // Collected Stamps + for (int i = 0; i < 3; i++) + for (int j = 0; j < 9; j++) + addSlot(new SlotClosed(tile, j + i * 9 + MachinePhilatelist.SLOT_BUFFER_1, 8 + j * 18, 46 + i * 18)); + + // Player inventory + for (int i = 0; i < 3; i++) + for (int j = 0; j < 9; j++) + addSlot(new Slot(player, j + i * 9 + 9, 8 + j * 18, 111 + i * 18)); + // Player hotbar + for (int i = 0; i < 9; i++) + addSlot(new Slot(player, i, 8 + i * 18, 169)); + + } + +} diff --git a/forestry_common/mail/forestry/mail/gui/ContainerTradeName.java b/forestry_common/mail/forestry/mail/gui/ContainerTradeName.java new file mode 100755 index 000000000..f4703d375 --- /dev/null +++ b/forestry_common/mail/forestry/mail/gui/ContainerTradeName.java @@ -0,0 +1,59 @@ +/******************************************************************************* + * Copyright 2011-2014 by SirSengir + * + * This work is licensed under a Creative Commons Attribution-NonCommercial-NoDerivs 3.0 Unported License. + * + * To view a copy of this license, visit http://creativecommons.org/licenses/by-nc-nd/3.0/. + ******************************************************************************/ +package forestry.mail.gui; + +import net.minecraft.entity.player.EntityPlayer; +import net.minecraft.entity.player.InventoryPlayer; + +import forestry.core.gui.ContainerForestry; +import forestry.core.network.PacketIds; +import forestry.core.network.PacketPayload; +import forestry.core.network.PacketUpdate; +import forestry.core.proxy.Proxies; +import forestry.core.utils.InventoryAdapter; +import forestry.mail.gadgets.MachineTrader; + +public class ContainerTradeName extends ContainerForestry { + + boolean isLinked; + MachineTrader machine; + + public ContainerTradeName(InventoryPlayer player, MachineTrader tile) { + super(new InventoryAdapter(0, "Empty")); + machine = tile; + isLinked = machine.isLinked(); + } + + public String getMoniker() { + return machine.getMoniker(); + } + + public void setMoniker(String moniker) { + + if (moniker == null || moniker.isEmpty()) + return; + + PacketPayload payload = new PacketPayload(0, 0, 1); + payload.stringPayload[0] = moniker; + + PacketUpdate packet = new PacketUpdate(PacketIds.TRADING_MONIKER_SET, payload); + Proxies.net.sendToServer(packet); + + machine.setMoniker(moniker); + } + + public void handleSetMoniker(PacketUpdate packet) { + machine.setMoniker(packet.payload.stringPayload[0]); + } + + @Override + public boolean canInteractWith(EntityPlayer entityplayer) { + return true; + } + +} diff --git a/forestry_common/mail/forestry/mail/gui/ContainerTrader.java b/forestry_common/mail/forestry/mail/gui/ContainerTrader.java new file mode 100755 index 000000000..4b3ab69e6 --- /dev/null +++ b/forestry_common/mail/forestry/mail/gui/ContainerTrader.java @@ -0,0 +1,78 @@ +/******************************************************************************* + * Copyright 2011-2014 by SirSengir + * + * This work is licensed under a Creative Commons Attribution-NonCommercial-NoDerivs 3.0 Unported License. + * + * To view a copy of this license, visit http://creativecommons.org/licenses/by-nc-nd/3.0/. + ******************************************************************************/ +package forestry.mail.gui; + +import net.minecraft.entity.player.InventoryPlayer; +import net.minecraft.init.Items; +import net.minecraft.inventory.IInventory; +import net.minecraft.inventory.Slot; + +import forestry.core.gui.ContainerForestry; +import forestry.core.gui.slots.SlotClosed; +import forestry.core.gui.slots.SlotCustom; +import forestry.mail.TradeStation; +import forestry.mail.gadgets.MachineTrader; +import forestry.mail.items.ItemStamps; + +public class ContainerTrader extends ContainerForestry { + + private final MachineTrader machine; + + public ContainerTrader(InventoryPlayer player, MachineTrader tile) { + super(tile); + + machine = tile; + IInventory inventory = machine.getOrCreateTradeInventory(); + + // Trade good + this.addSlot(new Slot(inventory, TradeStation.SLOT_TRADEGOOD, 78, 109)); + + // Exchange + for (int i = 0; i < 2; i++) + for (int j = 0; j < 2; j++) + addSlot(new Slot(inventory, TradeStation.SLOT_EXCHANGE_1 + j + i * 2, 69 + j * 18, 55 + i * 18)); + + // Stamps + for (int i = 0; i < 2; i++) + for (int j = 0; j < 2; j++) + addSlot(new SlotCustom(inventory, TradeStation.SLOT_STAMPS_1 + j + i * 2, 15 + j * 18, 37 + i * 18, new Object[] { ItemStamps.class })); + + // Letters + for (int i = 0; i < 3; i++) + for (int j = 0; j < 2; j++) + addSlot(new SlotCustom(inventory, TradeStation.SLOT_LETTERS_1 + j + i * 2, 15 + j * 18, 73 + i * 18, new Object[] { Items.paper })); + + // Input buffer + for (int i = 0; i < 6; i++) + for (int j = 0; j < 2; j++) + addSlot(new Slot(inventory, TradeStation.SLOT_INPUTBUF_1 + j + i * 2, 123 + j * 18, 19 + i * 18)); + + // Output buffer + for (int i = 0; i < 6; i++) + for (int j = 0; j < 2; j++) + addSlot(new SlotClosed(inventory, TradeStation.SLOT_OUTPUTBUF_1 + j + i * 2, 177 + j * 18, 19 + i * 18)); + + // Player inventory + for (int i = 0; i < 3; i++) + for (int j = 0; j < 9; j++) + addSlot(new Slot(player, j + i * 9 + 9, 33 + j * 18, 138 + i * 18)); + // Player hotbar + for (int i = 0; i < 9; i++) + addSlot(new Slot(player, i, 33 + i * 18, 196)); + + } + + public boolean isLinked() { + return getMoniker() != null && !getMoniker().isEmpty(); + } + + public String getMoniker() { + return machine.getMoniker(); + } + +} diff --git a/forestry_common/mail/forestry/mail/gui/GuiCatalogue.java b/forestry_common/mail/forestry/mail/gui/GuiCatalogue.java new file mode 100755 index 000000000..4a98632eb --- /dev/null +++ b/forestry_common/mail/forestry/mail/gui/GuiCatalogue.java @@ -0,0 +1,144 @@ +/******************************************************************************* + * Copyright 2011-2014 by SirSengir + * + * This work is licensed under a Creative Commons Attribution-NonCommercial-NoDerivs 3.0 Unported License. + * + * To view a copy of this license, visit http://creativecommons.org/licenses/by-nc-nd/3.0/. + ******************************************************************************/ +package forestry.mail.gui; + +import java.util.Locale; + +import net.minecraft.client.gui.GuiButton; +import net.minecraft.client.gui.GuiScreen; +import net.minecraft.entity.player.EntityPlayer; +import net.minecraft.util.ResourceLocation; + +import org.lwjgl.input.Keyboard; +import org.lwjgl.opengl.GL11; + +import forestry.api.mail.TradeStationInfo; +import forestry.core.config.SessionVars; +import forestry.core.gadgets.TileForestry; +import forestry.core.gui.GuiForestry; +import forestry.core.utils.StringUtil; +import forestry.mail.EnumAddressee; + +public class GuiCatalogue extends GuiForestry { + + GuiButton buttonTrade; + GuiButton buttonClose; + + GuiButton buttonFilter; + GuiButton buttonCopy; + + ContainerCatalogue container; + + public GuiCatalogue(EntityPlayer player) { + super(new ResourceLocation("textures/gui/book.png"), new ContainerCatalogue(player)); + this.xSize = 192; + this.ySize = 192; + container = (ContainerCatalogue)inventorySlots; + } + + @SuppressWarnings("unchecked") + @Override + public void initGui() { + super.initGui(); + + buttonList.clear(); + Keyboard.enableRepeatEvents(true); + + //buttonList.add(buttonTrade = new GuiButton(1, width / 2 - 100, 4 + ySize, 98, 20, StringUtil.localize("gui.mail.catalogue.trade"))); + //buttonList.add(buttonClose = new GuiButton(0, (width - 100) / 2, 4 + ySize, 98, 20, StringUtil.localize("gui.mail.catalogue.close"))); + + buttonList.add(new GuiButton(2, width / 2 + 44, guiTop + 150, 12, 20, ">")); + buttonList.add(new GuiButton(3, width / 2 - 58, guiTop + 150, 12, 20, "<")); + + buttonList.add(buttonFilter = new GuiButton(4, (width / 2) - 44, guiTop + 150, 42, 20, StringUtil.localize("gui.mail.filter.all"))); + + buttonList.add(buttonCopy = new GuiButton(5, width / 2, guiTop + 150, 42, 20, StringUtil.localize("gui.mail.address.copy"))); + } + + @Override + public void onGuiClosed() { + Keyboard.enableRepeatEvents(false); + super.onGuiClosed(); + } + + @Override + protected void drawGuiContainerBackgroundLayer(float var1, int mouseX, int mouseY) { + super.drawGuiContainerBackgroundLayer(var1, mouseX, mouseY); + + fontRendererObj.drawString(String.format("%s / %s", container.getCurrentPos(), container.getMaxCount()), guiLeft + xSize - 72, guiTop + 12, fontColor.get("gui.book")); + + if(container.getTradeInfo() != null) + drawTradePreview(guiLeft + 38, guiTop + 30); + else + drawNoTrade(guiLeft + 38, guiTop + 30); + + buttonFilter.displayString = StringUtil.localize("gui.mail.filter." + container.getFilterIdent()); + if(container.getTradeInfo() == null || !container.getTradeInfo().state.isOk()) + buttonCopy.enabled = false; + else + buttonCopy.enabled = true; + } + + private void drawNoTrade(int x, int y) { + fontRendererObj.drawSplitString(StringUtil.localize("gui.mail.notrades"), x, y + 18, 119, fontColor.get("gui.book")); + } + + private void drawTradePreview(int x, int y) { + + fontRendererObj.drawString("\u00A7l\u00A7n" + container.getTradeInfo().moniker, x, y, fontColor.get("gui.book")); + + TradeStationInfo info = container.getTradeInfo(); + fontRendererObj.drawString(String.format(StringUtil.localize("gui.mail.willtrade"), info.owner), x, y + 18, fontColor.get("gui.book")); + + itemRender.renderItemAndEffectIntoGUI(fontRendererObj, mc.renderEngine, info.tradegood, x, y + 28); + itemRender.renderItemOverlayIntoGUI(fontRendererObj, mc.renderEngine, info.tradegood, x, y + 28); + + GL11.glDisable(GL11.GL_LIGHTING); + fontRendererObj.drawString(StringUtil.localize("gui.mail.tradefor"), x, y + 46, fontColor.get("gui.book")); + GL11.glEnable(GL11.GL_LIGHTING); + for (int i = 0; i < container.getTradeInfo().required.length; i++) { + GL11.glDisable(GL11.GL_LIGHTING); + itemRender.renderItemAndEffectIntoGUI(fontRendererObj, mc.renderEngine, info.required[i], x + i * 18, y + 56); + itemRender.renderItemOverlayIntoGUI(fontRendererObj, mc.renderEngine, info.required[i], x + i * 18, y + 56); + GL11.glEnable(GL11.GL_LIGHTING); + } + + GL11.glDisable(GL11.GL_LIGHTING); + if(info.state.isOk()) + fontRendererObj.drawSplitString("\u00A72" + StringUtil.localize("chat.mail." + info.state.getIdentifier()), x, y + 82, 119, fontColor.get("gui.book")); + else + fontRendererObj.drawSplitString("\u00A74" + StringUtil.localize("chat.mail." + info.state.getIdentifier()), x, y + 82, 119, fontColor.get("gui.book")); + GL11.glEnable(GL11.GL_LIGHTING); + } + + @Override + protected void actionPerformed(GuiButton button) { + switch(button.id) { + case 0: + mc.displayGuiScreen((GuiScreen)null); + break; + case 2: + container.advanceIteration(); + break; + case 3: + container.regressIteration(); + break; + case 4: + container.cycleFilter(); + break; + case 5: + TradeStationInfo info = container.getTradeInfo(); + if(info != null) { + SessionVars.setStringVar("mail.letter.recipient", info.moniker); + SessionVars.setStringVar("mail.letter.addressee", EnumAddressee.TRADER.toString().toLowerCase(Locale.ENGLISH)); + } + mc.displayGuiScreen((GuiScreen)null); + break; + } + } +} diff --git a/forestry_common/mail/forestry/mail/gui/GuiLetter.java b/forestry_common/mail/forestry/mail/gui/GuiLetter.java new file mode 100755 index 000000000..a53a53f9a --- /dev/null +++ b/forestry_common/mail/forestry/mail/gui/GuiLetter.java @@ -0,0 +1,244 @@ +/******************************************************************************* + * Copyright 2011-2014 by SirSengir + * + * This work is licensed under a Creative Commons Attribution-NonCommercial-NoDerivs 3.0 Unported License. + * + * To view a copy of this license, visit http://creativecommons.org/licenses/by-nc-nd/3.0/. + ******************************************************************************/ +package forestry.mail.gui; + +import java.util.Locale; + +import net.minecraft.client.gui.GuiTextField; +import net.minecraft.entity.player.EntityPlayer; + +import org.lwjgl.input.Keyboard; +import org.lwjgl.opengl.GL11; + +import forestry.api.mail.IPostalCarrier; +import forestry.api.mail.MailAddress; +import forestry.api.mail.PostManager; +import forestry.core.config.Defaults; +import forestry.core.config.SessionVars; +import forestry.core.gadgets.TileForestry; +import forestry.core.gui.GuiForestry; +import forestry.core.gui.GuiTextBox; +import forestry.core.gui.widgets.Widget; +import forestry.core.proxy.Proxies; +import forestry.core.utils.StringUtil; +import forestry.mail.EnumAddressee; +import forestry.mail.items.ItemLetter.LetterInventory; + +public class GuiLetter extends GuiForestry { + + protected class AddresseeSlot extends Widget { + + public AddresseeSlot(int xPos, int yPos) { + super(widgetManager, xPos, yPos); + this.width = 26; + this.height = 15; + } + + @Override + public void draw(int startX, int startY) { + + GL11.glColor4f(1.0f, 1.0f, 1.0f, 1.0F); + //mc.renderEngine.bindTexture(Defaults.TEXTURE_PATH_GUI + "/letter.png"); + IPostalCarrier carrier = PostManager.postRegistry.getCarrier(container.getCarrierType()); + if(carrier != null) + drawTexturedModelRectFromIcon(startX + xPos, startY + yPos - 5, carrier.getIcon(), 26, 26); + + } + + @Override + protected String getLegacyTooltip(EntityPlayer player) { + return StringUtil.localize("gui.addressee." + container.getCarrierType().toLowerCase(Locale.ENGLISH)); + } + + @Override + public void handleMouseClick(int mouseX, int mouseY, int mouseButton) { + if(!isProcessedLetter) + container.advanceCarrierType(); + } + + } + + private final boolean isProcessedLetter; + private boolean checkedSessionVars; + + private GuiTextField address; + private GuiTextBox text; + + boolean addressFocus; + boolean textFocus; + + private final ContainerLetter container; + + public GuiLetter(EntityPlayer player, LetterInventory inventory) { + super(Defaults.TEXTURE_PATH_GUI + "/letter.png", new ContainerLetter(player, inventory), inventory); + this.xSize = 194; + this.ySize = 227; + + this.container = (ContainerLetter) inventorySlots; + this.isProcessedLetter = container.getLetter().isProcessed(); + this.widgetManager.add(new AddresseeSlot(16, 12)); + } + + @Override + public void initGui() { + super.initGui(); + + Keyboard.enableRepeatEvents(true); + + address = new GuiTextField(this.fontRendererObj, guiLeft + 46, guiTop + 13, 93, 13); + if (container.getRecipient() != null) { + address.setText(container.getRecipient().getIdentifier()); + this.setRecipient(container.getRecipient().getIdentifier(), container.getCarrierType()); + } + + text = new GuiTextBox(this.fontRendererObj, guiLeft + 17, guiTop + 31, 122, 57); + text.setMaxStringLength(128); + if (!container.getText().isEmpty()) + text.setText(container.getText()); + } + + @Override + protected void keyTyped(char eventCharacter, int eventKey) { + + // Set focus or enter text into address + if (this.address.isFocused()) { + if (eventKey == Keyboard.KEY_RETURN) + this.address.setFocused(false); + else + this.address.textboxKeyTyped(eventCharacter, eventKey); + return; + } + + if (this.text.isFocused()) { + if (eventKey == Keyboard.KEY_RETURN) { + if(Proxies.common.isShiftDown()) + text.setText(text.getText() + "\n"); + else + this.text.setFocused(false); + } else if(eventKey == Keyboard.KEY_DOWN) { + text.advanceLine(); + } else if(eventKey == Keyboard.KEY_UP) { + text.regressLine(); + } else if(text.moreLinesAllowed() || eventKey == Keyboard.KEY_DELETE || eventKey == Keyboard.KEY_BACK) + this.text.textboxKeyTyped(eventCharacter, eventKey); + return; + } + + super.keyTyped(eventCharacter, eventKey); + } + + @Override + protected void mouseClicked(int par1, int par2, int mouseButton) { + super.mouseClicked(par1, par2, mouseButton); + + this.address.mouseClicked(par1, par2, mouseButton); + this.text.mouseClicked(par1, par2, mouseButton); + + } + + @Override + protected void drawGuiContainerBackgroundLayer(float var1, int mouseX, int mouseY) { + + if(!isProcessedLetter && !checkedSessionVars) { + checkedSessionVars = true; + setFromSessionVars(); + } + + // Check for focus changes + if (addressFocus != address.isFocused()) + setRecipient(this.address.getText(), container.getCarrierType()); + addressFocus = address.isFocused(); + if (textFocus != text.isFocused()) + setText(); + textFocus = text.isFocused(); + + super.drawGuiContainerBackgroundLayer(var1, mouseX, mouseY); + + if (this.isProcessedLetter) { + fontRendererObj.drawString(address.getText(), guiLeft + 49, guiTop + 16, fontColor.get("gui.mail.lettertext")); + fontRendererObj.drawSplitString(text.getText(), guiLeft + 20, guiTop + 34, 119, fontColor.get("gui.mail.lettertext")); + } else { + address.drawTextBox(); + if (container.getCarrierType().equals(EnumAddressee.TRADER.toString().toLowerCase(Locale.ENGLISH))) + drawTradePreview(guiLeft + 18, guiTop + 32); + else + text.drawTextBox(); + } + } + + private void drawTradePreview(int x, int y) { + + String infoString = null; + if (container.getTradeInfo() == null) + infoString = "gui.mail.notrader"; + else if (container.getTradeInfo().tradegood == null) + infoString = "gui.mail.nothingtotrade"; + else if (!container.getTradeInfo().state.isOk()) + infoString = "chat.mail." + container.getTradeInfo().state.getIdentifier(); + + if (infoString != null) { + fontRendererObj.drawSplitString(StringUtil.localize(infoString), x, y, 119, fontColor.get("gui.mail.lettertext")); + return; + } + + fontRendererObj.drawString(StringUtil.localize("gui.mail.pleasesend"), x, y, fontColor.get("gui.mail.lettertext")); + + itemRender.renderItemAndEffectIntoGUI(fontRendererObj, mc.renderEngine, container.getTradeInfo().tradegood, x, y + 10); + itemRender.renderItemOverlayIntoGUI(fontRendererObj, mc.renderEngine, container.getTradeInfo().tradegood, x, y + 10); + + GL11.glDisable(GL11.GL_LIGHTING); + fontRendererObj.drawString(StringUtil.localize("gui.mail.foreveryattached"), x, y + 28, fontColor.get("gui.mail.lettertext")); + GL11.glEnable(GL11.GL_LIGHTING); + for (int i = 0; i < container.getTradeInfo().required.length; i++) { + GL11.glDisable(GL11.GL_LIGHTING); + itemRender.renderItemAndEffectIntoGUI(fontRendererObj, mc.renderEngine, container.getTradeInfo().required[i], x + i * 18, y + 38); + itemRender.renderItemOverlayIntoGUI(fontRendererObj, mc.renderEngine, container.getTradeInfo().required[i], x + i * 18, y + 38); + GL11.glEnable(GL11.GL_LIGHTING); + } + + } + + @Override + public void onGuiClosed() { + setRecipient(this.address.getText(), container.getCarrierType()); + setText(); + Keyboard.enableRepeatEvents(false); + super.onGuiClosed(); + } + + private void setFromSessionVars() { + if(SessionVars.getStringVar("mail.letter.recipient") == null) + return; + + String recipient = SessionVars.getStringVar("mail.letter.recipient"); + String type = SessionVars.getStringVar("mail.letter.addressee"); + if(type != null) { + address.setText(recipient); + setRecipient(recipient, type); + } + + SessionVars.clearStringVar("mail.letter.recipient"); + SessionVars.clearStringVar("mail.letter.addressee"); + } + + private void setRecipient(String identifier, String type) { + if (this.isProcessedLetter) + return; + + MailAddress recipient = new MailAddress(identifier, type); + container.setRecipient(recipient); + container.updateTradeInfo(this.mc.theWorld, recipient); + } + + private void setText() { + if (this.isProcessedLetter) + return; + + container.setText(this.text.getText()); + } +} diff --git a/forestry_common/mail/forestry/mail/gui/GuiMailbox.java b/forestry_common/mail/forestry/mail/gui/GuiMailbox.java new file mode 100755 index 000000000..f4b1da043 --- /dev/null +++ b/forestry_common/mail/forestry/mail/gui/GuiMailbox.java @@ -0,0 +1,23 @@ +/******************************************************************************* + * Copyright 2011-2014 by SirSengir + * + * This work is licensed under a Creative Commons Attribution-NonCommercial-NoDerivs 3.0 Unported License. + * + * To view a copy of this license, visit http://creativecommons.org/licenses/by-nc-nd/3.0/. + ******************************************************************************/ +package forestry.mail.gui; + +import net.minecraft.entity.player.InventoryPlayer; + +import forestry.core.config.Defaults; +import forestry.core.gui.GuiForestry; +import forestry.mail.gadgets.MachineMailbox; + +public class GuiMailbox extends GuiForestry { + + public GuiMailbox(InventoryPlayer player, MachineMailbox tile) { + super(Defaults.TEXTURE_PATH_GUI + "/mailbox.png", new ContainerMailbox(player, tile), tile); + this.xSize = 230; + this.ySize = 227; + } +} diff --git a/forestry_common/mail/forestry/mail/gui/GuiMailboxInfo.java b/forestry_common/mail/forestry/mail/gui/GuiMailboxInfo.java new file mode 100755 index 000000000..d7eed1f6d --- /dev/null +++ b/forestry_common/mail/forestry/mail/gui/GuiMailboxInfo.java @@ -0,0 +1,79 @@ +/******************************************************************************* + * Copyright 2011-2014 by SirSengir + * + * This work is licensed under a Creative Commons Attribution-NonCommercial-NoDerivs 3.0 Unported License. + * + * To view a copy of this license, visit http://creativecommons.org/licenses/by-nc-nd/3.0/. + ******************************************************************************/ +package forestry.mail.gui; + +import net.minecraft.client.gui.FontRenderer; +import net.minecraft.client.gui.Gui; +import net.minecraft.util.ResourceLocation; + +import org.lwjgl.opengl.GL11; + +import forestry.core.config.Config; +import forestry.core.config.Defaults; +import forestry.core.proxy.Proxies; +import forestry.core.utils.ForestryResource; +import forestry.mail.POBoxInfo; + +public class GuiMailboxInfo extends Gui { + + public static GuiMailboxInfo instance; + + private final FontRenderer fontRendererObj; + private POBoxInfo poInfo; + private final ResourceLocation textureAlert = new ForestryResource(Defaults.TEXTURE_PATH_GUI + "/mailalert.png"); + + public GuiMailboxInfo() { + fontRendererObj = Proxies.common.getClientInstance().fontRenderer; + } + + public void render(int x, int y) { + if (poInfo == null) + return; + if (Proxies.common.getRenderWorld() == null) + return; + if (!Config.mailAlertEnabled) + return; + if (!poInfo.hasMail()) + return; + + GL11.glEnable(3042); + GL11.glEnable(32826); + + GL11.glColor4f(1.0F, 1.0F, 1.0F, 1.0F); + Proxies.common.bindTexture(textureAlert); + + this.drawTexturedModalRect(x, y, 0, 0, 98, 17); + + fontRendererObj + .drawString(Integer.toString(poInfo.playerLetters), x + 27 + getCenteredOffset(Integer.toString(poInfo.playerLetters), 22), y + 5, 0xffffff); + fontRendererObj.drawString(Integer.toString(poInfo.tradeLetters), x + 75 + getCenteredOffset(Integer.toString(poInfo.tradeLetters), 22), y + 5, 0xffffff); + + GL11.glDisable(32826); + GL11.glColor4f(1.0F, 1.0F, 1.0F, 1.0F); + + } + + protected int getCenteredOffset(String string, int xWidth) { + return (xWidth - fontRendererObj.getStringWidth(string)) / 2; + } + + public void setPOBoxInfo(POBoxInfo info) { + boolean playJingle = false; + + if (info.hasMail()) + if (this.poInfo == null) + playJingle = true; + else if (this.poInfo.playerLetters != info.playerLetters || this.poInfo.tradeLetters != info.tradeLetters) + playJingle = true; + + if (playJingle) + Proxies.common.getRenderWorld().playSoundAtEntity(Proxies.common.getClientInstance().thePlayer, "random.levelup", 1.0f, 1.0f); + + this.poInfo = info; + } +} diff --git a/forestry_common/mail/forestry/mail/gui/GuiPhilatelist.java b/forestry_common/mail/forestry/mail/gui/GuiPhilatelist.java new file mode 100755 index 000000000..429ad23e6 --- /dev/null +++ b/forestry_common/mail/forestry/mail/gui/GuiPhilatelist.java @@ -0,0 +1,24 @@ +/******************************************************************************* + * Copyright 2011-2014 by SirSengir + * + * This work is licensed under a Creative Commons Attribution-NonCommercial-NoDerivs 3.0 Unported License. + * + * To view a copy of this license, visit http://creativecommons.org/licenses/by-nc-nd/3.0/. + ******************************************************************************/ +package forestry.mail.gui; + +import net.minecraft.entity.player.InventoryPlayer; + +import forestry.core.config.Defaults; +import forestry.core.gui.GuiForestry; +import forestry.mail.gadgets.MachinePhilatelist; + +public class GuiPhilatelist extends GuiForestry { + + public GuiPhilatelist(InventoryPlayer player, MachinePhilatelist tile) { + super(Defaults.TEXTURE_PATH_GUI + "/philatelist.png", new ContainerPhilatelist(player, tile), tile); + this.xSize = 176; + this.ySize = 193; + } + +} diff --git a/forestry_common/mail/forestry/mail/gui/GuiTradeName.java b/forestry_common/mail/forestry/mail/gui/GuiTradeName.java new file mode 100755 index 000000000..9c4056a7c --- /dev/null +++ b/forestry_common/mail/forestry/mail/gui/GuiTradeName.java @@ -0,0 +1,99 @@ +/******************************************************************************* + * Copyright 2011-2014 by SirSengir + * + * This work is licensed under a Creative Commons Attribution-NonCommercial-NoDerivs 3.0 Unported License. + * + * To view a copy of this license, visit http://creativecommons.org/licenses/by-nc-nd/3.0/. + ******************************************************************************/ +package forestry.mail.gui; + +import net.minecraft.client.gui.GuiScreen; +import net.minecraft.client.gui.GuiTextField; +import net.minecraft.entity.player.InventoryPlayer; + +import org.lwjgl.input.Keyboard; + +import forestry.core.config.Defaults; +import forestry.core.gui.GuiForestry; +import forestry.core.utils.StringUtil; +import forestry.mail.gadgets.MachineTrader; + +public class GuiTradeName extends GuiForestry { + + private GuiTextField moniker; + + private boolean monikerFocus; + + private final ContainerTradeName container; + + public GuiTradeName(InventoryPlayer inventoryplayer, MachineTrader tile) { + super(Defaults.TEXTURE_PATH_GUI + "/tradername.png", new ContainerTradeName(inventoryplayer, tile), tile); + this.xSize = 176; + this.ySize = 90; + + this.container = (ContainerTradeName) inventorySlots; + } + + @Override + public void initGui() { + super.initGui(); + + moniker = new GuiTextField(this.fontRendererObj, guiLeft + 44, guiTop + 39, 90, 14); + if (container.getMoniker() != null) + moniker.setText(container.getMoniker()); + } + + @Override + protected void keyTyped(char eventCharacter, int eventKey) { + + // Set focus or enter text into address + if (this.moniker.isFocused()) { + if (eventKey == Keyboard.KEY_RETURN) + this.moniker.setFocused(false); + else + this.moniker.textboxKeyTyped(eventCharacter, eventKey); + return; + } + + super.keyTyped(eventCharacter, eventKey); + } + + @Override + protected void mouseClicked(int par1, int par2, int mouseButton) { + super.mouseClicked(par1, par2, mouseButton); + this.moniker.mouseClicked(par1, par2, mouseButton); + } + + @Override + protected void drawGuiContainerBackgroundLayer(float var1, int var2, int var3) { + + // Close gui screen if we linked up. + if (container.machine.isLinked()) { + this.mc.displayGuiScreen((GuiScreen) null); + this.mc.setIngameFocus(); + } + + // Check for focus changes + if (monikerFocus != moniker.isFocused()) + setMoniker(); + monikerFocus = moniker.isFocused(); + + super.drawGuiContainerBackgroundLayer(var1, var2, var3); + + String prompt = StringUtil.localize("gui.mail.nametrader"); + fontRendererObj.drawString(prompt, guiLeft + this.getCenteredOffset(prompt), guiTop + 16, fontColor.get("gui.mail.text")); + moniker.drawTextBox(); + + } + + @Override + public void onGuiClosed() { + setMoniker(); + super.onGuiClosed(); + } + + private void setMoniker() { + container.setMoniker(this.moniker.getText()); + } + +} diff --git a/forestry_common/mail/forestry/mail/gui/GuiTrader.java b/forestry_common/mail/forestry/mail/gui/GuiTrader.java new file mode 100755 index 000000000..eaf46ecd9 --- /dev/null +++ b/forestry_common/mail/forestry/mail/gui/GuiTrader.java @@ -0,0 +1,43 @@ +/******************************************************************************* + * Copyright 2011-2014 by SirSengir + * + * This work is licensed under a Creative Commons Attribution-NonCommercial-NoDerivs 3.0 Unported License. + * + * To view a copy of this license, visit http://creativecommons.org/licenses/by-nc-nd/3.0/. + ******************************************************************************/ +package forestry.mail.gui; + +import net.minecraft.entity.player.InventoryPlayer; + +import forestry.core.config.Defaults; +import forestry.core.gui.GuiForestry; +import forestry.core.utils.StringUtil; +import forestry.mail.gadgets.MachineTrader; + +public class GuiTrader extends GuiForestry { + + private final ContainerTrader container; + + public GuiTrader(InventoryPlayer inventoryplayer, MachineTrader tile) { + super(Defaults.TEXTURE_PATH_GUI + "/mailtrader.png", new ContainerTrader(inventoryplayer, tile), tile); + this.xSize = 226; + this.ySize = 220; + + this.container = (ContainerTrader) inventorySlots; + } + + @Override + protected void drawGuiContainerForegroundLayer(int mouseX, int mouseY) { + super.drawGuiContainerForegroundLayer(mouseX, mouseY); + String name = StringUtil.localize("tile.for." + tile.getInventoryName()); + this.fontRendererObj.drawString(name, getCenteredOffset(name), 6, fontColor.get("gui.mail.text")); + } + + @Override + protected void drawGuiContainerBackgroundLayer(float var1, int mouseX, int mouseY) { + super.drawGuiContainerBackgroundLayer(var1, mouseX, mouseY); + + fontRendererObj.drawString(container.getMoniker(), guiLeft + 19, guiTop + 22, fontColor.get("gui.mail.text")); + + } +} diff --git a/forestry_common/mail/forestry/mail/items/ItemCatalogue.java b/forestry_common/mail/forestry/mail/items/ItemCatalogue.java new file mode 100755 index 000000000..590469ab3 --- /dev/null +++ b/forestry_common/mail/forestry/mail/items/ItemCatalogue.java @@ -0,0 +1,37 @@ +/******************************************************************************* + * Copyright 2011-2014 by SirSengir + * + * This work is licensed under a Creative Commons Attribution-NonCommercial-NoDerivs 3.0 Unported License. + * + * To view a copy of this license, visit http://creativecommons.org/licenses/by-nc-nd/3.0/. + ******************************************************************************/ +package forestry.mail.items; + +import net.minecraft.entity.player.EntityPlayer; +import net.minecraft.item.ItemStack; +import net.minecraft.world.World; + +import forestry.api.core.ForestryAPI; +import forestry.core.items.ItemForestry; +import forestry.core.network.GuiId; +import forestry.core.proxy.Proxies; + +public class ItemCatalogue extends ItemForestry { + + public ItemCatalogue() { + super(); + setMaxStackSize(1); + } + + @Override + public ItemStack onItemRightClick(ItemStack itemstack, World world, EntityPlayer entityplayer) { + if (Proxies.common.isSimulating(world)) { + entityplayer.openGui(ForestryAPI.instance, GuiId.CatalogueGUI.ordinal(), world, (int) entityplayer.posX, (int) entityplayer.posY, + (int) entityplayer.posZ); + } + + return itemstack; + } + + +} diff --git a/forestry_common/mail/forestry/mail/items/ItemLetter.java b/forestry_common/mail/forestry/mail/items/ItemLetter.java new file mode 100755 index 000000000..5c0ace90b --- /dev/null +++ b/forestry_common/mail/forestry/mail/items/ItemLetter.java @@ -0,0 +1,270 @@ +/******************************************************************************* + * Copyright 2011-2014 by SirSengir + * + * This work is licensed under a Creative Commons Attribution-NonCommercial-NoDerivs 3.0 Unported License. + * + * To view a copy of this license, visit http://creativecommons.org/licenses/by-nc-nd/3.0/. + ******************************************************************************/ +package forestry.mail.items; + +import java.util.List; + +import net.minecraft.client.renderer.texture.IIconRegister; +import net.minecraft.entity.player.EntityPlayer; +import net.minecraft.item.ItemStack; +import net.minecraft.nbt.NBTTagCompound; +import net.minecraft.util.ChatComponentTranslation; +import net.minecraft.util.IIcon; +import net.minecraft.world.World; + +import cpw.mods.fml.relauncher.Side; +import cpw.mods.fml.relauncher.SideOnly; + +import forestry.api.core.ForestryAPI; +import forestry.api.mail.ILetter; +import forestry.core.EnumErrorCode; +import forestry.core.config.Config; +import forestry.core.interfaces.IErrorSource; +import forestry.core.interfaces.IHintSource; +import forestry.core.items.ItemInventoried; +import forestry.core.network.GuiId; +import forestry.core.proxy.Proxies; +import forestry.core.render.TextureManager; +import forestry.core.utils.ItemInventory; +import forestry.core.utils.StringUtil; +import forestry.mail.Letter; + +public class ItemLetter extends ItemInventoried { + + public static class LetterInventory extends ItemInventory implements IErrorSource, IHintSource { + + ILetter letter; + + public LetterInventory(ItemStack itemstack) { + super(ItemLetter.class); + this.parent = itemstack; + this.isItemInventory = true; + + // Set an uid to identify the itemstack on SMP + setUID(true); + + readFromNBT(itemstack.getTagCompound()); + } + + public ILetter getLetter() { + return this.letter; + } + + @Override + public void onGuiSaved(EntityPlayer player) { + super.onGuiSaved(player); + + if (parent == null) + return; + + // Already delivered mails can't be made usable anymore. + int state = getState(parent.getItemDamage()); + if (state >= 2) { + if (state == 2 && letter.countAttachments() <= 0) + parent.setItemDamage(encodeMeta(3, getSize(parent.getItemDamage()))); + return; + } + + int type = getType(letter); + + if (parent != null && letter.isMailable() && letter.isPostPaid()) + parent.setItemDamage(encodeMeta(1, type)); + else + parent.setItemDamage(encodeMeta(0, type)); + } + + @Override + public void readFromNBT(NBTTagCompound nbttagcompound) { + + if (nbttagcompound == null) + return; + + letter = new Letter(nbttagcompound); + } + + @Override + public void writeToNBT(NBTTagCompound nbttagcompound) { + letter.writeToNBT(nbttagcompound); + } + + @Override + public ItemStack decrStackSize(int i, int j) { + return letter.decrStackSize(i, j); + } + + @Override + public void setInventorySlotContents(int i, ItemStack itemstack) { + letter.setInventorySlotContents(i, itemstack); + } + + @Override + public ItemStack getStackInSlot(int i) { + return letter.getStackInSlot(i); + } + + @Override + public int getSizeInventory() { + return letter.getSizeInventory(); + } + + @Override + public String getInventoryName() { + return letter.getInventoryName(); + } + + @Override + public int getInventoryStackLimit() { + return letter.getInventoryStackLimit(); + } + + @Override + public void markDirty() { + letter.markDirty(); + } + + @Override + public boolean isUseableByPlayer(EntityPlayer entityplayer) { + return letter.isUseableByPlayer(entityplayer); + } + + @Override + public void openInventory() { + } + + @Override + public void closeInventory() { + } + + @Override + public ItemStack getStackInSlotOnClosing(int slot) { + return letter.getStackInSlotOnClosing(slot); + } + + // / IERRORSOURCE + @Override + public boolean throwsErrors() { + return true; + } + + @Override + public EnumErrorCode getErrorState() { + + if (!letter.hasRecipient()) + return EnumErrorCode.NORECIPIENT; + + if (!letter.isProcessed() && !letter.isPostPaid()) + return EnumErrorCode.NOTPOSTPAID; + + return EnumErrorCode.OK; + } + + /* IHINTSOURCE */ + @Override + public boolean hasHints() { + return Config.hints.get("letter") != null && Config.hints.get("letter").length > 0; + } + + @Override + public String[] getHints() { + return Config.hints.get("letter"); + } + + } + + public ItemLetter() { + super(); + } + + @Override + public ItemStack onItemRightClick(ItemStack itemstack, World world, EntityPlayer entityplayer) { + if (Proxies.common.isSimulating(world)) + if (itemstack.stackSize == 1) { + entityplayer.openGui(ForestryAPI.instance, GuiId.LetterGUI.ordinal(), world, (int) entityplayer.posX, (int) entityplayer.posY, + (int) entityplayer.posZ); + } else { + entityplayer.addChatMessage(new ChatComponentTranslation("chat.mail.wrongstacksize")); + } + + return itemstack; + } + + @Override + public boolean getShareTag() { + return true; + } + + /* ICONS */ + @SideOnly(Side.CLIENT) + private IIcon[][] icons; + + @SideOnly(Side.CLIENT) + @Override + public void registerIcons(IIconRegister register) { + icons = new IIcon[3][4]; + for (int i = 0; i < 3; i++) { + icons[i][0] = TextureManager.getInstance().registerTex(register, "mail/letter." + i + ".fresh"); + icons[i][1] = TextureManager.getInstance().registerTex(register, "mail/letter." + i + ".stamped"); + icons[i][2] = TextureManager.getInstance().registerTex(register, "mail/letter." + i + ".opened"); + icons[i][3] = TextureManager.getInstance().registerTex(register, "mail/letter." + i + ".emptied"); + } + + } + + @SideOnly(Side.CLIENT) + @Override + public IIcon getIconFromDamage(int damage) { + + int state = getState(damage); + int size = getSize(damage); + + return icons[size][state]; + } + + public static int encodeMeta(int state, int size) { + int meta = size << 4; + meta |= state; + + size = getSize(meta); + state = getState(meta); + + return meta; + } + + public static int getState(int meta) { + return meta & 0x0f; + } + + public static int getSize(int meta) { + return meta >> 4; + } + + @SuppressWarnings({ "unchecked", "rawtypes" }) + @Override + public void addInformation(ItemStack itemstack, EntityPlayer player, List list, boolean flag) { + NBTTagCompound nbttagcompound = itemstack.getTagCompound(); + if (nbttagcompound == null) { + list.add("<" + StringUtil.localize("gui.blank") + ">"); + return; + } + + ILetter letter = new Letter(nbttagcompound); + letter.addTooltip(list); + } + + public static int getType(ILetter letter) { + int count = letter.countAttachments(); + + if (count > 5) + return 2; + else if (count > 1) + return 1; + else + return 0; + } + +} diff --git a/forestry_common/mail/forestry/mail/items/ItemStamps.java b/forestry_common/mail/forestry/mail/items/ItemStamps.java new file mode 100755 index 000000000..2767691e8 --- /dev/null +++ b/forestry_common/mail/forestry/mail/items/ItemStamps.java @@ -0,0 +1,68 @@ +/******************************************************************************* + * Copyright 2011-2014 by SirSengir + * + * This work is licensed under a Creative Commons Attribution-NonCommercial-NoDerivs 3.0 Unported License. + * + * To view a copy of this license, visit http://creativecommons.org/licenses/by-nc-nd/3.0/. + ******************************************************************************/ +package forestry.mail.items; + +import net.minecraft.item.ItemStack; + +import forestry.api.mail.EnumPostage; +import forestry.api.mail.IStamps; +import forestry.core.CreativeTabForestry; +import forestry.core.items.ItemOverlay; +import forestry.core.utils.StringUtil; + +public class ItemStamps extends ItemOverlay implements IStamps { + + public static class StampInfo extends OverlayInfo { + + private final Object craftingIngredient; + private final EnumPostage postage; + + public StampInfo(String name, EnumPostage postage, Object crafting, int primaryColor, int secondaryColor) { + super(name, primaryColor, secondaryColor); + this.craftingIngredient = crafting; + this.postage = postage; + } + + public EnumPostage getPostage() { + return this.postage; + } + + public Object getCraftingIngredient() { + return this.craftingIngredient; + } + + } + + private final StampInfo[] stampInfo; + + public ItemStamps(StampInfo[] overlays) { + super(CreativeTabForestry.tabForestry, overlays); + this.stampInfo = overlays; + } + + @Override + public EnumPostage getPostage(ItemStack itemstack) { + if (itemstack.getItem() != this) + return EnumPostage.P_0; + + if (itemstack.getItemDamage() < 0 || itemstack.getItemDamage() >= stampInfo.length) + return EnumPostage.P_0; + + return stampInfo[itemstack.getItemDamage()].getPostage(); + } + + @Override + public String getItemStackDisplayName(ItemStack itemstack) { + if (itemstack.getItemDamage() < 0 || itemstack.getItemDamage() >= stampInfo.length) + return null; + + return StringUtil.localize(getUnlocalizedName()) + " " + stampInfo[itemstack.getItemDamage()].name; + } + + +} diff --git a/forestry_common/mail/forestry/mail/network/PacketPOBoxInfo.java b/forestry_common/mail/forestry/mail/network/PacketPOBoxInfo.java new file mode 100755 index 000000000..d6398c9aa --- /dev/null +++ b/forestry_common/mail/forestry/mail/network/PacketPOBoxInfo.java @@ -0,0 +1,51 @@ +/******************************************************************************* + * Copyright 2011-2014 by SirSengir + * + * This work is licensed under a Creative Commons Attribution-NonCommercial-NoDerivs 3.0 Unported License. + * + * To view a copy of this license, visit http://creativecommons.org/licenses/by-nc-nd/3.0/. + ******************************************************************************/ +package forestry.mail.network; + +import java.io.DataInputStream; +import java.io.DataOutputStream; +import java.io.IOException; + +import forestry.core.network.ForestryPacket; +import forestry.mail.POBoxInfo; + +public class PacketPOBoxInfo extends ForestryPacket { + + public POBoxInfo poboxInfo; + + public PacketPOBoxInfo() { + } + + public PacketPOBoxInfo(int id, POBoxInfo info) { + super(id); + this.poboxInfo = info; + } + + @Override + public void writeData(DataOutputStream data) throws IOException { + if (poboxInfo == null) { + data.writeShort(-1); + return; + } + + data.writeShort(0); + data.writeInt(poboxInfo.playerLetters); + data.writeInt(poboxInfo.tradeLetters); + } + + @Override + public void readData(DataInputStream data) throws IOException { + + short isNotNull = data.readShort(); + if (isNotNull < 0) + return; + + this.poboxInfo = new POBoxInfo(data.readInt(), data.readInt()); + } + +} diff --git a/forestry_common/mail/forestry/mail/network/PacketTradeInfo.java b/forestry_common/mail/forestry/mail/network/PacketTradeInfo.java new file mode 100755 index 000000000..28f2fc949 --- /dev/null +++ b/forestry_common/mail/forestry/mail/network/PacketTradeInfo.java @@ -0,0 +1,73 @@ +/******************************************************************************* + * Copyright 2011-2014 by SirSengir + * + * This work is licensed under a Creative Commons Attribution-NonCommercial-NoDerivs 3.0 Unported License. + * + * To view a copy of this license, visit http://creativecommons.org/licenses/by-nc-nd/3.0/. + ******************************************************************************/ +package forestry.mail.network; + +import java.io.DataInputStream; +import java.io.DataOutputStream; +import java.io.IOException; + +import net.minecraft.item.ItemStack; + +import forestry.api.mail.TradeStationInfo; +import forestry.core.network.ForestryPacket; +import forestry.mail.EnumStationState; + +public class PacketTradeInfo extends ForestryPacket { + + public TradeStationInfo tradeInfo; + + public PacketTradeInfo() { + } + + public PacketTradeInfo(int id, TradeStationInfo info) { + super(id); + this.tradeInfo = info; + } + + @Override + public void writeData(DataOutputStream data) throws IOException { + + if (tradeInfo == null) { + data.writeShort(-1); + return; + } + + data.writeShort(0); + + data.writeUTF(tradeInfo.moniker); + data.writeUTF(tradeInfo.owner); + writeItemStack(tradeInfo.tradegood, data); + data.writeShort(tradeInfo.required.length); + for (int i = 0; i < tradeInfo.required.length; i++) + writeItemStack(tradeInfo.required[i], data); + data.writeShort(tradeInfo.state.ordinal()); + } + + @Override + public void readData(DataInputStream data) throws IOException { + + short isNotNull = data.readShort(); + if (isNotNull < 0) + return; + + String moniker; + String owner; + ItemStack tradegood; + ItemStack[] required; + + moniker = data.readUTF(); + owner = data.readUTF(); + tradegood = readItemStack(data); + required = new ItemStack[data.readShort()]; + for (int i = 0; i < required.length; i++) + required[i] = readItemStack(data); + + this.tradeInfo = new TradeStationInfo(moniker, owner, tradegood, required, EnumStationState.values()[data.readShort()]); + } + +} diff --git a/forestry_common/mail/forestry/mail/proxy/ClientProxyMail.java b/forestry_common/mail/forestry/mail/proxy/ClientProxyMail.java new file mode 100755 index 000000000..250b6c0c2 --- /dev/null +++ b/forestry_common/mail/forestry/mail/proxy/ClientProxyMail.java @@ -0,0 +1,57 @@ +/******************************************************************************* + * Copyright 2011-2014 by SirSengir + * + * This work is licensed under a Creative Commons Attribution-NonCommercial-NoDerivs 3.0 Unported License. + * + * To view a copy of this license, visit http://creativecommons.org/licenses/by-nc-nd/3.0/. + ******************************************************************************/ +package forestry.mail.proxy; + +import net.minecraft.world.World; + +import forestry.core.network.ForestryPacket; +import forestry.core.network.PacketIds; +import forestry.core.proxy.Proxies; +import forestry.core.utils.Localization; +import forestry.mail.POBox; +import forestry.mail.POBoxInfo; +import forestry.mail.PostRegistry; +import forestry.mail.gui.GuiMailboxInfo; + +public class ClientProxyMail extends ProxyMail { + + @Override + public void clearMailboxInfo() { + GuiMailboxInfo.instance = null; + } + + @Override + public void resetMailboxInfo() { + if (Proxies.common.getClientInstance().thePlayer == null) + return; + + GuiMailboxInfo.instance = new GuiMailboxInfo(); + + if (!Proxies.common.isSimulating(Proxies.common.getRenderWorld())) + Proxies.net.sendToServer(new ForestryPacket(PacketIds.POBOX_INFO_REQUEST)); + else { + POBox pobox = PostRegistry.getPOBox(Proxies.common.getRenderWorld(), Proxies.common.getClientInstance().thePlayer.getGameProfile().getId()); + if (pobox != null) + setPOBoxInfo(Proxies.common.getRenderWorld(), Proxies.common.getClientInstance().thePlayer.getGameProfile().getId(), pobox.getPOBoxInfo()); + } + } + + @Override + public void setPOBoxInfo(World world, String playername, POBoxInfo info) { + if (Proxies.common.getClientInstance().thePlayer == null || !Proxies.common.getClientInstance().thePlayer.getGameProfile().getId().equals(playername)) + return; + + GuiMailboxInfo.instance.setPOBoxInfo(info); + } + + @Override + public void addLocalizations() { + Localization.instance.addLocalization("/lang/forestry/mail/"); + } + +} diff --git a/forestry_common/mail/forestry/mail/proxy/ProxyMail.java b/forestry_common/mail/forestry/mail/proxy/ProxyMail.java new file mode 100755 index 000000000..0a61875ab --- /dev/null +++ b/forestry_common/mail/forestry/mail/proxy/ProxyMail.java @@ -0,0 +1,40 @@ +/******************************************************************************* + * Copyright 2011-2014 by SirSengir + * + * This work is licensed under a Creative Commons Attribution-NonCommercial-NoDerivs 3.0 Unported License. + * + * To view a copy of this license, visit http://creativecommons.org/licenses/by-nc-nd/3.0/. + ******************************************************************************/ +package forestry.mail.proxy; + +import net.minecraft.entity.player.EntityPlayerMP; +import net.minecraft.world.World; + +import forestry.core.network.PacketIds; +import forestry.core.proxy.Proxies; +import forestry.mail.POBoxInfo; +import forestry.mail.network.PacketPOBoxInfo; + +public class ProxyMail { + + public void clearMailboxInfo() { + } + + public void resetMailboxInfo() { + } + + public void setPOBoxInfo(World world, String playername, POBoxInfo info) { + for (int i = 0; i < world.playerEntities.size(); i++) { + EntityPlayerMP player = (EntityPlayerMP) world.playerEntities.get(i); + if (!player.getGameProfile().getId().equals(playername)) + continue; + + Proxies.net.sendToPlayer(new PacketPOBoxInfo(PacketIds.POBOX_INFO, info), player); + break; + } + } + + public void addLocalizations() { + } + +} diff --git a/forestry_common/mail/forestry/mail/triggers/TriggerBuffer.java b/forestry_common/mail/forestry/mail/triggers/TriggerBuffer.java new file mode 100755 index 000000000..8951864f7 --- /dev/null +++ b/forestry_common/mail/forestry/mail/triggers/TriggerBuffer.java @@ -0,0 +1,42 @@ +/******************************************************************************* + * Copyright 2011-2014 by SirSengir + * + * This work is licensed under a Creative Commons Attribution-NonCommercial-NoDerivs 3.0 Unported License. + * + * To view a copy of this license, visit http://creativecommons.org/licenses/by-nc-nd/3.0/. + ******************************************************************************/ +package forestry.mail.triggers; + +import net.minecraft.tileentity.TileEntity; + +import net.minecraftforge.common.util.ForgeDirection; + +import buildcraft.api.gates.ITriggerParameter; + +import forestry.core.triggers.Trigger; +import forestry.mail.gadgets.MachineTrader; + +public class TriggerBuffer extends Trigger { + + float threshold; + + public TriggerBuffer(String tag, float threshold) { + super(tag, "mailBuffer"); + this.threshold = threshold; + } + + @Override + public String getDescription() { + return super.getDescription() + " > " + threshold * 100 + "%"; + } + + @Override + public boolean isTriggerActive(ForgeDirection direction, TileEntity tile, ITriggerParameter parameter) { + + if (!(tile instanceof MachineTrader)) + return false; + + return ((MachineTrader) tile).hasOutputBufMin(threshold); + } + +} diff --git a/forestry_common/mail/forestry/mail/triggers/TriggerHasMail.java b/forestry_common/mail/forestry/mail/triggers/TriggerHasMail.java new file mode 100755 index 000000000..fe6b04405 --- /dev/null +++ b/forestry_common/mail/forestry/mail/triggers/TriggerHasMail.java @@ -0,0 +1,33 @@ +/******************************************************************************* + * Copyright 2011-2014 by SirSengir + * + * This work is licensed under a Creative Commons Attribution-NonCommercial-NoDerivs 3.0 Unported License. + * + * To view a copy of this license, visit http://creativecommons.org/licenses/by-nc-nd/3.0/. + ******************************************************************************/ +package forestry.mail.triggers; + +import net.minecraft.tileentity.TileEntity; + +import net.minecraftforge.common.util.ForgeDirection; + +import buildcraft.api.gates.ITriggerParameter; + +import forestry.core.triggers.Trigger; +import forestry.mail.IMailContainer; + +public class TriggerHasMail extends Trigger { + + public TriggerHasMail() { + super("mail.hasMail", "hasMail"); + } + + @Override + public boolean isTriggerActive(ForgeDirection direction, TileEntity tile, ITriggerParameter parameter) { + + if (!(tile instanceof IMailContainer)) + return false; + + return ((IMailContainer) tile).hasMail(); + } +} diff --git a/forestry_common/mail/forestry/mail/triggers/TriggerLowInput.java b/forestry_common/mail/forestry/mail/triggers/TriggerLowInput.java new file mode 100755 index 000000000..e9bd8fb3e --- /dev/null +++ b/forestry_common/mail/forestry/mail/triggers/TriggerLowInput.java @@ -0,0 +1,41 @@ +/******************************************************************************* + * Copyright 2011-2014 by SirSengir + * + * This work is licensed under a Creative Commons Attribution-NonCommercial-NoDerivs 3.0 Unported License. + * + * To view a copy of this license, visit http://creativecommons.org/licenses/by-nc-nd/3.0/. + ******************************************************************************/ +package forestry.mail.triggers; + +import net.minecraft.tileentity.TileEntity; + +import net.minecraftforge.common.util.ForgeDirection; + +import buildcraft.api.gates.ITriggerParameter; + +import forestry.core.triggers.Trigger; +import forestry.mail.gadgets.MachineTrader; + +public class TriggerLowInput extends Trigger { + + float threshold; + + public TriggerLowInput(String tag, float threshold) { + super(tag, "lowInput"); + this.threshold = threshold; + } + + @Override + public String getDescription() { + return super.getDescription() + " < " + threshold * 100 + "%"; + } + + @Override + public boolean isTriggerActive(ForgeDirection direction, TileEntity tile, ITriggerParameter parameter) { + + if (!(tile instanceof MachineTrader)) + return false; + + return !((MachineTrader) tile).hasInputBufMin(threshold); + } +} diff --git a/forestry_common/mail/forestry/mail/triggers/TriggerLowPaper.java b/forestry_common/mail/forestry/mail/triggers/TriggerLowPaper.java new file mode 100755 index 000000000..4b7a5e133 --- /dev/null +++ b/forestry_common/mail/forestry/mail/triggers/TriggerLowPaper.java @@ -0,0 +1,42 @@ +/******************************************************************************* + * Copyright 2011-2014 by SirSengir + * + * This work is licensed under a Creative Commons Attribution-NonCommercial-NoDerivs 3.0 Unported License. + * + * To view a copy of this license, visit http://creativecommons.org/licenses/by-nc-nd/3.0/. + ******************************************************************************/ +package forestry.mail.triggers; + +import net.minecraft.tileentity.TileEntity; + +import net.minecraftforge.common.util.ForgeDirection; + +import buildcraft.api.gates.ITriggerParameter; + +import forestry.core.triggers.Trigger; +import forestry.mail.gadgets.MachineTrader; + +public class TriggerLowPaper extends Trigger { + + float threshold; + + public TriggerLowPaper(String tag, float threshold) { + super(tag, "lowPaper"); + this.threshold = threshold; + } + + @Override + public String getDescription() { + return super.getDescription() + " < " + threshold * 100 + "%"; + } + + @Override + public boolean isTriggerActive(ForgeDirection direction, TileEntity tile, ITriggerParameter parameter) { + + if (!(tile instanceof MachineTrader)) + return false; + + return !((MachineTrader) tile).hasPaperMin(threshold); + } + +} diff --git a/forestry_common/mail/forestry/mail/triggers/TriggerLowStamps.java b/forestry_common/mail/forestry/mail/triggers/TriggerLowStamps.java new file mode 100755 index 000000000..56a8065c6 --- /dev/null +++ b/forestry_common/mail/forestry/mail/triggers/TriggerLowStamps.java @@ -0,0 +1,42 @@ +/******************************************************************************* + * Copyright 2011-2014 by SirSengir + * + * This work is licensed under a Creative Commons Attribution-NonCommercial-NoDerivs 3.0 Unported License. + * + * To view a copy of this license, visit http://creativecommons.org/licenses/by-nc-nd/3.0/. + ******************************************************************************/ +package forestry.mail.triggers; + +import net.minecraft.tileentity.TileEntity; + +import net.minecraftforge.common.util.ForgeDirection; + +import buildcraft.api.gates.ITriggerParameter; + +import forestry.core.triggers.Trigger; +import forestry.mail.gadgets.MachineTrader; + +public class TriggerLowStamps extends Trigger { + + int threshold; + + public TriggerLowStamps(String tag, int threshold) { + super(tag, "lowStamps"); + this.threshold = threshold; + } + + @Override + public String getDescription() { + return super.getDescription() + " < " + threshold + "p"; + } + + @Override + public boolean isTriggerActive(ForgeDirection direction, TileEntity tile, ITriggerParameter parameter) { + + if (!(tile instanceof MachineTrader)) + return false; + + return !((MachineTrader) tile).hasPostageMin(threshold); + } + +} diff --git a/forestry_common/mail/forestry/plugins/PluginMail.java b/forestry_common/mail/forestry/plugins/PluginMail.java new file mode 100755 index 000000000..60c360c3f --- /dev/null +++ b/forestry_common/mail/forestry/plugins/PluginMail.java @@ -0,0 +1,223 @@ +/******************************************************************************* + * Copyright 2011-2014 by SirSengir + * + * This work is licensed under a Creative Commons Attribution-NonCommercial-NoDerivs 3.0 Unported License. + * + * To view a copy of this license, visit http://creativecommons.org/licenses/by-nc-nd/3.0/. + ******************************************************************************/ +package forestry.plugins; + +import net.minecraft.block.material.Material; +import net.minecraft.command.ICommand; +import net.minecraft.init.Blocks; +import net.minecraft.init.Items; +import net.minecraft.item.ItemStack; + +import cpw.mods.fml.common.SidedProxy; +import cpw.mods.fml.common.network.IGuiHandler; + +import forestry.api.core.PluginInfo; +import forestry.api.mail.EnumPostage; +import forestry.api.mail.PostManager; +import forestry.api.recipes.RecipeManagers; +import forestry.core.config.Config; +import forestry.core.config.Defaults; +import forestry.core.config.ForestryBlock; +import forestry.core.config.ForestryItem; +import forestry.core.gadgets.BlockBase; +import forestry.core.gadgets.MachineDefinition; +import forestry.core.interfaces.IOreDictionaryHandler; +import forestry.core.interfaces.IPacketHandler; +import forestry.core.interfaces.ISaveEventHandler; +import forestry.core.items.ItemForestryBlock; +import forestry.core.proxy.Proxies; +import forestry.core.triggers.Trigger; +import forestry.core.utils.LiquidHelper; +import forestry.core.utils.ShapedRecipeCustom; +import forestry.mail.CommandMail; +import forestry.mail.EnumAddressee; +import forestry.mail.GuiHandlerMail; +import forestry.mail.PacketHandlerMail; +import forestry.mail.PostRegistry; +import forestry.mail.PostalCarrier; +import forestry.mail.SaveEventHandlerMail; +import forestry.mail.TickHandlerMailClient; +import forestry.mail.gadgets.MachineMailbox; +import forestry.mail.gadgets.MachinePhilatelist; +import forestry.mail.gadgets.MachineTrader; +import forestry.mail.items.ItemCatalogue; +import forestry.mail.items.ItemLetter; +import forestry.mail.items.ItemStamps; +import forestry.mail.items.ItemStamps.StampInfo; +import forestry.mail.proxy.ProxyMail; +import forestry.mail.triggers.TriggerBuffer; +import forestry.mail.triggers.TriggerHasMail; +import forestry.mail.triggers.TriggerLowInput; +import forestry.mail.triggers.TriggerLowPaper; +import forestry.mail.triggers.TriggerLowStamps; + +@PluginInfo(pluginID = "Mail", name = "Mail", author = "SirSengir", url = Defaults.URL, description = "Adds Forestry's mail and trade system.") +public class PluginMail extends NativePlugin { + + @SidedProxy(clientSide = "forestry.mail.proxy.ClientProxyMail", serverSide = "forestry.mail.proxy.ProxyMail") + public static ProxyMail proxy; + public static Trigger triggerHasMail; + public static Trigger lowPaper25; + public static Trigger lowPaper10; + public static Trigger lowPostage40; + public static Trigger lowPostage20; + public static Trigger lowInput25; + public static Trigger lowInput10; + public static Trigger highBuffer75; + public static Trigger highBuffer90; + public static MachineDefinition definitionMailbox; + public static MachineDefinition definitionTradestation; + public static MachineDefinition definitionPhilatelist; + public static StampInfo[] stampDefinitions; + + @Override + public boolean isAvailable() { + return !Config.disableMail; + } + + @Override + public void preInit() { + super.preInit(); + + new TickHandlerMailClient(); + + triggerHasMail = new TriggerHasMail(); + lowPaper25 = new TriggerLowPaper("mail.lowPaper.25", 0.25f); + lowPaper10 = new TriggerLowPaper("mail.lowPaper.10", 0.1f); + lowPostage40 = new TriggerLowStamps("mail.lowStamps.40", 40); + lowPostage20 = new TriggerLowStamps("mail.lowStamps.20", 20); + lowInput25 = new TriggerLowInput("mail.lowInput.25", 0.25f); + lowInput10 = new TriggerLowInput("mail.lowInput.10", 0.1f); + highBuffer75 = new TriggerBuffer("mail.lowBuffer.75", 0.75f); + highBuffer90 = new TriggerBuffer("mail.lowBuffer.90", 0.90f); + + ForestryBlock.mail = new BlockBase(Material.iron); + ForestryBlock.mail.setBlockName("for.mail"); + Proxies.common.registerBlock(ForestryBlock.mail, ItemForestryBlock.class); + + ShapedRecipeCustom recipe = ShapedRecipeCustom.createShapedRecipe(new ItemStack(ForestryBlock.mail, 1, Defaults.DEFINITION_MAILBOX_META), + " # ", "#Y#", "XXX", + '#', "ingotTin", + 'X', Blocks.chest, + 'Y', ForestryItem.sturdyCasing); + definitionMailbox = ForestryBlock.mail.addDefinition(new MachineDefinition(Defaults.DEFINITION_MAILBOX_META, "forestry.Mailbox", MachineMailbox.class, recipe).setFaces(0, 1, 2, 2, 2, 2, 0, 7)); + + + recipe = ShapedRecipeCustom.createShapedRecipe(new ItemStack(ForestryBlock.mail, 1, Defaults.DEFINITION_TRADESTATION_META), + "Z#Z", "#Y#", "XWX", + '#', ForestryItem.tubes.getItemStack(1, 2), + 'X', Blocks.chest, + 'Y', ForestryItem.sturdyCasing, + 'Z', ForestryItem.tubes.getItemStack(1, 3), + 'W', ForestryItem.circuitboards.getItemStack(1, 2)); + definitionTradestation = ForestryBlock.mail.addDefinition(new MachineDefinition(Defaults.DEFINITION_TRADESTATION_META, "forestry.Tradestation", MachineTrader.class, recipe).setFaces(0, 1, 2, 3, 4, 4, 0, 7)); + + definitionPhilatelist = ForestryBlock.mail.addDefinition(new MachineDefinition(Defaults.DEFINITION_PHILATELIST_META, "forestry.Philatelist", MachinePhilatelist.class) + .setFaces(0, 1, 2, 3, 2, 2, 0, 7)); + + + + PostManager.postRegistry = new PostRegistry(); + PostManager.postRegistry.registerCarrier(new PostalCarrier(EnumAddressee.PLAYER)); + PostManager.postRegistry.registerCarrier(new PostalCarrier(EnumAddressee.TRADER)); + } + + @Override + public void doInit() { + super.doInit(); + + proxy.addLocalizations(); + + definitionMailbox.register(); + definitionTradestation.register(); + definitionPhilatelist.register(); + } + + @Override + public void postInit() { + super.postInit(); + } + + @Override + public IGuiHandler getGuiHandler() { + return new GuiHandlerMail(); + } + + @Override + public IPacketHandler getPacketHandler() { + return new PacketHandlerMail(); + } + + @Override + protected void registerItems() { + + stampDefinitions = new StampInfo[] { + new StampInfo("1n", EnumPostage.P_1, ForestryItem.apatite, 0x4a8ca7, 0xffffff), new StampInfo("2n", EnumPostage.P_2, "ingotCopper", 0xe8c814, 0xffffff), + new StampInfo("5n", EnumPostage.P_5, "ingotTin", 0x9c0707, 0xffffff), new StampInfo("10n", EnumPostage.P_10, Items.gold_ingot, 0x7bd1b8, 0xffffff), + new StampInfo("20n", EnumPostage.P_20, Items.diamond, 0xff9031, 0xfff7dd), new StampInfo("50n", EnumPostage.P_50, Items.emerald, 0x6431d7, 0xfff7dd), + new StampInfo("100n", EnumPostage.P_100, Items.nether_star, 0xd731ba, 0xfff7dd) }; //new StampInfo("200n", EnumPostage.P_200, Item.netherStar, 0xcd9831, 0xfff7dd)}; + + /* STAMPS */ + ForestryItem.stamps.registerItem(new ItemStamps(stampDefinitions), "stamps"); + + /* LETTER */ + ForestryItem.letters.registerItem(new ItemLetter(), "letters"); + + /* CATALOGUE */ + ForestryItem.catalogue.registerItem(new ItemCatalogue(), "catalogue"); + } + + @Override + protected void registerBackpackItems() { + } + + @Override + protected void registerCrates() { + } + + @Override + protected void registerRecipes() { + // Letters + Proxies.common.addShapelessRecipe(ForestryItem.letters.getItemStack(), Items.paper, ForestryItem.propolis.getItemStack(1, Defaults.WILDCARD)); + + if (Config.craftingStampsEnabled) { + for (int i = 0; i < stampDefinitions.length; i++) { + if (Config.collectorStamps.contains(stampDefinitions[i].name)) + continue; + + Proxies.common.addRecipe(ForestryItem.stamps.getItemStack(9, i), new Object[] { "XXX", "###", "ZZZ", 'X', + stampDefinitions[i].getCraftingIngredient(), '#', Items.paper, 'Z', ForestryItem.honeyDrop }); + RecipeManagers.carpenterManager.addRecipe(10, LiquidHelper.getLiquid(Defaults.LIQUID_SEEDOIL, 300), null, ForestryItem.stamps.getItemStack(9, i), + new Object[] { "XXX", "###", 'X', stampDefinitions[i].getCraftingIngredient(), '#', Items.paper }); + } + } + + // Recycling + Proxies.common.addRecipe(new ItemStack(Items.paper), new Object[] { "###", '#', ForestryItem.letters.getItemStack(1, Defaults.WILDCARD) }); + + // Carpenter + RecipeManagers.carpenterManager.addRecipe(10, LiquidHelper.getLiquid(Defaults.LIQUID_WATER, 250), null, ForestryItem.letters.getItemStack(), new Object[] { "###", "###", '#', ForestryItem.woodPulp }); + + Proxies.common.addShapelessRecipe(ForestryItem.catalogue.getItemStack(), new Object[] { ForestryItem.stamps.getItemStack(1, Defaults.WILDCARD), new ItemStack(Items.book) }); + } + + @Override + public ISaveEventHandler getSaveEventHandler() { + return new SaveEventHandlerMail(); + } + + @Override + public IOreDictionaryHandler getDictionaryHandler() { + return null; + } + + @Override + public ICommand[] getConsoleCommands() { + return new ICommand[] { new CommandMail() }; + } +} diff --git a/forestry_common/storage/forestry/plugins/PluginStorage.java b/forestry_common/storage/forestry/plugins/PluginStorage.java new file mode 100755 index 000000000..0d35b6b04 --- /dev/null +++ b/forestry_common/storage/forestry/plugins/PluginStorage.java @@ -0,0 +1,594 @@ +/******************************************************************************* + * Copyright 2011-2014 by SirSengir + * + * This work is licensed under a Creative Commons Attribution-NonCommercial-NoDerivs 3.0 Unported License. + * + * To view a copy of this license, visit http://creativecommons.org/licenses/by-nc-nd/3.0/. + ******************************************************************************/ +package forestry.plugins; + +import java.util.ArrayList; +import java.util.logging.Level; +import java.util.logging.Logger; + +import net.minecraft.block.Block; +import net.minecraft.block.BlockBasePressurePlate; +import net.minecraft.block.BlockButton; +import net.minecraft.block.BlockChest; +import net.minecraft.block.BlockFence; +import net.minecraft.block.BlockFenceGate; +import net.minecraft.block.BlockFurnace; +import net.minecraft.block.BlockLadder; +import net.minecraft.block.BlockLever; +import net.minecraft.block.BlockLog; +import net.minecraft.block.BlockMelon; +import net.minecraft.block.BlockPumpkin; +import net.minecraft.block.BlockRedstoneDiode; +import net.minecraft.block.BlockStairs; +import net.minecraft.block.BlockTorch; +import net.minecraft.block.BlockTrapDoor; +import net.minecraft.block.BlockWall; +import net.minecraft.block.BlockWorkbench; +import net.minecraft.init.Blocks; +import net.minecraft.init.Items; +import net.minecraft.item.Item; +import net.minecraft.item.ItemDoor; +import net.minecraft.item.ItemFood; +import net.minecraft.item.ItemStack; + +import cpw.mods.fml.common.event.FMLInterModComms.IMCMessage; +import cpw.mods.fml.common.network.IGuiHandler; +import cpw.mods.fml.common.registry.GameData; + +import net.minecraftforge.common.IPlantable; +import net.minecraftforge.common.IShearable; +import net.minecraftforge.oredict.OreDictionary; + +import forestry.api.core.PluginInfo; +import forestry.api.core.Tabs; +import forestry.api.recipes.RecipeManagers; +import forestry.api.storage.BackpackManager; +import forestry.api.storage.EnumBackpackType; +import forestry.api.storage.IBackpackDefinition; +import forestry.core.config.Config; +import forestry.core.config.Configuration; +import forestry.core.config.Defaults; +import forestry.core.config.ForestryBlock; +import forestry.core.config.ForestryItem; +import forestry.core.config.Property; +import forestry.core.interfaces.IOreDictionaryHandler; +import forestry.core.interfaces.IPickupHandler; +import forestry.core.interfaces.IResupplyHandler; +import forestry.core.interfaces.ISaveEventHandler; +import forestry.core.network.GuiId; +import forestry.core.proxy.Proxies; +import forestry.core.utils.LiquidHelper; +import forestry.storage.BackpackDefinition; +import forestry.storage.BackpackHelper; +import forestry.storage.GuiHandlerStorage; +import forestry.storage.PickupHandlerStorage; +import forestry.storage.ResupplyHandler; +import forestry.storage.items.ItemBackpack; +import forestry.storage.items.ItemNaturalistBackpack; +import forestry.storage.items.ItemNaturalistBackpack.BackpackDefinitionApiarist; +import forestry.storage.items.ItemNaturalistBackpack.BackpackDefinitionLepidopterist; + +@PluginInfo(pluginID = "Storage", name = "Storage", author = "SirSengir", url = Defaults.URL, description = "Adds backpacks and crates.") +public class PluginStorage extends NativePlugin implements IOreDictionaryHandler { + + private final ArrayList minerItems = new ArrayList(); + private final ArrayList diggerItems = new ArrayList(); + private final ArrayList foresterItems = new ArrayList(); + private final ArrayList hunterItems = new ArrayList(); + private final ArrayList adventurerItems = new ArrayList(); + private final ArrayList builderItems = new ArrayList(); + static String CONFIG_CATEGORY = "backpacks"; + Configuration config; + + @Override + public boolean isAvailable() { + return !Config.disableStorage; + } + + @Override + public void preInit() { + BackpackManager.backpackInterface = new BackpackHelper(); + super.preInit(); + createBackpackArrays(); + } + + @Override + public void postInit() { + super.postInit(); + + scanForItems(); + + config = new Configuration(); + + Property backpackConf = config.get("backpacks.miner.items", CONFIG_CATEGORY, ""); + backpackConf.Comment = "add additional blocks and items for the miner's backpack here in the format id:meta. separate blocks and items using ';'. wildcard for metadata: '*'"; + parseBackpackItems("Miner's Backpack", backpackConf.Value, BackpackManager.definitions.get("miner")); + backpackConf = config.get("backpacks.digger.items", CONFIG_CATEGORY, ""); + backpackConf.Comment = "add additional blocks and items for the digger's backpack here in the format id:meta. separate blocks and items using ';'. wildcard for metadata: '*'"; + parseBackpackItems("Digger's Backpack", backpackConf.Value, BackpackManager.definitions.get("digger")); + backpackConf = config.get("backpacks.forester.items", CONFIG_CATEGORY, ""); + backpackConf.Comment = "add additional blocks and items for the forester's backpack here in the format id:meta. separate blocks and items using ';'. wildcard for metadata: '*'"; + parseBackpackItems("Forester's Backpack", backpackConf.Value, BackpackManager.definitions.get("forester")); + backpackConf = config.get("backpacks.hunter.items", CONFIG_CATEGORY, ""); + backpackConf.Comment = "add additional blocks and items for the hunter's backpack here in the format id:meta. separate blocks and items using ';'. wildcard for metadata: '*'"; + parseBackpackItems("Hunter's Backpack", backpackConf.Value, BackpackManager.definitions.get("hunter")); + backpackConf = config.get("backpacks.adventurer.items", CONFIG_CATEGORY, ""); + backpackConf.Comment = "add blocks and items for the adventurer's backpack here in the format id:meta. separate blocks and items using ';'. wildcard for metadata: '*'"; + parseBackpackItems("Adventurer's Backpack", backpackConf.Value, BackpackManager.definitions.get("adventurer")); + backpackConf = config.get("backpacks.builder.items", CONFIG_CATEGORY, ""); + backpackConf.Comment = "add blocks and items for the builder's backpack here in the format id:meta. separate blocks and items using ';'. wildcard for metadata: '*'"; + parseBackpackItems("Builder's Backpack", backpackConf.Value, BackpackManager.definitions.get("builder")); + + config.save(); + + } + + public static void addBackpackItem(String pack, ItemStack stack) { + if (stack == null) + return; + BackpackManager.definitions.get(pack).addValidItem(stack); + } + + public static void addBackpackItem(String pack, Block block) { + BackpackManager.definitions.get(pack).addValidItem(new ItemStack(block, 1, Defaults.WILDCARD)); + } + + public static void addBackpackItem(String pack, Item item) { + BackpackManager.definitions.get(pack).addValidItem(new ItemStack(item, 1, Defaults.WILDCARD)); + } + + public static void scanForItems() { + for (Object id : Block.blockRegistry.getKeys()) { + try { + Block block = (Block) Block.blockRegistry.getObject(id); + + if (block instanceof IPlantable || + block instanceof IShearable || + block instanceof BlockLog || + block instanceof BlockMelon || + block instanceof BlockPumpkin) + addBackpackItem("forester", block); + if (block instanceof BlockStairs || block.getRenderType() == 10 || + block instanceof BlockFence || block.getRenderType() == 11 || + block instanceof BlockFenceGate || block.getRenderType() == 21 || + block instanceof BlockWall || block.getRenderType() == 32 || + block instanceof BlockBasePressurePlate || + block instanceof BlockLever || + block instanceof BlockButton || + block instanceof BlockTorch || + block instanceof BlockRedstoneDiode || + block instanceof BlockChest || block.getRenderType() == 22 || + block instanceof BlockWorkbench || + block instanceof BlockFurnace || + block instanceof BlockLadder || block.getRenderType() == 8 || + block instanceof BlockTrapDoor || + block.getUnlocalizedName().contains("door")) + addBackpackItem("builder", block); + } catch (Throwable error) { + error.printStackTrace(); + } + } + + for (Object id : Item.itemRegistry.getKeys()) { + try { + Item item = (Item) Item.itemRegistry.getObject(id); + + if (item instanceof IPlantable) + addBackpackItem("forester", item); + else if (item instanceof ItemFood) + addBackpackItem("hunter", item); + else if (item instanceof ItemDoor) + addBackpackItem("builder", item); + } catch (Throwable error) { + error.printStackTrace(); + } + } + } + + @Override + public boolean processIMCMessage(IMCMessage message) { + if (message.key.equals("add-backpack-items")) { + String[] tokens = message.getStringValue().split("@"); + if (tokens.length != 2) { + Logger.getLogger("Forestry").log(Level.INFO, + String.format("Received an invalid 'add-backpack-items' request %s from mod %s", message.getStringValue(), message.getSender())); + return true; + } + + if (!BackpackManager.definitions.containsKey(tokens[0])) { + Logger.getLogger("Forestry").log( + Level.INFO, + String.format("Received an invalid 'add-backpack-items' request %s from mod %s for non-existent backpack %s.", + message.getStringValue(), message.getSender(), tokens[0])); + return true; + } + + parseBackpackItems(tokens[0] + "'s Backpack", tokens[1], BackpackManager.definitions.get(tokens[0])); + + return true; + } + return false; + } + + @Override + public IPickupHandler getPickupHandler() { + return new PickupHandlerStorage(); + } + + @Override + public IGuiHandler getGuiHandler() { + return new GuiHandlerStorage(); + } + + @Override + public IResupplyHandler getResupplyHandler() { + return new ResupplyHandler(); + } + + @Override + protected void registerItems() { + // / BACKPACKS + ForestryItem.apiaristBackpack.registerItem(new ItemNaturalistBackpack(GuiId.ApiaristBackpackGUI.ordinal(), new BackpackDefinitionApiarist("apiarist", 0xc4923d)).setCreativeTab(Tabs.tabApiculture), "apiaristBag"); + BackpackDefinition definition = (BackpackDefinition) ((ItemBackpack) ForestryItem.apiaristBackpack.item()).getDefinition(); + BackpackManager.definitions.put(definition.getKey(), definition); + + ForestryItem.lepidopteristBackpack.registerItem(new ItemNaturalistBackpack(GuiId.LepidopteristBackpackGUI.ordinal(), new BackpackDefinitionLepidopterist("lepidopterist", 0x995b31)).setCreativeTab(Tabs.tabLepidopterology), "lepidopteristBag"); + definition = (BackpackDefinition) ((ItemBackpack) ForestryItem.lepidopteristBackpack.item()).getDefinition(); + BackpackManager.definitions.put(definition.getKey(), definition); + + definition = new BackpackDefinition("miner", 0x36187d).setValidItems(BackpackManager.backpackItems[0]); + BackpackManager.definitions.put(definition.getKey(), definition); + ForestryItem.minerBackpack.registerItem(BackpackManager.backpackInterface.addBackpack(definition, EnumBackpackType.T1), "minerBag"); + ForestryItem.minerBackpackT2.registerItem(BackpackManager.backpackInterface.addBackpack(definition, EnumBackpackType.T2), "minerBagT2"); + + definition = new BackpackDefinition("digger", 0x363cc5).setValidItems(BackpackManager.backpackItems[1]); + BackpackManager.definitions.put(definition.getKey(), definition); + ForestryItem.diggerBackpack.registerItem(BackpackManager.backpackInterface.addBackpack(definition, EnumBackpackType.T1), "diggerBag"); + ForestryItem.diggerBackpackT2.registerItem(BackpackManager.backpackInterface.addBackpack(definition, EnumBackpackType.T2), "diggerBagT2"); + + definition = new BackpackDefinition("forester", 0x347427) + .setValidItems(BackpackManager.backpackItems[2]); + BackpackManager.definitions.put(definition.getKey(), definition); + ForestryItem.foresterBackpack.registerItem(BackpackManager.backpackInterface.addBackpack(definition, EnumBackpackType.T1), "foresterBag"); + ForestryItem.foresterBackpackT2.registerItem(BackpackManager.backpackInterface.addBackpack(definition, EnumBackpackType.T2), "foresterBagT2"); + + definition = new BackpackDefinition("hunter", 0x412215).setValidItems(BackpackManager.backpackItems[3]); + BackpackManager.definitions.put(definition.getKey(), definition); + ForestryItem.hunterBackpack.registerItem(BackpackManager.backpackInterface.addBackpack(definition, EnumBackpackType.T1), "hunterBag"); + ForestryItem.hunterBackpackT2.registerItem(BackpackManager.backpackInterface.addBackpack(definition, EnumBackpackType.T2), "hunterBagT2"); + + definition = new BackpackDefinition("adventurer", 0x7fb8c2) + .setValidItems(BackpackManager.backpackItems[4]); + BackpackManager.definitions.put(definition.getKey(), definition); + ForestryItem.adventurerBackpack.registerItem(BackpackManager.backpackInterface.addBackpack(definition, EnumBackpackType.T1), "adventurerBackpack"); + ForestryItem.adventurerBackpackT2.registerItem(BackpackManager.backpackInterface.addBackpack(definition, EnumBackpackType.T2), "adventurerBackpackT2"); + + definition = new BackpackDefinition("builder", 0xdd3a3a) + .setValidItems(BackpackManager.backpackItems[5]); + BackpackManager.definitions.put(definition.getKey(), definition); + ForestryItem.builderBackpack.registerItem(BackpackManager.backpackInterface.addBackpack(definition, EnumBackpackType.T1), "builderBackpack"); + ForestryItem.builderBackpackT2.registerItem(BackpackManager.backpackInterface.addBackpack(definition, EnumBackpackType.T2), "builderBackpackT2"); + + } + + @Override + protected void registerBackpackItems() { + + // [0] Set valid items in miner's backpack + minerItems.add(new ItemStack(Blocks.obsidian)); + minerItems.add(new ItemStack(Blocks.coal_ore)); + minerItems.add(new ItemStack(Items.coal)); + minerItems.add(new ItemStack(Blocks.diamond_ore)); + minerItems.add(new ItemStack(Items.diamond)); + minerItems.add(new ItemStack(Blocks.gold_ore)); + minerItems.add(new ItemStack(Items.gold_ingot)); + minerItems.add(new ItemStack(Blocks.iron_ore)); + minerItems.add(new ItemStack(Items.iron_ingot)); + minerItems.add(new ItemStack(Blocks.lapis_ore)); + minerItems.add(new ItemStack(Blocks.redstone_ore)); + minerItems.add(new ItemStack(Items.redstone)); + minerItems.add(new ItemStack(Items.dye, 1, 4)); + minerItems.add(new ItemStack(Items.glowstone_dust)); + minerItems.add(new ItemStack(Items.emerald)); + minerItems.add(new ItemStack(Blocks.diamond_block)); + minerItems.add(new ItemStack(Blocks.emerald_block)); + minerItems.add(new ItemStack(Blocks.gold_block)); + minerItems.add(new ItemStack(Blocks.iron_block)); + minerItems.add(new ItemStack(Blocks.lapis_block)); + minerItems.add(ForestryItem.bronzePickaxe.getItemStack()); + minerItems.add(ForestryItem.kitPickaxe.getItemStack()); + minerItems.add(ForestryItem.brokenBronzePickaxe.getItemStack()); + minerItems.add(new ItemStack(Items.quartz)); + minerItems.add(new ItemStack(Blocks.emerald_ore)); + minerItems.add(new ItemStack(Blocks.quartz_ore)); + + // [1] Set valid items in digger's backpack + diggerItems.add(new ItemStack(Blocks.dirt)); + diggerItems.add(new ItemStack(Blocks.cobblestone)); + diggerItems.add(new ItemStack(Blocks.sand)); + diggerItems.add(new ItemStack(Blocks.sandstone)); + diggerItems.add(new ItemStack(Blocks.gravel)); + diggerItems.add(new ItemStack(Items.flint)); + diggerItems.add(new ItemStack(Blocks.netherrack)); + diggerItems.add(new ItemStack(Items.clay_ball)); + diggerItems.add(new ItemStack(Blocks.soul_sand)); + diggerItems.add(ForestryItem.bronzeShovel.getItemStack()); + diggerItems.add(ForestryItem.kitShovel.getItemStack()); + diggerItems.add(ForestryItem.brokenBronzeShovel.getItemStack()); + + // [2] Set valid items in forester's backpack + foresterItems.add(new ItemStack(Blocks.sapling, 1, Defaults.WILDCARD)); + foresterItems.add(new ItemStack(Blocks.red_mushroom)); + foresterItems.add(new ItemStack(Blocks.brown_mushroom)); + foresterItems.add(new ItemStack(Blocks.log, 1, Defaults.WILDCARD)); + foresterItems.add(new ItemStack(Items.wheat_seeds)); + foresterItems.add(new ItemStack(Blocks.red_flower)); + foresterItems.add(new ItemStack(Blocks.yellow_flower)); + foresterItems.add(new ItemStack(Blocks.leaves, 1, Defaults.WILDCARD)); + foresterItems.add(new ItemStack(Blocks.cactus)); + foresterItems.add(new ItemStack(Blocks.tallgrass, 1, Defaults.WILDCARD)); + foresterItems.add(new ItemStack(Blocks.vine)); + foresterItems.add(new ItemStack(Blocks.pumpkin)); + foresterItems.add(new ItemStack(Blocks.melon_block)); + foresterItems.add(new ItemStack(Items.apple)); + foresterItems.add(new ItemStack(Items.golden_apple)); + foresterItems.add(new ItemStack(Items.nether_wart)); + foresterItems.add(new ItemStack(Items.pumpkin_seeds)); + foresterItems.add(new ItemStack(Items.melon_seeds)); + foresterItems.add(new ItemStack(Items.wheat)); + foresterItems.add(new ItemStack(ForestryBlock.saplingGE, 1)); + + // [3] Set valid items in hunter's backpack + hunterItems.add(new ItemStack(Items.feather)); + hunterItems.add(new ItemStack(Items.gunpowder)); + hunterItems.add(new ItemStack(Items.blaze_powder)); + hunterItems.add(new ItemStack(Items.blaze_rod)); + hunterItems.add(new ItemStack(Items.bone)); + hunterItems.add(new ItemStack(Items.string)); + hunterItems.add(new ItemStack(Items.rotten_flesh)); + hunterItems.add(new ItemStack(Items.ghast_tear)); + hunterItems.add(new ItemStack(Items.gold_nugget)); + hunterItems.add(new ItemStack(Items.arrow)); + hunterItems.add(new ItemStack(Items.porkchop)); + hunterItems.add(new ItemStack(Items.cooked_porkchop)); + hunterItems.add(new ItemStack(Items.beef)); + hunterItems.add(new ItemStack(Items.cooked_beef)); + hunterItems.add(new ItemStack(Items.chicken)); + hunterItems.add(new ItemStack(Items.cooked_chicken)); + hunterItems.add(new ItemStack(Items.leather)); + hunterItems.add(new ItemStack(Items.egg)); + hunterItems.add(new ItemStack(Items.ender_pearl)); + hunterItems.add(new ItemStack(Items.spider_eye)); + hunterItems.add(new ItemStack(Items.fermented_spider_eye)); + hunterItems.add(new ItemStack(Items.slime_ball)); + hunterItems.add(new ItemStack(Items.dye, 1, 0)); + hunterItems.add(new ItemStack(Blocks.hay_block)); + hunterItems.add(new ItemStack(Blocks.wool)); + hunterItems.add(new ItemStack(Blocks.wool, 1, Defaults.WILDCARD)); + hunterItems.add(new ItemStack(Items.ender_eye)); + hunterItems.add(new ItemStack(Items.magma_cream)); + hunterItems.add(new ItemStack(Items.speckled_melon)); + hunterItems.add(new ItemStack(Items.fish)); + hunterItems.add(new ItemStack(Items.cooked_fished)); + hunterItems.add(new ItemStack(Items.lead)); + hunterItems.add(new ItemStack(Items.fishing_rod)); + hunterItems.add(new ItemStack(Items.name_tag)); + hunterItems.add(new ItemStack(Items.saddle)); + hunterItems.add(new ItemStack(Items.diamond_horse_armor)); + hunterItems.add(new ItemStack(Items.golden_horse_armor)); + hunterItems.add(new ItemStack(Items.iron_horse_armor)); + + // [4] Set valid items in adventurer's backpack + + // [5] Set valid items in builder's backpack + builderItems.add(new ItemStack(Blocks.torch)); + builderItems.add(new ItemStack(Blocks.redstone_torch)); + builderItems.add(new ItemStack(Blocks.unlit_redstone_torch)); + builderItems.add(new ItemStack(Blocks.redstone_lamp)); + builderItems.add(new ItemStack(Blocks.lit_redstone_lamp)); + builderItems.add(new ItemStack(ForestryBlock.candle)); + builderItems.add(new ItemStack(ForestryBlock.stump)); + builderItems.add(new ItemStack(Blocks.stonebrick, 1, Defaults.WILDCARD)); + builderItems.add(new ItemStack(Blocks.sandstone, 1, 1)); + builderItems.add(new ItemStack(Blocks.sandstone, 1, 2)); + builderItems.add(new ItemStack(Blocks.stone)); + builderItems.add(new ItemStack(Blocks.brick_block)); + builderItems.add(new ItemStack(Blocks.planks, 1, Defaults.WILDCARD)); + builderItems.add(new ItemStack(Blocks.hardened_clay, 1, Defaults.WILDCARD)); + builderItems.add(new ItemStack(Blocks.nether_brick)); + builderItems.add(new ItemStack(Blocks.nether_brick_fence)); + builderItems.add(new ItemStack(Blocks.stone_stairs)); + builderItems.add(new ItemStack(Blocks.oak_stairs)); + builderItems.add(new ItemStack(Blocks.brick_stairs)); + builderItems.add(new ItemStack(Blocks.nether_brick_stairs)); + builderItems.add(new ItemStack(Blocks.stone_brick_stairs)); + builderItems.add(new ItemStack(Blocks.glass)); + builderItems.add(new ItemStack(Blocks.glass_pane)); + builderItems.add(new ItemStack(Blocks.chest)); + builderItems.add(new ItemStack(Blocks.crafting_table)); + builderItems.add(new ItemStack(Blocks.furnace)); + builderItems.add(new ItemStack(Blocks.lever)); + builderItems.add(new ItemStack(Blocks.wooden_button)); + builderItems.add(new ItemStack(Blocks.stone_button)); + builderItems.add(new ItemStack(Blocks.dispenser)); + builderItems.add(new ItemStack(Blocks.dropper)); + builderItems.add(new ItemStack(Blocks.ladder)); + builderItems.add(new ItemStack(Blocks.fence)); + builderItems.add(new ItemStack(Blocks.fence_gate)); + builderItems.add(new ItemStack(Blocks.iron_bars)); + builderItems.add(new ItemStack(Blocks.stone_slab, 1, Defaults.WILDCARD)); + builderItems.add(new ItemStack(Blocks.quartz_block, 1, Defaults.WILDCARD)); + builderItems.add(new ItemStack(Blocks.quartz_stairs)); + builderItems.add(new ItemStack(Blocks.sandstone_stairs)); + builderItems.add(new ItemStack(Blocks.birch_stairs)); + builderItems.add(new ItemStack(Blocks.spruce_stairs)); + builderItems.add(new ItemStack(Blocks.jungle_stairs)); + builderItems.add(new ItemStack(Blocks.cobblestone_wall, 1, Defaults.WILDCARD)); + builderItems.add(new ItemStack(Items.iron_door)); + builderItems.add(new ItemStack(Items.wooden_door)); + builderItems.add(new ItemStack(Items.sign)); + builderItems.add(new ItemStack(Items.repeater)); + builderItems.add(new ItemStack(Items.comparator)); + builderItems.add(new ItemStack(Items.item_frame)); + } + + @Override + protected void registerRecipes() { + + // Apiarist's Backpack + Proxies.common.addRecipe(ForestryItem.apiaristBackpack.getItemStack(), + new Object[] { "X#X", "VYV", "X#X", '#', Blocks.wool, 'X', Items.string, 'V', + "stickWood", 'Y', new ItemStack(ForestryBlock.apiculture, 1, Defaults.DEFINITION_APIARISTCHEST_META) }); + // Lepidopterist's Backpack + Proxies.common.addRecipe(ForestryItem.lepidopteristBackpack.getItemStack(), + new Object[] { "X#X", "VYV", "X#X", '#', Blocks.wool, 'X', Items.string, 'V', + "stickWood", 'Y', new ItemStack(ForestryBlock.lepidopterology, 1, Defaults.DEFINITION_LEPICHEST_META) }); + // Miner's Backpack + Proxies.common.addRecipe(ForestryItem.minerBackpack.getItemStack(), + new Object[] { "X#X", "VYV", "X#X", '#', Blocks.wool, 'X', Items.string, 'V', + Items.iron_ingot, 'Y', Blocks.chest }); + // Digger's Backpack + Proxies.common.addRecipe(ForestryItem.diggerBackpack.getItemStack(), + new Object[] { "X#X", "VYV", "X#X", '#', Blocks.wool, 'X', Items.string, 'V', + Blocks.stone, 'Y', Blocks.chest }); + // Forester's Backpack + Proxies.common.addRecipe(ForestryItem.foresterBackpack.getItemStack(), new Object[] { "X#X", "VYV", "X#X", '#', Blocks.wool, + 'X', Items.string, 'V', "logWood", 'Y', Blocks.chest }); + // Hunter's Backpack + Proxies.common.addRecipe(ForestryItem.hunterBackpack.getItemStack(), + new Object[] { "X#X", "VYV", "X#X", '#', Blocks.wool, 'X', Items.string, 'V', + Items.feather, 'Y', Blocks.chest }); + // Adventurer's Backpack + Proxies.common.addRecipe(ForestryItem.adventurerBackpack.getItemStack(), new Object[] { "X#X", "VYV", "X#X", '#', Blocks.wool, + 'X', Items.string, 'V', Items.bone, 'Y', Blocks.chest }); + // Builder's Backpack + Proxies.common.addRecipe(ForestryItem.builderBackpack.getItemStack(), new Object[] { "X#X", "VYV", "X#X", '#', Blocks.wool, + 'X', Items.string, 'V', Items.clay_ball, 'Y', Blocks.chest }); + + // / CARPENTER + // / BACKPACKS T2 + RecipeManagers.carpenterManager.addRecipe(200, LiquidHelper.getLiquid(Defaults.LIQUID_WATER, 1000), null, ForestryItem.minerBackpackT2.getItemStack(), + new Object[] { "WXW", "WTW", "WWW", 'X', Items.diamond, 'W', + ForestryItem.craftingMaterial.getItemStack(1, 3), 'T', ForestryItem.minerBackpack }); + RecipeManagers.carpenterManager.addRecipe(200, LiquidHelper.getLiquid(Defaults.LIQUID_WATER, 1000), null, ForestryItem.diggerBackpackT2.getItemStack(), + new Object[] { "WXW", "WTW", "WWW", 'X', Items.diamond, 'W', + ForestryItem.craftingMaterial.getItemStack(1, 3), 'T', ForestryItem.diggerBackpack }); + RecipeManagers.carpenterManager.addRecipe(200, LiquidHelper.getLiquid(Defaults.LIQUID_WATER, 1000), null, ForestryItem.foresterBackpackT2.getItemStack(), + new Object[] { "WXW", "WTW", "WWW", 'X', Items.diamond, 'W', + ForestryItem.craftingMaterial.getItemStack(1, 3), 'T', ForestryItem.foresterBackpack }); + RecipeManagers.carpenterManager.addRecipe(200, LiquidHelper.getLiquid(Defaults.LIQUID_WATER, 1000), null, ForestryItem.hunterBackpackT2.getItemStack(), + new Object[] { "WXW", "WTW", "WWW", 'X', Items.diamond, 'W', + ForestryItem.craftingMaterial.getItemStack(1, 3), 'T', ForestryItem.hunterBackpack }); + RecipeManagers.carpenterManager.addRecipe(200, LiquidHelper.getLiquid(Defaults.LIQUID_WATER, 1000), null, ForestryItem.adventurerBackpackT2.getItemStack(), + new Object[] { "WXW", "WTW", "WWW", 'X', Items.diamond, 'W', + ForestryItem.craftingMaterial.getItemStack(1, 3), 'T', ForestryItem.adventurerBackpack }); + RecipeManagers.carpenterManager.addRecipe(200, LiquidHelper.getLiquid(Defaults.LIQUID_WATER, 1000), null, ForestryItem.builderBackpackT2.getItemStack(), + new Object[] { "WXW", "WTW", "WWW", 'X', Items.diamond, 'W', + ForestryItem.craftingMaterial.getItemStack(1, 3), 'T', ForestryItem.builderBackpack }); + + } + + @SuppressWarnings("unchecked") + private void createBackpackArrays() { + + if (BackpackManager.backpackItems != null) + return; + + BackpackManager.backpackItems = new ArrayList[6]; + + BackpackManager.backpackItems[0] = minerItems; + BackpackManager.backpackItems[1] = diggerItems; + BackpackManager.backpackItems[2] = foresterItems; + BackpackManager.backpackItems[3] = hunterItems; + BackpackManager.backpackItems[4] = adventurerItems; + BackpackManager.backpackItems[5] = builderItems; + + } + + @Override + protected void registerCrates() { + } + + private static void parseBackpackItems(String backpackIdent, String list, IBackpackDefinition target) { + String[] parts = list.split("[;]+"); + + for (String part : parts) { + if (part.isEmpty()) + continue; + + String[] ident = part.split("[:]+"); + + if (ident.length != 1 && ident.length != 2) { + Proxies.log.warning("Failed to add block/item of (" + part + ") to "+backpackIdent+" since it isn't formatted properly."); + continue; + } + + Item item = GameData.itemRegistry.getObject(ident[0]); + + if (item == null) { + Block block = GameData.blockRegistry.getObject(ident[0]); + + if (block == null || block == Blocks.air || Item.getItemFromBlock(block) == null) { + Proxies.log.warning("Failed to add block/item of (" + part + ") to "+backpackIdent+" since it couldn't be found."); + continue; + } + + item = Item.getItemFromBlock(block); + } + + int meta = 0; + + if (ident.length > 1) { + meta = ident[1].equals("*") ? OreDictionary.WILDCARD_VALUE : Integer.parseInt(ident[1]); + } + + Proxies.log.finer("Adding block/item of (" + part + ") to "+backpackIdent+"."); + target.addValidItem(new ItemStack(item, 1, meta)); + } + } + + @Override + public ISaveEventHandler getSaveEventHandler() { + return null; + } + + @Override + public IOreDictionaryHandler getDictionaryHandler() { + return this; + } + + @Override + public void onOreRegistration(String name, ItemStack ore) { + + createBackpackArrays(); + + if (ore == null) { + Proxies.log.warning("An ore/item of type %s was registered with the Forge ore dictionary, however the passed itemstack is null. Someone broke it. :(", name); + return; + } + + if (name.startsWith("ingot")) + minerItems.add(ore); + else if (name.startsWith("ore")) + minerItems.add(ore); + else if (name.startsWith("gem")) + minerItems.add(ore); + else if (name.startsWith("dust")) + minerItems.add(ore); + else if (name.startsWith("crystal")) + minerItems.add(ore); + else if (name.matches("dropUranium")) + minerItems.add(ore); + else if (name.equals("treeLeaves") || name.equals("treeSapling") || name.equals("logWood")) + foresterItems.add(ore); + else if (name.equals("stairWood") || name.equals("plankWood") || name.equals("slabWood")) + builderItems.add(ore); + else if (name.startsWith("wood")) + foresterItems.add(ore); + } +} diff --git a/forestry_common/storage/forestry/storage/BackpackDefinition.java b/forestry_common/storage/forestry/storage/BackpackDefinition.java new file mode 100755 index 000000000..c761e7f4d --- /dev/null +++ b/forestry_common/storage/forestry/storage/BackpackDefinition.java @@ -0,0 +1,84 @@ +/******************************************************************************* + * Copyright 2011-2014 by SirSengir + * + * This work is licensed under a Creative Commons Attribution-NonCommercial-NoDerivs 3.0 Unported License. + * + * To view a copy of this license, visit http://creativecommons.org/licenses/by-nc-nd/3.0/. + ******************************************************************************/ +package forestry.storage; + +import java.util.ArrayList; + +import net.minecraft.entity.player.EntityPlayer; +import net.minecraft.item.ItemStack; + +import forestry.api.storage.IBackpackDefinition; +import forestry.core.config.Defaults; +import forestry.core.utils.StringUtil; + +public class BackpackDefinition implements IBackpackDefinition { + final String name; + + final int primaryColor; // - c03384 + final int secondaryColor; + + ArrayList validItems = new ArrayList(); + + public BackpackDefinition(String name, int primaryColor) { + this(name, primaryColor, 0xffffff); + } + + public BackpackDefinition(String name, int primaryColor, int secondaryColor) { + this.name = name; + this.primaryColor = primaryColor; + this.secondaryColor = secondaryColor; + } + + @Override + public String getKey() { + return name; + } + + @Override + public String getName() { + return StringUtil.localize("storage.backpack." + name); + } + + @Override + public int getPrimaryColour() { + return primaryColor; + } + + @Override + public int getSecondaryColour() { + return secondaryColor; + } + + public BackpackDefinition setValidItems(ArrayList validItems) { + this.validItems = validItems; + return this; + } + + @Override + public void addValidItem(ItemStack validItem) { + this.validItems.add(validItem); + } + + @Override + public ArrayList getValidItems(EntityPlayer player) { + return validItems; + } + + @Override + public boolean isValidItem(EntityPlayer player, ItemStack itemstack) { + for (ItemStack stack : getValidItems(player)) + if (stack.getItemDamage() == Defaults.WILDCARD) { + if (stack.getItem() == itemstack.getItem()) + return true; + } else if (stack.isItemEqual(itemstack)) + return true; + + return false; + } + +} diff --git a/forestry_common/storage/forestry/storage/BackpackHelper.java b/forestry_common/storage/forestry/storage/BackpackHelper.java new file mode 100755 index 000000000..44c3133e1 --- /dev/null +++ b/forestry_common/storage/forestry/storage/BackpackHelper.java @@ -0,0 +1,26 @@ +/******************************************************************************* + * Copyright 2011-2014 by SirSengir + * + * This work is licensed under a Creative Commons Attribution-NonCommercial-NoDerivs 3.0 Unported License. + * + * To view a copy of this license, visit http://creativecommons.org/licenses/by-nc-nd/3.0/. + ******************************************************************************/ +package forestry.storage; + +import net.minecraft.item.Item; + +import forestry.api.storage.BackpackManager; +import forestry.api.storage.EnumBackpackType; +import forestry.api.storage.IBackpackDefinition; +import forestry.api.storage.IBackpackInterface; +import forestry.storage.items.ItemBackpack; + +public class BackpackHelper implements IBackpackInterface { + + @Override + public Item addBackpack(IBackpackDefinition definition, EnumBackpackType type) { + BackpackManager.definitions.put(definition.getKey(), definition); + return new ItemBackpack(definition, type.ordinal() + 1); + } + +} diff --git a/forestry_common/storage/forestry/storage/BackpackMode.java b/forestry_common/storage/forestry/storage/BackpackMode.java new file mode 100755 index 000000000..2b7299320 --- /dev/null +++ b/forestry_common/storage/forestry/storage/BackpackMode.java @@ -0,0 +1,12 @@ +/******************************************************************************* + * Copyright 2011-2014 by SirSengir + * + * This work is licensed under a Creative Commons Attribution-NonCommercial-NoDerivs 3.0 Unported License. + * + * To view a copy of this license, visit http://creativecommons.org/licenses/by-nc-nd/3.0/. + ******************************************************************************/ +package forestry.storage; + +public enum BackpackMode { + NORMAL, LOCKED, RECEIVE, RESUPPLY +} diff --git a/forestry_common/storage/forestry/storage/GuiHandlerStorage.java b/forestry_common/storage/forestry/storage/GuiHandlerStorage.java new file mode 100755 index 000000000..fdda27494 --- /dev/null +++ b/forestry_common/storage/forestry/storage/GuiHandlerStorage.java @@ -0,0 +1,154 @@ +/******************************************************************************* + * Copyright 2011-2014 by SirSengir + * + * This work is licensed under a Creative Commons Attribution-NonCommercial-NoDerivs 3.0 Unported License. + * + * To view a copy of this license, visit http://creativecommons.org/licenses/by-nc-nd/3.0/. + ******************************************************************************/ +package forestry.storage; + +import net.minecraft.entity.player.EntityPlayer; +import net.minecraft.item.Item; +import net.minecraft.item.ItemStack; +import net.minecraft.world.World; + +import forestry.api.core.ForestryAPI; +import forestry.api.genetics.AlleleManager; +import forestry.api.genetics.ISpeciesRoot; +import forestry.core.GuiHandlerBase; +import forestry.core.config.Defaults; +import forestry.core.gui.GuiNaturalistInventory; +import forestry.core.gui.IPagedInventory; +import forestry.core.network.GuiId; +import forestry.core.utils.ItemInventory; +import forestry.storage.gui.ContainerBackpack; +import forestry.storage.gui.ContainerNaturalistBackpack; +import forestry.storage.gui.GuiBackpack; +import forestry.storage.gui.GuiBackpackT2; +import forestry.storage.items.ItemBackpack; + +public class GuiHandlerStorage extends GuiHandlerBase { + + public static class PagedInventory extends ItemInventory implements IPagedInventory { + + //private final int x, y, z; + private final int guiId; + + public PagedInventory(Class itemClass, int size, ItemStack itemstack, int x, int y, int z, int guiId) { + super(itemClass, size, itemstack); + /*this.x = x; + this.y = y; + this.z = z;*/ + this.guiId = guiId; + } + + @Override + public void flipPage(EntityPlayer player, int page) { + onGuiSaved(player); + player.openGui(ForestryAPI.instance, encodeGuiData(guiId, page), player.worldObj, (int) player.posX, (int) player.posY, (int) player.posZ); + } + } + + @Override + public Object getClientGuiElement(int id, EntityPlayer player, World world, int x, int y, int z) { + int cleanId = decodeGuiID(id); + int guiData = decodeGuiData(id); + + if (cleanId >= GuiId.values().length) + return null; + + ItemStack equipped; + switch (GuiId.values()[cleanId]) { + + case ApiaristBackpackGUI: + equipped = getBackpackItem(player); + if (equipped == null) + return null; + ISpeciesRoot speciesRoot = AlleleManager.alleleRegistry.getSpeciesRoot("rootBees"); + PagedInventory inventory = new PagedInventory(ItemBackpack.class, Defaults.SLOTS_BACKPACK_APIARIST, equipped, x, y, z, cleanId); + return new GuiNaturalistInventory(speciesRoot, player, new ContainerNaturalistBackpack(speciesRoot, player.inventory, inventory, guiData, 25), inventory, guiData, 5); + + case BackpackGUI: + equipped = getBackpackItem(player); + if (equipped == null) + return null; + return new GuiBackpack(new ContainerBackpack(player, new ItemInventory(ItemBackpack.class, Defaults.SLOTS_BACKPACK_DEFAULT, equipped))); + + case BackpackT2GUI: + equipped = getBackpackItem(player); + if (equipped == null) + return null; + return new GuiBackpackT2(new ContainerBackpack(player, new ItemInventory(ItemBackpack.class, Defaults.SLOTS_BACKPACK_T2, equipped))); + + case LepidopteristBackpackGUI: + equipped = getBackpackItem(player); + if (equipped == null) + return null; + speciesRoot = AlleleManager.alleleRegistry.getSpeciesRoot("rootButterflies"); + inventory = new PagedInventory(ItemBackpack.class, Defaults.SLOTS_BACKPACK_APIARIST, equipped, x, y, z, id); + return new GuiNaturalistInventory(speciesRoot, player, new ContainerNaturalistBackpack(speciesRoot, player.inventory, inventory, guiData, 25), inventory, guiData, 5); + + default: + return null; + + } + } + + private ItemStack getBackpackItem(EntityPlayer player) { + ItemStack equipped = getEquippedItem(player); + if (equipped == null) + return null; + if (equipped.getItem() instanceof ItemBackpack) + return equipped; + return null; + } + + @Override + public Object getServerGuiElement(int id, EntityPlayer player, World world, int x, int y, int z) { + int cleanId = decodeGuiID(id); + int guiData = decodeGuiData(id); + + if (cleanId >= GuiId.values().length) + return null; + + ItemStack equipped; + switch (GuiId.values()[cleanId]) { + + case ApiaristBackpackGUI: + equipped = getBackpackItem(player); + if (equipped == null) + return null; + + ISpeciesRoot speciesRoot = AlleleManager.alleleRegistry.getSpeciesRoot("rootBees"); + speciesRoot.getBreedingTracker(world, player.getGameProfile().getId()).synchToPlayer(player); + return new ContainerNaturalistBackpack(speciesRoot, player.inventory, new PagedInventory(ItemBackpack.class, Defaults.SLOTS_BACKPACK_APIARIST, equipped, x, y, z, cleanId), guiData, 25); + + case BackpackGUI: + equipped = getBackpackItem(player); + if (equipped == null) + return null; + + return new ContainerBackpack(player, new ItemInventory(ItemBackpack.class, Defaults.SLOTS_BACKPACK_DEFAULT, equipped)); + + case BackpackT2GUI: + equipped = getBackpackItem(player); + if (equipped == null) + return null; + + return new ContainerBackpack(player, new ItemInventory(ItemBackpack.class, Defaults.SLOTS_BACKPACK_T2, equipped)); + + case LepidopteristBackpackGUI: + equipped = getBackpackItem(player); + if (equipped == null) + return null; + + speciesRoot = AlleleManager.alleleRegistry.getSpeciesRoot("rootButterflies"); + speciesRoot.getBreedingTracker(world, player.getGameProfile().getId()).synchToPlayer(player); + return new ContainerNaturalistBackpack(speciesRoot, player.inventory, new PagedInventory(ItemBackpack.class, Defaults.SLOTS_BACKPACK_APIARIST, equipped, x, y, z, cleanId), guiData, 25); + + default: + return null; + + } + } +} diff --git a/forestry_common/storage/forestry/storage/PickupHandlerStorage.java b/forestry_common/storage/forestry/storage/PickupHandlerStorage.java new file mode 100755 index 000000000..7ebafc0a5 --- /dev/null +++ b/forestry_common/storage/forestry/storage/PickupHandlerStorage.java @@ -0,0 +1,99 @@ +/******************************************************************************* + * Copyright 2011-2014 by SirSengir + * + * This work is licensed under a Creative Commons Attribution-NonCommercial-NoDerivs 3.0 Unported License. + * + * To view a copy of this license, visit http://creativecommons.org/licenses/by-nc-nd/3.0/. + ******************************************************************************/ +package forestry.storage; + +import net.minecraft.entity.item.EntityItem; +import net.minecraft.entity.player.EntityPlayer; +import net.minecraft.item.ItemStack; + +import forestry.core.gui.ContainerNaturalistInventory; +import forestry.core.interfaces.IPickupHandler; +import forestry.storage.gui.ContainerBackpack; +import forestry.storage.items.ItemBackpack; + +public class PickupHandlerStorage implements IPickupHandler { + + @Override + public boolean onItemPickup(EntityPlayer player, EntityItem entityitem) { + + ItemStack itemstack = entityitem.getEntityItem(); + if (itemstack == null || itemstack.stackSize <= 0) + return false; + + // Do not pick up if a backpack is open // FIXME: Must not contain + // anything from apiculture + if (player.openContainer instanceof ContainerBackpack || player.openContainer instanceof ContainerNaturalistInventory) + return true; + + // Make sure to top off manually placed itemstacks in player + // inventory first + topOffPlayerInventory(player, itemstack); + + for (ItemStack pack : player.inventory.mainInventory) { + + if (pack == null || pack.stackSize <= 0) + continue; + + if (itemstack == null || itemstack.stackSize <= 0) + break; + + if (!(pack.getItem() instanceof ItemBackpack)) + continue; + + ItemBackpack backpack = ((ItemBackpack) pack.getItem()); + if (backpack.getDefinition().isValidItem(player, itemstack)) + backpack.tryStowing(player, pack, itemstack); + } + + if (itemstack == null || itemstack.stackSize <= 0) + return false; + else + return true; + } + + /** + * This tops off existing stacks in the player's inventory. That way you can keep f.e. a stack of dirt or cobblestone in your inventory which gets refreshed + * constantly by picked up items. + * + * @param player + * @param itemstack + */ + private void topOffPlayerInventory(EntityPlayer player, ItemStack itemstack) { + + // Add to player inventory first, if there is an incomplete stack in + // there. + for (int i = 0; i < player.inventory.getSizeInventory(); i++) { + ItemStack inventoryStack = player.inventory.getStackInSlot(i); + // We only add to existing stacks. + if (inventoryStack == null) + continue; + + // Already full + if (inventoryStack.stackSize >= inventoryStack.getMaxStackSize()) + continue; + + if (inventoryStack.isItemEqual(itemstack) && ItemStack.areItemStackTagsEqual(inventoryStack, itemstack)) { + int space = inventoryStack.getMaxStackSize() - inventoryStack.stackSize; + + // Enough space to add all + if (space > itemstack.stackSize) { + inventoryStack.stackSize += itemstack.stackSize; + itemstack.stackSize = 0; + itemstack = null; + break; + // Only part can be added + } else { + inventoryStack.stackSize = inventoryStack.getMaxStackSize(); + itemstack.stackSize -= space; + } + } + } + + } + +} diff --git a/forestry_common/storage/forestry/storage/ResupplyHandler.java b/forestry_common/storage/forestry/storage/ResupplyHandler.java new file mode 100755 index 000000000..79a602d71 --- /dev/null +++ b/forestry_common/storage/forestry/storage/ResupplyHandler.java @@ -0,0 +1,127 @@ +/******************************************************************************* + * Copyright 2011-2014 by SirSengir + * + * This work is licensed under a Creative Commons Attribution-NonCommercial-NoDerivs 3.0 Unported License. + * + * To view a copy of this license, visit http://creativecommons.org/licenses/by-nc-nd/3.0/. + ******************************************************************************/ +package forestry.storage; + +import net.minecraft.entity.player.EntityPlayer; +import net.minecraft.inventory.ContainerPlayer; +import net.minecraft.item.ItemStack; + +import cpw.mods.fml.common.eventhandler.Event; + +import net.minecraftforge.common.MinecraftForge; + +import forestry.api.storage.BackpackManager; +import forestry.api.storage.BackpackResupplyEvent; +import forestry.api.storage.IBackpackDefinition; +import forestry.core.interfaces.IResupplyHandler; +import forestry.core.utils.ItemInventory; +import forestry.storage.items.ItemBackpack; + +public class ResupplyHandler implements IResupplyHandler { + + @Override + public void resupply(EntityPlayer player) { + + // Do not attempt resupplying if this backpack is already opened. + if (!(player.openContainer instanceof ContainerPlayer)) + return; + + for (IBackpackDefinition backpack : BackpackManager.definitions.values()) + resupply(backpack, player); + + } + + public void resupply(IBackpackDefinition backpackItem, EntityPlayer player) { + + // Get all backpacks of this type in the player's inventory + for (ItemStack backpack : player.inventory.mainInventory) { + + if (backpack == null || backpack.stackSize <= 0) + continue; + + if (!(backpack.getItem() instanceof ItemBackpack)) + continue; + + // Only handle those in resupply mode + if (ItemBackpack.getMode(backpack) != BackpackMode.RESUPPLY) + continue; + + // Delay before resupplying + if (backpack.getItemDamage() < 40) { + backpack.setItemDamage(backpack.getItemDamage() + 1); + continue; + } + + // Load their inventory + ItemBackpack packItem = ((ItemBackpack) backpack.getItem()); + ItemInventory backpackinventory = new ItemInventory(ItemBackpack.class, packItem.getBackpackSize(), backpack); + Event event = new BackpackResupplyEvent(player, packItem.getDefinition(), backpackinventory); + MinecraftForge.EVENT_BUS.post(event); + if (event.isCanceled()) + continue; + + boolean inventoryChanged = false; + // Cycle through their contents + for (int i = 0; i < backpackinventory.getSizeInventory(); i++) { + + ItemStack packstack = backpackinventory.getStackInSlot(i); + if (packstack == null) + continue; + if (packstack.stackSize <= 0) + continue; + + // Try to add it to the player's inventory and note any change + boolean change = topOffPlayerInventory(player, packstack); + if (!inventoryChanged) + inventoryChanged = change; + + // Clear consumed stacks + if (packstack.stackSize <= 0) + backpackinventory.setInventorySlotContents(i, null); + } + // Save the backpack inventory if it changed + if (inventoryChanged) + backpackinventory.onGuiSaved(player); + + } + } + + /** + * This tops off existing stacks in the player's inventory. + * + * @param player + * @param itemstack + */ + private boolean topOffPlayerInventory(EntityPlayer player, ItemStack itemstack) { + + // Add to player inventory first, if there is an incomplete stack in + // there. + for (int i = 0; i < player.inventory.getSizeInventory(); i++) { + ItemStack inventoryStack = player.inventory.getStackInSlot(i); + // We only add to existing stacks. + if (inventoryStack == null) + continue; + + // Already full + if (inventoryStack.stackSize >= inventoryStack.getMaxStackSize()) + continue; + + if (inventoryStack.isItemEqual(itemstack) && ItemStack.areItemStackTagsEqual(inventoryStack, itemstack)) { + + inventoryStack.stackSize++; + itemstack.stackSize--; + if (itemstack.stackSize <= 0) + itemstack = null; + return true; + } + } + return false; + + } + +} diff --git a/forestry_common/storage/forestry/storage/gui/ContainerBackpack.java b/forestry_common/storage/forestry/storage/gui/ContainerBackpack.java new file mode 100755 index 000000000..8470cd121 --- /dev/null +++ b/forestry_common/storage/forestry/storage/gui/ContainerBackpack.java @@ -0,0 +1,73 @@ +/******************************************************************************* + * Copyright 2011-2014 by SirSengir + * + * This work is licensed under a Creative Commons Attribution-NonCommercial-NoDerivs 3.0 Unported License. + * + * To view a copy of this license, visit http://creativecommons.org/licenses/by-nc-nd/3.0/. + ******************************************************************************/ +package forestry.storage.gui; + +import net.minecraft.entity.player.EntityPlayer; +import net.minecraft.item.ItemStack; + +import forestry.core.config.Defaults; +import forestry.core.gui.ContainerItemInventory; +import forestry.core.gui.slots.SlotCustom; +import forestry.core.utils.ItemInventory; +import forestry.storage.items.ItemBackpack; + +public class ContainerBackpack extends ContainerItemInventory { + + public ContainerBackpack(EntityPlayer player, ItemInventory inventory) { + super(inventory, player); + + int lines = 0; + int columns = 0; + int startX = 0; + int startY = 0; + if (inventory.getSizeInventory() == Defaults.SLOTS_BACKPACK_DEFAULT) { + lines = 3; + columns = 5; + startX = 44; + startY = 19; + } else if (inventory.getSizeInventory() == Defaults.SLOTS_BACKPACK_T2) { + lines = 5; + columns = 9; + startX = 8; + startY = 8; + } + + // Inventory + for (int j = 0; j < lines; j++) + for (int k = 0; k < columns; k++) { + int slot = k + j * columns; + addSlot(new SlotCustom(inventory, ((ItemBackpack) inventory.parent.getItem()).getValidItems(player), slot, startX + k * 18, startY + j * 18)); + } + + // Player inventory + for (int i = 0; i < 3; i++) + for (int j = 0; j < 9; j++) + addSecuredSlot(player.inventory, j + i * 9 + 9, 8 + j * 18, 11 + startY + lines * 18 + i * 18); + // Player hotbar + for (int i = 0; i < 9; i++) + addSecuredSlot(player.inventory, i, 8 + i * 18, 11 + startY + lines * 18 + 58); + } + + @Override + protected boolean isAcceptedItem(EntityPlayer player, ItemStack stack) { + // FIXME: This is incorrect. + // However, if we return false here, even valid items will be dropped + // while being kept inside the backpack, leading to duping. + // inventory.parent will turn null with the current implementation if + // something is put inside a backpack and the backpack is then + // moved from the action bar into the player's inventory. + if (inventory.parent == null) + return true; + + if (!(inventory.parent.getItem() instanceof ItemBackpack)) + return false; + + return ((ItemBackpack) inventory.parent.getItem()).getDefinition().isValidItem(player, stack); + } + +} diff --git a/forestry_common/storage/forestry/storage/gui/ContainerNaturalistBackpack.java b/forestry_common/storage/forestry/storage/gui/ContainerNaturalistBackpack.java new file mode 100755 index 000000000..64268f617 --- /dev/null +++ b/forestry_common/storage/forestry/storage/gui/ContainerNaturalistBackpack.java @@ -0,0 +1,81 @@ +/******************************************************************************* + * Copyright 2011-2014 by SirSengir + * + * This work is licensed under a Creative Commons Attribution-NonCommercial-NoDerivs 3.0 Unported License. + * + * To view a copy of this license, visit http://creativecommons.org/licenses/by-nc-nd/3.0/. + ******************************************************************************/ +package forestry.storage.gui; + +import net.minecraft.entity.player.EntityPlayer; +import net.minecraft.entity.player.InventoryPlayer; +import net.minecraft.item.ItemStack; + +import forestry.api.genetics.ISpeciesRoot; +import forestry.core.gui.ContainerItemInventory; +import forestry.core.gui.IGuiSelectable; +import forestry.core.gui.slots.SlotCustom; +import forestry.core.network.PacketUpdate; +import forestry.core.proxy.Proxies; +import forestry.storage.GuiHandlerStorage.PagedInventory; + +public class ContainerNaturalistBackpack extends ContainerItemInventory implements IGuiSelectable { + + private final PagedInventory inv; + private ISpeciesRoot speciesRoot; + + public ContainerNaturalistBackpack(ISpeciesRoot speciesRoot, InventoryPlayer player, PagedInventory inventory, int page, int pageSize) { + super(inventory, player.player); + + this.inv = inventory; + this.speciesRoot = speciesRoot; + + // Inventory + for (int x = 0; x < 5; x++) { + for (int y = 0; y < 5; y++) { + addSlot(new SlotCustom(inventory, y + page * pageSize + x * 5, 100 + y * 18, 21 + x * 18, new Object[] { speciesRoot })); + } + } + + // Player inventory + for (int i1 = 0; i1 < 3; i1++) { + for (int l1 = 0; l1 < 9; l1++) { + addSecuredSlot(player, l1 + i1 * 9 + 9, 18 + l1 * 18, 120 + i1 * 18); + } + } + // Player hotbar + for (int j1 = 0; j1 < 9; j1++) { + addSecuredSlot(player, j1, 18 + j1 * 18, 178); + } + } + + @Override + public void purgeBag(EntityPlayer player) { + for (int i = 0; i < inventory.getSizeInventory(); i++) { + ItemStack stack = inventory.getStackInSlot(i); + if (stack == null) + continue; + + if (speciesRoot.isMember(stack)) + continue; + + Proxies.common.dropItemPlayer(player, stack); + inventory.setInventorySlotContents(i, null); + } + } + + @Override + protected boolean isAcceptedItem(EntityPlayer player, ItemStack stack) { + // TODO Auto-generated method stub + return false; + } + + @Override + public void handleSelectionChange(EntityPlayer player, PacketUpdate packet) { + inv.flipPage(player, packet.payload.intPayload[0]); + } + + @Override + public void setSelection(PacketUpdate packet) { + } +} diff --git a/forestry_common/storage/forestry/storage/gui/GuiBackpack.java b/forestry_common/storage/forestry/storage/gui/GuiBackpack.java new file mode 100755 index 000000000..bf706b83f --- /dev/null +++ b/forestry_common/storage/forestry/storage/gui/GuiBackpack.java @@ -0,0 +1,29 @@ +/******************************************************************************* + * Copyright 2011-2014 by SirSengir + * + * This work is licensed under a Creative Commons Attribution-NonCommercial-NoDerivs 3.0 Unported License. + * + * To view a copy of this license, visit http://creativecommons.org/licenses/by-nc-nd/3.0/. + ******************************************************************************/ +package forestry.storage.gui; + +import forestry.core.config.Defaults; +import forestry.core.gadgets.TileForestry; +import forestry.core.gui.ContainerForestry; +import forestry.core.gui.GuiForestry; + +public class GuiBackpack extends GuiForestry { + + public GuiBackpack(ContainerForestry container) { + this(Defaults.TEXTURE_PATH_GUI + "/backpack.png", container); + } + + protected GuiBackpack(String texture, ContainerForestry container) { + super(texture, container); + } + + @Override + protected boolean checkHotbarKeys(int key) { + return false; + } +} diff --git a/forestry_common/storage/forestry/storage/gui/GuiBackpackT2.java b/forestry_common/storage/forestry/storage/gui/GuiBackpackT2.java new file mode 100755 index 000000000..06e2a6657 --- /dev/null +++ b/forestry_common/storage/forestry/storage/gui/GuiBackpackT2.java @@ -0,0 +1,22 @@ +/******************************************************************************* + * Copyright 2011-2014 by SirSengir + * + * This work is licensed under a Creative Commons Attribution-NonCommercial-NoDerivs 3.0 Unported License. + * + * To view a copy of this license, visit http://creativecommons.org/licenses/by-nc-nd/3.0/. + ******************************************************************************/ +package forestry.storage.gui; + + +import forestry.core.config.Defaults; +import forestry.core.gui.ContainerForestry; + +public class GuiBackpackT2 extends GuiBackpack { + + public GuiBackpackT2(ContainerForestry container) { + super(Defaults.TEXTURE_PATH_GUI + "/backpackT2.png", container); + + xSize = 176; + ySize = 192; + } +} diff --git a/forestry_common/storage/forestry/storage/items/ItemBackpack.java b/forestry_common/storage/forestry/storage/items/ItemBackpack.java new file mode 100755 index 000000000..eb60fd6ce --- /dev/null +++ b/forestry_common/storage/forestry/storage/items/ItemBackpack.java @@ -0,0 +1,351 @@ +/******************************************************************************* + * Copyright 2011-2014 by SirSengir + * + * This work is licensed under a Creative Commons Attribution-NonCommercial-NoDerivs 3.0 Unported License. + * + * To view a copy of this license, visit http://creativecommons.org/licenses/by-nc-nd/3.0/. + ******************************************************************************/ +package forestry.storage.items; + +import java.util.Collection; +import java.util.List; +import java.util.Locale; + +import net.minecraft.client.renderer.texture.IIconRegister; +import net.minecraft.entity.player.EntityPlayer; +import net.minecraft.inventory.IInventory; +import net.minecraft.item.ItemStack; +import net.minecraft.tileentity.TileEntity; +import net.minecraft.util.IIcon; +import net.minecraft.world.World; + +import cpw.mods.fml.common.eventhandler.Event; +import cpw.mods.fml.relauncher.Side; +import cpw.mods.fml.relauncher.SideOnly; + +import net.minecraftforge.common.MinecraftForge; +import net.minecraftforge.common.util.ForgeDirection; + +import forestry.api.core.ForestryAPI; +import forestry.api.storage.BackpackStowEvent; +import forestry.api.storage.EnumBackpackType; +import forestry.api.storage.IBackpackDefinition; +import forestry.core.config.Defaults; +import forestry.core.inventory.InvTools; +import forestry.core.inventory.wrappers.IInvSlot; +import forestry.core.inventory.wrappers.InventoryIterator; +import forestry.core.items.ItemInventoried; +import forestry.core.network.GuiId; +import forestry.core.proxy.Proxies; +import forestry.core.render.TextureManager; +import forestry.core.utils.ItemInventory; +import forestry.core.utils.StringUtil; +import forestry.storage.BackpackMode; + +public class ItemBackpack extends ItemInventoried { + + IBackpackDefinition info; + byte type; + + public ItemBackpack(IBackpackDefinition info, int type) { + super(); + this.info = info; + this.type = (byte) type; + setMaxStackSize(1); + } + + public IBackpackDefinition getDefinition() { + return info; + } + + /** + * @return true if the item's stackTagCompound needs to be synchronized over + * SMP. + */ + @Override + public boolean getShareTag() { + return true; + } + + @Override + public ItemStack onItemRightClick(ItemStack itemstack, World world, EntityPlayer player) { + + if (!Proxies.common.isSimulating(world)) + return itemstack; + + if (!player.isSneaking()) + openGui(player, itemstack); + else + switchMode(itemstack); + return itemstack; + + } + + @Override + public boolean onItemUse(ItemStack itemstack, EntityPlayer player, World world, int x, int y, int z, int side, float hitX, float hitY, float hitZ) { + if (getInventoryHit(world, x, y, z, side) != null) + return true; + else + return false; + } + + @Override + public boolean onItemUseFirst(ItemStack itemstack, EntityPlayer player, World world, int x, int y, int z, int side, float hitX, float hitY, float hitZ) { + + if (!Proxies.common.isSimulating(world)) + return false; + + // We only do this when shift is clicked + if (!player.isSneaking()) + return false; + + return evaluateTileHit(itemstack, player, world, x, y, z, side, hitX, hitY, hitZ); + } + + public ItemStack tryStowing(EntityPlayer player, ItemStack backpackStack, ItemStack stack) { + + ItemBackpack backpack = ((ItemBackpack) backpackStack.getItem()); + ItemInventory inventory = new ItemInventory(ItemBackpack.class, backpack.getBackpackSize(), backpackStack); + if (backpackStack.getItemDamage() == 1) + return stack; + + Event event = new BackpackStowEvent(player, backpack.getDefinition(), inventory, stack); + MinecraftForge.EVENT_BUS.post(event); + if (stack.stackSize <= 0) + return null; + if (event.isCanceled()) + return stack; + + ItemStack remainder = InvTools.moveItemStack(stack, inventory); + stack.stackSize = remainder == null ? 0 : remainder.stackSize; + + inventory.save(); + return null; + } + + private void switchMode(ItemStack itemstack) { + BackpackMode mode = getMode(itemstack); + if (mode == BackpackMode.RESUPPLY) + itemstack.setItemDamage(0); + else if (mode == BackpackMode.RECEIVE) + itemstack.setItemDamage(3); + else if (mode == BackpackMode.LOCKED) + itemstack.setItemDamage(2); + else + itemstack.setItemDamage(1); + } + + private IInventory getInventoryHit(World world, int x, int y, int z, int side) { + TileEntity targeted = world.getTileEntity(x, y, z); + return InvTools.getInventoryFromTile(targeted, ForgeDirection.getOrientation(side)); + } + + private boolean evaluateTileHit(ItemStack stack, EntityPlayer player, World world, int x, int y, int z, int side, float hitX, float hitY, float hitZ) { + + // Shift right-clicking on an inventory tile will attempt to transfer + // items contained in the backpack + IInventory inventory = getInventoryHit(world, x, y, z, side); + // Process only inventories + if (inventory != null) { + + // Must have inventory slots + if (inventory.getSizeInventory() <= 0) + return true; + + // Create our own backpack inventory + ItemInventory backpackInventory = new ItemInventory(ItemBackpack.class, getBackpackSize(), stack); + + if (stack.getItemDamage() == 2) + tryChestReceive(player, backpackInventory, inventory); + else + tryChestTransfer(backpackInventory, inventory); + + backpackInventory.save(); + + return true; + } + + return false; + } + + private void tryChestTransfer(ItemInventory backpackInventory, IInventory target) { + + for (IInvSlot slot : InventoryIterator.getIterable(backpackInventory)) { + ItemStack packStack = slot.getStackInSlot(); + if (packStack == null) + continue; + + ItemStack remaining = InvTools.moveItemStack(packStack, target); + slot.setStackInSlot(remaining); + } + } + + private void tryChestReceive(EntityPlayer player, ItemInventory backpackInventory, IInventory target) { + + for (IInvSlot slot : InventoryIterator.getIterable(target)) { + ItemStack targetStack = slot.getStackInSlot(); + if (targetStack == null) + continue; + + if(!info.isValidItem(player, targetStack)) + continue; + + ItemStack remaining = InvTools.moveItemStack(targetStack, backpackInventory); + slot.setStackInSlot(remaining); + } + + } + + public void openGui(EntityPlayer entityplayer, ItemStack itemstack) { + if (getBackpackSize() == Defaults.SLOTS_BACKPACK_DEFAULT) + entityplayer.openGui(ForestryAPI.instance, GuiId.BackpackGUI.ordinal(), entityplayer.worldObj, (int) entityplayer.posX, (int) entityplayer.posY, + (int) entityplayer.posZ); + else if (getBackpackSize() == Defaults.SLOTS_BACKPACK_T2) + entityplayer.openGui(ForestryAPI.instance, GuiId.BackpackT2GUI.ordinal(), entityplayer.worldObj, (int) entityplayer.posX, (int) entityplayer.posY, + (int) entityplayer.posZ); + } + + public boolean isBackpack(ItemStack stack) { + if (stack == null) + return false; + + return stack.getItem() == this; + } + + public Collection getValidItems(EntityPlayer player) { + return info.getValidItems(player); + } + + public int getBackpackSize() { + return getSlotsForType(type); + } + + @SuppressWarnings({ "rawtypes", "unchecked" }) + @Override + public void addInformation(ItemStack itemstack, EntityPlayer player, List list, boolean flag) { + ItemInventory inventory = new ItemInventory(ItemBackpack.class, getBackpackSize(), itemstack); + + // HashMap contents = new HashMap(); + int occupied = 0; + + for (int i = 0; i < inventory.getSizeInventory(); i++) { + if (inventory.getStackInSlot(i) == null) + continue; + if (inventory.getStackInSlot(i).stackSize <= 0) + continue; + + // Count the slot as occupied + occupied++; + } + + BackpackMode mode = getMode(itemstack); + if (mode == BackpackMode.LOCKED) + list.add("(LOCKED)"); + else if (mode == BackpackMode.RECEIVE) + list.add("(RECEIVING)"); + else if (mode == BackpackMode.RESUPPLY) + list.add("(RESUPPLY)"); + list.add(occupied + "/" + getBackpackSize() + " " + StringUtil.localize("gui.slots")); + + } + + @Override + public String getItemStackDisplayName(ItemStack itemstack) { + if (type > 1) + return StringUtil.localize("storage.backpack.t2adj") + " " + info.getName(); + else + return info.getName(); + } + + /* ICONS */ + @SideOnly(Side.CLIENT) + private IIcon[][] icons; + + @SideOnly(Side.CLIENT) + @Override + public void registerIcons(IIconRegister register) { + icons = new IIcon[EnumBackpackType.values().length][6]; + + for (int i = 0; i < EnumBackpackType.values().length; i++) { + icons[i][0] = TextureManager.getInstance().registerTex( + register, "backpacks/" + EnumBackpackType.values()[i].toString().toLowerCase(Locale.ENGLISH) + ".cloth"); + icons[i][1] = TextureManager.getInstance().registerTex( + register, "backpacks/" + EnumBackpackType.values()[i].toString().toLowerCase(Locale.ENGLISH) + ".outline"); + icons[i][2] = TextureManager.getInstance().registerTex(register, "backpacks/neutral"); + icons[i][3] = TextureManager.getInstance().registerTex(register, "backpacks/locked"); + icons[i][4] = TextureManager.getInstance().registerTex(register, "backpacks/receive"); + icons[i][5] = TextureManager.getInstance().registerTex(register, "backpacks/resupply"); + } + } + + // Return true to enable color overlay - client side only + @Override + public boolean requiresMultipleRenderPasses() { + return true; + } + + @Override + public int getRenderPasses(int metadata) { + return 3; + } + + @Override + public int getColorFromItemStack(ItemStack itemstack, int j) { + + if (j == 0) + return info.getPrimaryColour(); + else if (j == 1) + return info.getSecondaryColour(); + else + return 0xffffff; + } + + @SideOnly(Side.CLIENT) + @Override + public IIcon getIconFromDamageForRenderPass(int i, int j) { + + int iconType = type; + if (type > 0) + iconType--; + + if (j == 0) + return icons[iconType][0]; + if (j == 1) + return icons[iconType][1]; + + if (i > 2) + return icons[iconType][5]; + else if (i > 1) + return icons[iconType][4]; + else if (i > 0) + return icons[iconType][3]; + else + return icons[iconType][2]; + } + + public static int getSlotsForType(int type) { + switch (type) { + case 0: + return Defaults.SLOTS_BACKPACK_APIARIST; + case 2: + return Defaults.SLOTS_BACKPACK_T2; + case 1: + default: + return Defaults.SLOTS_BACKPACK_DEFAULT; + } + } + + public static BackpackMode getMode(ItemStack backpack) { + int meta = backpack.getItemDamage(); + + if (meta >= 3) + return BackpackMode.RESUPPLY; + else if (meta >= 2) + return BackpackMode.RECEIVE; + else if (meta >= 1) + return BackpackMode.LOCKED; + else + return BackpackMode.NORMAL; + } +} diff --git a/forestry_common/storage/forestry/storage/items/ItemNaturalistBackpack.java b/forestry_common/storage/forestry/storage/items/ItemNaturalistBackpack.java new file mode 100755 index 000000000..41af04866 --- /dev/null +++ b/forestry_common/storage/forestry/storage/items/ItemNaturalistBackpack.java @@ -0,0 +1,61 @@ +/******************************************************************************* + * Copyright 2011-2014 by SirSengir + * + * This work is licensed under a Creative Commons Attribution-NonCommercial-NoDerivs 3.0 Unported License. + * + * To view a copy of this license, visit http://creativecommons.org/licenses/by-nc-nd/3.0/. + ******************************************************************************/ +package forestry.storage.items; + +import java.util.ArrayList; + +import net.minecraft.entity.player.EntityPlayer; +import net.minecraft.item.ItemStack; + +import forestry.api.core.ForestryAPI; +import forestry.plugins.PluginApiculture; +import forestry.plugins.PluginLepidopterology; +import forestry.storage.BackpackDefinition; + +public class ItemNaturalistBackpack extends ItemBackpack { + + public static class BackpackDefinitionApiarist extends BackpackDefinition { + + public BackpackDefinitionApiarist(String name, int primaryColor) { + super(name, primaryColor); + } + + @Override + public boolean isValidItem(EntityPlayer player, ItemStack stack) { + return PluginApiculture.beeInterface.isMember(stack); + } + } + + public static class BackpackDefinitionLepidopterist extends BackpackDefinition { + + public BackpackDefinitionLepidopterist(String name, int primaryColor) { + super(name, primaryColor); + } + + @Override + public boolean isValidItem(EntityPlayer player, ItemStack stack) { + return PluginLepidopterology.butterflyInterface.isMember(stack); + } + } + private final int guiId; + + public ItemNaturalistBackpack(int guiId, BackpackDefinition definition) { + super(definition, 0); + this.guiId = guiId; + } + + @Override + public void openGui(EntityPlayer player, ItemStack itemstack) { + player.openGui(ForestryAPI.instance, guiId, player.worldObj, (int) player.posX, (int) player.posY, (int) player.posZ); + } + + @Override + public ArrayList getValidItems(EntityPlayer player) { + return null; + } +} diff --git a/forestry_resources/CREDITS.txt b/forestry_resources/CREDITS.txt new file mode 100755 index 000000000..5d9c630f7 --- /dev/null +++ b/forestry_resources/CREDITS.txt @@ -0,0 +1,27 @@ + +Forestry for Minecraft +CREDITS + +I'd like to thank and mention the following people who helped in the making of this mod or whose own work made it possible: + +MCP Team, Searge - MCP, without which modding Minecraft would be a pain +SpaceToad - Minecraft Forge, BuildCraft +CPW - FML, Forge +IC2 Team - IndustrialCraft 2 API +Eloraam - Minecraft Forge +LexManos - Minecraft Forge +Krapht - Input and generally being a great guy. +Pahimar - Input, BeeFX and see above. +Binnie - Addons, bugfixes +Mistaqur - Bugfixes, NEI plugin +Player - Input, general coding help, helping fix my EU net derps. +Maeyanie - Bukkit porting +Dariys - Testing, testing, testing and some more testing! +Direwolf20 - Mod spotlights +Stylez84 - Mod spotlight and testing +Crocodine - Flowcharts/Diagrams +Ineedabettername - Testing +Killgore - Testing +Headhunter67 - Testing +V4sh - Sprite contribution and testing +jimeowan - Original localization class \ No newline at end of file diff --git a/forestry_resources/README.txt b/forestry_resources/README.txt new file mode 100755 index 000000000..bfa57ea9a --- /dev/null +++ b/forestry_resources/README.txt @@ -0,0 +1,17 @@ + +Forestry for Minecraft +====================== + +Please refer to Forestry's thread on the Minecraft forums: +http://www.minecraftforum.net/topic/700588-181-forestry-for-minecraft/page__p__9486882 + +Forestry Wiki: +http://forestry.sengir.net/wiki/ + + +License: +---------- + +The code of "Forestry for Minecraft" in source or binary form is the intellectual property of SirSengir. +It may not be reproduced, redistributed or modified. If you have other plans, ask first. + diff --git a/forestry_resources/assets/forestry/logo.png b/forestry_resources/assets/forestry/logo.png new file mode 100755 index 000000000..bfa3bc0f8 Binary files /dev/null and b/forestry_resources/assets/forestry/logo.png differ diff --git a/forestry_resources/assets/forestry/textures/blocks/analyzer.0.png b/forestry_resources/assets/forestry/textures/blocks/analyzer.0.png new file mode 100755 index 000000000..dfa868c70 Binary files /dev/null and b/forestry_resources/assets/forestry/textures/blocks/analyzer.0.png differ diff --git a/forestry_resources/assets/forestry/textures/blocks/analyzer_pedestal.png b/forestry_resources/assets/forestry/textures/blocks/analyzer_pedestal.png new file mode 100755 index 000000000..6d9275c99 Binary files /dev/null and b/forestry_resources/assets/forestry/textures/blocks/analyzer_pedestal.png differ diff --git a/forestry_resources/assets/forestry/textures/blocks/analyzer_tower1.png b/forestry_resources/assets/forestry/textures/blocks/analyzer_tower1.png new file mode 100755 index 000000000..ff7b47319 Binary files /dev/null and b/forestry_resources/assets/forestry/textures/blocks/analyzer_tower1.png differ diff --git a/forestry_resources/assets/forestry/textures/blocks/analyzer_tower2.png b/forestry_resources/assets/forestry/textures/blocks/analyzer_tower2.png new file mode 100755 index 000000000..9b1889102 Binary files /dev/null and b/forestry_resources/assets/forestry/textures/blocks/analyzer_tower2.png differ diff --git a/forestry_resources/assets/forestry/textures/blocks/apiaristchest.0.png b/forestry_resources/assets/forestry/textures/blocks/apiaristchest.0.png new file mode 100755 index 000000000..7ff8f73b8 Binary files /dev/null and b/forestry_resources/assets/forestry/textures/blocks/apiaristchest.0.png differ diff --git a/forestry_resources/assets/forestry/textures/blocks/apiaristchest.1.png b/forestry_resources/assets/forestry/textures/blocks/apiaristchest.1.png new file mode 100755 index 000000000..dd65182e0 Binary files /dev/null and b/forestry_resources/assets/forestry/textures/blocks/apiaristchest.1.png differ diff --git a/forestry_resources/assets/forestry/textures/blocks/apiaristchest.2.png b/forestry_resources/assets/forestry/textures/blocks/apiaristchest.2.png new file mode 100755 index 000000000..0c09eb6d2 Binary files /dev/null and b/forestry_resources/assets/forestry/textures/blocks/apiaristchest.2.png differ diff --git a/forestry_resources/assets/forestry/textures/blocks/apiaristchest.3.png b/forestry_resources/assets/forestry/textures/blocks/apiaristchest.3.png new file mode 100755 index 000000000..10c084eda Binary files /dev/null and b/forestry_resources/assets/forestry/textures/blocks/apiaristchest.3.png differ diff --git a/forestry_resources/assets/forestry/textures/blocks/apiaristchest.4.png b/forestry_resources/assets/forestry/textures/blocks/apiaristchest.4.png new file mode 100755 index 000000000..0c09eb6d2 Binary files /dev/null and b/forestry_resources/assets/forestry/textures/blocks/apiaristchest.4.png differ diff --git a/forestry_resources/assets/forestry/textures/blocks/apiary.0.png b/forestry_resources/assets/forestry/textures/blocks/apiary.0.png new file mode 100755 index 000000000..9f6ddee03 Binary files /dev/null and b/forestry_resources/assets/forestry/textures/blocks/apiary.0.png differ diff --git a/forestry_resources/assets/forestry/textures/blocks/apiary.1.png b/forestry_resources/assets/forestry/textures/blocks/apiary.1.png new file mode 100755 index 000000000..5b4abd8b6 Binary files /dev/null and b/forestry_resources/assets/forestry/textures/blocks/apiary.1.png differ diff --git a/forestry_resources/assets/forestry/textures/blocks/apiary.2.png b/forestry_resources/assets/forestry/textures/blocks/apiary.2.png new file mode 100755 index 000000000..6ed67d217 Binary files /dev/null and b/forestry_resources/assets/forestry/textures/blocks/apiary.2.png differ diff --git a/forestry_resources/assets/forestry/textures/blocks/apiary.4.png b/forestry_resources/assets/forestry/textures/blocks/apiary.4.png new file mode 100755 index 000000000..c6b745165 Binary files /dev/null and b/forestry_resources/assets/forestry/textures/blocks/apiary.4.png differ diff --git a/forestry_resources/assets/forestry/textures/blocks/apiary.7.png b/forestry_resources/assets/forestry/textures/blocks/apiary.7.png new file mode 100755 index 000000000..a2f2e4fd8 Binary files /dev/null and b/forestry_resources/assets/forestry/textures/blocks/apiary.7.png differ diff --git a/forestry_resources/assets/forestry/textures/blocks/apiculture/alveary.bottom.png b/forestry_resources/assets/forestry/textures/blocks/apiculture/alveary.bottom.png new file mode 100755 index 000000000..7024ea503 Binary files /dev/null and b/forestry_resources/assets/forestry/textures/blocks/apiculture/alveary.bottom.png differ diff --git a/forestry_resources/assets/forestry/textures/blocks/apiculture/alveary.entrance.png b/forestry_resources/assets/forestry/textures/blocks/apiculture/alveary.entrance.png new file mode 100755 index 000000000..47acff73a Binary files /dev/null and b/forestry_resources/assets/forestry/textures/blocks/apiculture/alveary.entrance.png differ diff --git a/forestry_resources/assets/forestry/textures/blocks/apiculture/alveary.fan.off.png b/forestry_resources/assets/forestry/textures/blocks/apiculture/alveary.fan.off.png new file mode 100755 index 000000000..d04b490ac Binary files /dev/null and b/forestry_resources/assets/forestry/textures/blocks/apiculture/alveary.fan.off.png differ diff --git a/forestry_resources/assets/forestry/textures/blocks/apiculture/alveary.fan.on.png b/forestry_resources/assets/forestry/textures/blocks/apiculture/alveary.fan.on.png new file mode 100755 index 000000000..3a4fb5ad3 Binary files /dev/null and b/forestry_resources/assets/forestry/textures/blocks/apiculture/alveary.fan.on.png differ diff --git a/forestry_resources/assets/forestry/textures/blocks/apiculture/alveary.heater.off.png b/forestry_resources/assets/forestry/textures/blocks/apiculture/alveary.heater.off.png new file mode 100755 index 000000000..f5593b80a Binary files /dev/null and b/forestry_resources/assets/forestry/textures/blocks/apiculture/alveary.heater.off.png differ diff --git a/forestry_resources/assets/forestry/textures/blocks/apiculture/alveary.heater.on.png b/forestry_resources/assets/forestry/textures/blocks/apiculture/alveary.heater.on.png new file mode 100755 index 000000000..8c2ef1336 Binary files /dev/null and b/forestry_resources/assets/forestry/textures/blocks/apiculture/alveary.heater.on.png differ diff --git a/forestry_resources/assets/forestry/textures/blocks/apiculture/alveary.left.png b/forestry_resources/assets/forestry/textures/blocks/apiculture/alveary.left.png new file mode 100755 index 000000000..78f21b853 Binary files /dev/null and b/forestry_resources/assets/forestry/textures/blocks/apiculture/alveary.left.png differ diff --git a/forestry_resources/assets/forestry/textures/blocks/apiculture/alveary.plain.png b/forestry_resources/assets/forestry/textures/blocks/apiculture/alveary.plain.png new file mode 100755 index 000000000..e2bf2d95e Binary files /dev/null and b/forestry_resources/assets/forestry/textures/blocks/apiculture/alveary.plain.png differ diff --git a/forestry_resources/assets/forestry/textures/blocks/apiculture/alveary.right.png b/forestry_resources/assets/forestry/textures/blocks/apiculture/alveary.right.png new file mode 100755 index 000000000..b093220b8 Binary files /dev/null and b/forestry_resources/assets/forestry/textures/blocks/apiculture/alveary.right.png differ diff --git a/forestry_resources/assets/forestry/textures/blocks/apiculture/alveary.sieve.png b/forestry_resources/assets/forestry/textures/blocks/apiculture/alveary.sieve.png new file mode 100755 index 000000000..8acc72431 Binary files /dev/null and b/forestry_resources/assets/forestry/textures/blocks/apiculture/alveary.sieve.png differ diff --git a/forestry_resources/assets/forestry/textures/blocks/apiculture/alveary.stabiliser.png b/forestry_resources/assets/forestry/textures/blocks/apiculture/alveary.stabiliser.png new file mode 100755 index 000000000..9639a38c7 Binary files /dev/null and b/forestry_resources/assets/forestry/textures/blocks/apiculture/alveary.stabiliser.png differ diff --git a/forestry_resources/assets/forestry/textures/blocks/apiculture/alveary.swarmer.off.png b/forestry_resources/assets/forestry/textures/blocks/apiculture/alveary.swarmer.off.png new file mode 100755 index 000000000..997c4892b Binary files /dev/null and b/forestry_resources/assets/forestry/textures/blocks/apiculture/alveary.swarmer.off.png differ diff --git a/forestry_resources/assets/forestry/textures/blocks/apiculture/alveary.swarmer.on.png b/forestry_resources/assets/forestry/textures/blocks/apiculture/alveary.swarmer.on.png new file mode 100755 index 000000000..ad1c3d238 Binary files /dev/null and b/forestry_resources/assets/forestry/textures/blocks/apiculture/alveary.swarmer.on.png differ diff --git a/forestry_resources/assets/forestry/textures/blocks/apiculture/alveary.valve.png b/forestry_resources/assets/forestry/textures/blocks/apiculture/alveary.valve.png new file mode 100755 index 000000000..8e846646b Binary files /dev/null and b/forestry_resources/assets/forestry/textures/blocks/apiculture/alveary.valve.png differ diff --git a/forestry_resources/assets/forestry/textures/blocks/arbchest.0.png b/forestry_resources/assets/forestry/textures/blocks/arbchest.0.png new file mode 100755 index 000000000..84aa0895d Binary files /dev/null and b/forestry_resources/assets/forestry/textures/blocks/arbchest.0.png differ diff --git a/forestry_resources/assets/forestry/textures/blocks/arbchest.1.png b/forestry_resources/assets/forestry/textures/blocks/arbchest.1.png new file mode 100755 index 000000000..465ae44e5 Binary files /dev/null and b/forestry_resources/assets/forestry/textures/blocks/arbchest.1.png differ diff --git a/forestry_resources/assets/forestry/textures/blocks/arbchest.2.png b/forestry_resources/assets/forestry/textures/blocks/arbchest.2.png new file mode 100755 index 000000000..a6dd0e5c8 Binary files /dev/null and b/forestry_resources/assets/forestry/textures/blocks/arbchest.2.png differ diff --git a/forestry_resources/assets/forestry/textures/blocks/arbchest.3.png b/forestry_resources/assets/forestry/textures/blocks/arbchest.3.png new file mode 100755 index 000000000..0a62fd911 Binary files /dev/null and b/forestry_resources/assets/forestry/textures/blocks/arbchest.3.png differ diff --git a/forestry_resources/assets/forestry/textures/blocks/arbchest.4.png b/forestry_resources/assets/forestry/textures/blocks/arbchest.4.png new file mode 100755 index 000000000..b550ff38e Binary files /dev/null and b/forestry_resources/assets/forestry/textures/blocks/arbchest.4.png differ diff --git a/forestry_resources/assets/forestry/textures/blocks/arbchest.7.png b/forestry_resources/assets/forestry/textures/blocks/arbchest.7.png new file mode 100755 index 000000000..c5ca5af96 Binary files /dev/null and b/forestry_resources/assets/forestry/textures/blocks/arbchest.7.png differ diff --git a/forestry_resources/assets/forestry/textures/blocks/beehives/beehive.1.side.png b/forestry_resources/assets/forestry/textures/blocks/beehives/beehive.1.side.png new file mode 100755 index 000000000..9047af2f7 Binary files /dev/null and b/forestry_resources/assets/forestry/textures/blocks/beehives/beehive.1.side.png differ diff --git a/forestry_resources/assets/forestry/textures/blocks/beehives/beehive.1.top.png b/forestry_resources/assets/forestry/textures/blocks/beehives/beehive.1.top.png new file mode 100755 index 000000000..40f980eee Binary files /dev/null and b/forestry_resources/assets/forestry/textures/blocks/beehives/beehive.1.top.png differ diff --git a/forestry_resources/assets/forestry/textures/blocks/beehives/beehive.2.side.png b/forestry_resources/assets/forestry/textures/blocks/beehives/beehive.2.side.png new file mode 100755 index 000000000..6b7dd941d Binary files /dev/null and b/forestry_resources/assets/forestry/textures/blocks/beehives/beehive.2.side.png differ diff --git a/forestry_resources/assets/forestry/textures/blocks/beehives/beehive.2.top.png b/forestry_resources/assets/forestry/textures/blocks/beehives/beehive.2.top.png new file mode 100755 index 000000000..f68f1b09d Binary files /dev/null and b/forestry_resources/assets/forestry/textures/blocks/beehives/beehive.2.top.png differ diff --git a/forestry_resources/assets/forestry/textures/blocks/beehives/beehive.3.side.png b/forestry_resources/assets/forestry/textures/blocks/beehives/beehive.3.side.png new file mode 100755 index 000000000..61e553f31 Binary files /dev/null and b/forestry_resources/assets/forestry/textures/blocks/beehives/beehive.3.side.png differ diff --git a/forestry_resources/assets/forestry/textures/blocks/beehives/beehive.3.top.png b/forestry_resources/assets/forestry/textures/blocks/beehives/beehive.3.top.png new file mode 100755 index 000000000..4332bdf5d Binary files /dev/null and b/forestry_resources/assets/forestry/textures/blocks/beehives/beehive.3.top.png differ diff --git a/forestry_resources/assets/forestry/textures/blocks/beehives/beehive.4.side.png b/forestry_resources/assets/forestry/textures/blocks/beehives/beehive.4.side.png new file mode 100755 index 000000000..09e61670b Binary files /dev/null and b/forestry_resources/assets/forestry/textures/blocks/beehives/beehive.4.side.png differ diff --git a/forestry_resources/assets/forestry/textures/blocks/beehives/beehive.4.top.png b/forestry_resources/assets/forestry/textures/blocks/beehives/beehive.4.top.png new file mode 100755 index 000000000..23ff2412b Binary files /dev/null and b/forestry_resources/assets/forestry/textures/blocks/beehives/beehive.4.top.png differ diff --git a/forestry_resources/assets/forestry/textures/blocks/beehives/beehive.5.side.png b/forestry_resources/assets/forestry/textures/blocks/beehives/beehive.5.side.png new file mode 100755 index 000000000..e94db11ae Binary files /dev/null and b/forestry_resources/assets/forestry/textures/blocks/beehives/beehive.5.side.png differ diff --git a/forestry_resources/assets/forestry/textures/blocks/beehives/beehive.5.top.png b/forestry_resources/assets/forestry/textures/blocks/beehives/beehive.5.top.png new file mode 100755 index 000000000..b405b519d Binary files /dev/null and b/forestry_resources/assets/forestry/textures/blocks/beehives/beehive.5.top.png differ diff --git a/forestry_resources/assets/forestry/textures/blocks/beehives/beehive.6.side.png b/forestry_resources/assets/forestry/textures/blocks/beehives/beehive.6.side.png new file mode 100755 index 000000000..18a419cf0 Binary files /dev/null and b/forestry_resources/assets/forestry/textures/blocks/beehives/beehive.6.side.png differ diff --git a/forestry_resources/assets/forestry/textures/blocks/beehives/beehive.6.top.png b/forestry_resources/assets/forestry/textures/blocks/beehives/beehive.6.top.png new file mode 100755 index 000000000..8793b2c2d Binary files /dev/null and b/forestry_resources/assets/forestry/textures/blocks/beehives/beehive.6.top.png differ diff --git a/forestry_resources/assets/forestry/textures/blocks/beehives/beehive.7.side.png b/forestry_resources/assets/forestry/textures/blocks/beehives/beehive.7.side.png new file mode 100755 index 000000000..a00676ea3 Binary files /dev/null and b/forestry_resources/assets/forestry/textures/blocks/beehives/beehive.7.side.png differ diff --git a/forestry_resources/assets/forestry/textures/blocks/beehives/beehive.7.top.png b/forestry_resources/assets/forestry/textures/blocks/beehives/beehive.7.top.png new file mode 100755 index 000000000..6f11e860e Binary files /dev/null and b/forestry_resources/assets/forestry/textures/blocks/beehives/beehive.7.top.png differ diff --git a/forestry_resources/assets/forestry/textures/blocks/beehives/beehive.8.side.png b/forestry_resources/assets/forestry/textures/blocks/beehives/beehive.8.side.png new file mode 100755 index 000000000..0087491ea Binary files /dev/null and b/forestry_resources/assets/forestry/textures/blocks/beehives/beehive.8.side.png differ diff --git a/forestry_resources/assets/forestry/textures/blocks/beehives/beehive.8.top.png b/forestry_resources/assets/forestry/textures/blocks/beehives/beehive.8.top.png new file mode 100755 index 000000000..9d59aaf23 Binary files /dev/null and b/forestry_resources/assets/forestry/textures/blocks/beehives/beehive.8.top.png differ diff --git a/forestry_resources/assets/forestry/textures/blocks/beehouse.0.png b/forestry_resources/assets/forestry/textures/blocks/beehouse.0.png new file mode 100755 index 000000000..afe74e2a2 Binary files /dev/null and b/forestry_resources/assets/forestry/textures/blocks/beehouse.0.png differ diff --git a/forestry_resources/assets/forestry/textures/blocks/beehouse.1.png b/forestry_resources/assets/forestry/textures/blocks/beehouse.1.png new file mode 100755 index 000000000..786ea7953 Binary files /dev/null and b/forestry_resources/assets/forestry/textures/blocks/beehouse.1.png differ diff --git a/forestry_resources/assets/forestry/textures/blocks/beehouse.2.png b/forestry_resources/assets/forestry/textures/blocks/beehouse.2.png new file mode 100755 index 000000000..1697f41e2 Binary files /dev/null and b/forestry_resources/assets/forestry/textures/blocks/beehouse.2.png differ diff --git a/forestry_resources/assets/forestry/textures/blocks/beehouse.4.png b/forestry_resources/assets/forestry/textures/blocks/beehouse.4.png new file mode 100755 index 000000000..fd1c95078 Binary files /dev/null and b/forestry_resources/assets/forestry/textures/blocks/beehouse.4.png differ diff --git a/forestry_resources/assets/forestry/textures/blocks/beehouse.7.png b/forestry_resources/assets/forestry/textures/blocks/beehouse.7.png new file mode 100755 index 000000000..812f28e5e Binary files /dev/null and b/forestry_resources/assets/forestry/textures/blocks/beehouse.7.png differ diff --git a/forestry_resources/assets/forestry/textures/blocks/block_0_14.png b/forestry_resources/assets/forestry/textures/blocks/block_0_14.png new file mode 100755 index 000000000..ec9925813 Binary files /dev/null and b/forestry_resources/assets/forestry/textures/blocks/block_0_14.png differ diff --git a/forestry_resources/assets/forestry/textures/blocks/block_12_13.png b/forestry_resources/assets/forestry/textures/blocks/block_12_13.png new file mode 100755 index 000000000..11f0404fc Binary files /dev/null and b/forestry_resources/assets/forestry/textures/blocks/block_12_13.png differ diff --git a/forestry_resources/assets/forestry/textures/blocks/block_12_14.png b/forestry_resources/assets/forestry/textures/blocks/block_12_14.png new file mode 100755 index 000000000..1f9c3ae8b Binary files /dev/null and b/forestry_resources/assets/forestry/textures/blocks/block_12_14.png differ diff --git a/forestry_resources/assets/forestry/textures/blocks/block_12_15.png b/forestry_resources/assets/forestry/textures/blocks/block_12_15.png new file mode 100755 index 000000000..f48cee61b Binary files /dev/null and b/forestry_resources/assets/forestry/textures/blocks/block_12_15.png differ diff --git a/forestry_resources/assets/forestry/textures/blocks/block_13_14.png b/forestry_resources/assets/forestry/textures/blocks/block_13_14.png new file mode 100755 index 000000000..fdef61078 Binary files /dev/null and b/forestry_resources/assets/forestry/textures/blocks/block_13_14.png differ diff --git a/forestry_resources/assets/forestry/textures/blocks/block_13_15.png b/forestry_resources/assets/forestry/textures/blocks/block_13_15.png new file mode 100755 index 000000000..ff7dc937a Binary files /dev/null and b/forestry_resources/assets/forestry/textures/blocks/block_13_15.png differ diff --git a/forestry_resources/assets/forestry/textures/blocks/bottler.0.png b/forestry_resources/assets/forestry/textures/blocks/bottler.0.png new file mode 100755 index 000000000..37fb005d4 Binary files /dev/null and b/forestry_resources/assets/forestry/textures/blocks/bottler.0.png differ diff --git a/forestry_resources/assets/forestry/textures/blocks/bottler_base.png b/forestry_resources/assets/forestry/textures/blocks/bottler_base.png new file mode 100755 index 000000000..0bc23c6f6 Binary files /dev/null and b/forestry_resources/assets/forestry/textures/blocks/bottler_base.png differ diff --git a/forestry_resources/assets/forestry/textures/blocks/bottler_tank_product_empty.png b/forestry_resources/assets/forestry/textures/blocks/bottler_tank_product_empty.png new file mode 100755 index 000000000..1b4c2115b Binary files /dev/null and b/forestry_resources/assets/forestry/textures/blocks/bottler_tank_product_empty.png differ diff --git a/forestry_resources/assets/forestry/textures/blocks/bottler_tank_resource_empty.png b/forestry_resources/assets/forestry/textures/blocks/bottler_tank_resource_empty.png new file mode 100755 index 000000000..1e05ea274 Binary files /dev/null and b/forestry_resources/assets/forestry/textures/blocks/bottler_tank_resource_empty.png differ diff --git a/forestry_resources/assets/forestry/textures/blocks/bottler_tank_resource_high.png b/forestry_resources/assets/forestry/textures/blocks/bottler_tank_resource_high.png new file mode 100755 index 000000000..7b1786d2a Binary files /dev/null and b/forestry_resources/assets/forestry/textures/blocks/bottler_tank_resource_high.png differ diff --git a/forestry_resources/assets/forestry/textures/blocks/bottler_tank_resource_low.png b/forestry_resources/assets/forestry/textures/blocks/bottler_tank_resource_low.png new file mode 100755 index 000000000..0b197f8b8 Binary files /dev/null and b/forestry_resources/assets/forestry/textures/blocks/bottler_tank_resource_low.png differ diff --git a/forestry_resources/assets/forestry/textures/blocks/bottler_tank_resource_maximum.png b/forestry_resources/assets/forestry/textures/blocks/bottler_tank_resource_maximum.png new file mode 100755 index 000000000..5c275726c Binary files /dev/null and b/forestry_resources/assets/forestry/textures/blocks/bottler_tank_resource_maximum.png differ diff --git a/forestry_resources/assets/forestry/textures/blocks/bottler_tank_resource_medium.png b/forestry_resources/assets/forestry/textures/blocks/bottler_tank_resource_medium.png new file mode 100755 index 000000000..077637b84 Binary files /dev/null and b/forestry_resources/assets/forestry/textures/blocks/bottler_tank_resource_medium.png differ diff --git a/forestry_resources/assets/forestry/textures/blocks/candle.png b/forestry_resources/assets/forestry/textures/blocks/candle.png new file mode 100755 index 000000000..07caf0d1d Binary files /dev/null and b/forestry_resources/assets/forestry/textures/blocks/candle.png differ diff --git a/forestry_resources/assets/forestry/textures/blocks/candleStumpLit.png b/forestry_resources/assets/forestry/textures/blocks/candleStumpLit.png new file mode 100755 index 000000000..2bda96cab Binary files /dev/null and b/forestry_resources/assets/forestry/textures/blocks/candleStumpLit.png differ diff --git a/forestry_resources/assets/forestry/textures/blocks/candleStumpUnlit.png b/forestry_resources/assets/forestry/textures/blocks/candleStumpUnlit.png new file mode 100755 index 000000000..4fe3fe878 Binary files /dev/null and b/forestry_resources/assets/forestry/textures/blocks/candleStumpUnlit.png differ diff --git a/forestry_resources/assets/forestry/textures/blocks/candleTipLit.png b/forestry_resources/assets/forestry/textures/blocks/candleTipLit.png new file mode 100755 index 000000000..28eaff89c Binary files /dev/null and b/forestry_resources/assets/forestry/textures/blocks/candleTipLit.png differ diff --git a/forestry_resources/assets/forestry/textures/blocks/candleTipUnlit.png b/forestry_resources/assets/forestry/textures/blocks/candleTipUnlit.png new file mode 100755 index 000000000..621afb16d Binary files /dev/null and b/forestry_resources/assets/forestry/textures/blocks/candleTipUnlit.png differ diff --git a/forestry_resources/assets/forestry/textures/blocks/carpenter.0.png b/forestry_resources/assets/forestry/textures/blocks/carpenter.0.png new file mode 100755 index 000000000..752838a0a Binary files /dev/null and b/forestry_resources/assets/forestry/textures/blocks/carpenter.0.png differ diff --git a/forestry_resources/assets/forestry/textures/blocks/carpenter_base.png b/forestry_resources/assets/forestry/textures/blocks/carpenter_base.png new file mode 100755 index 000000000..2781d5a4f Binary files /dev/null and b/forestry_resources/assets/forestry/textures/blocks/carpenter_base.png differ diff --git a/forestry_resources/assets/forestry/textures/blocks/carpenter_tank_product_empty.png b/forestry_resources/assets/forestry/textures/blocks/carpenter_tank_product_empty.png new file mode 100755 index 000000000..ae3b97f8d Binary files /dev/null and b/forestry_resources/assets/forestry/textures/blocks/carpenter_tank_product_empty.png differ diff --git a/forestry_resources/assets/forestry/textures/blocks/carpenter_tank_resource_empty.png b/forestry_resources/assets/forestry/textures/blocks/carpenter_tank_resource_empty.png new file mode 100755 index 000000000..bb05307e2 Binary files /dev/null and b/forestry_resources/assets/forestry/textures/blocks/carpenter_tank_resource_empty.png differ diff --git a/forestry_resources/assets/forestry/textures/blocks/carpenter_tank_resource_high.png b/forestry_resources/assets/forestry/textures/blocks/carpenter_tank_resource_high.png new file mode 100755 index 000000000..f03465092 Binary files /dev/null and b/forestry_resources/assets/forestry/textures/blocks/carpenter_tank_resource_high.png differ diff --git a/forestry_resources/assets/forestry/textures/blocks/carpenter_tank_resource_low.png b/forestry_resources/assets/forestry/textures/blocks/carpenter_tank_resource_low.png new file mode 100755 index 000000000..2570afe57 Binary files /dev/null and b/forestry_resources/assets/forestry/textures/blocks/carpenter_tank_resource_low.png differ diff --git a/forestry_resources/assets/forestry/textures/blocks/carpenter_tank_resource_maximum.png b/forestry_resources/assets/forestry/textures/blocks/carpenter_tank_resource_maximum.png new file mode 100755 index 000000000..7e3e8bbb2 Binary files /dev/null and b/forestry_resources/assets/forestry/textures/blocks/carpenter_tank_resource_maximum.png differ diff --git a/forestry_resources/assets/forestry/textures/blocks/carpenter_tank_resource_medium.png b/forestry_resources/assets/forestry/textures/blocks/carpenter_tank_resource_medium.png new file mode 100755 index 000000000..d7452191e Binary files /dev/null and b/forestry_resources/assets/forestry/textures/blocks/carpenter_tank_resource_medium.png differ diff --git a/forestry_resources/assets/forestry/textures/blocks/centrifuge.0.png b/forestry_resources/assets/forestry/textures/blocks/centrifuge.0.png new file mode 100755 index 000000000..681473c3e Binary files /dev/null and b/forestry_resources/assets/forestry/textures/blocks/centrifuge.0.png differ diff --git a/forestry_resources/assets/forestry/textures/blocks/centrifuge_base.png b/forestry_resources/assets/forestry/textures/blocks/centrifuge_base.png new file mode 100755 index 000000000..f11c55b94 Binary files /dev/null and b/forestry_resources/assets/forestry/textures/blocks/centrifuge_base.png differ diff --git a/forestry_resources/assets/forestry/textures/blocks/centrifuge_tank_product_empty.png b/forestry_resources/assets/forestry/textures/blocks/centrifuge_tank_product_empty.png new file mode 100755 index 000000000..4e84e5006 Binary files /dev/null and b/forestry_resources/assets/forestry/textures/blocks/centrifuge_tank_product_empty.png differ diff --git a/forestry_resources/assets/forestry/textures/blocks/centrifuge_tank_resource_empty.png b/forestry_resources/assets/forestry/textures/blocks/centrifuge_tank_resource_empty.png new file mode 100755 index 000000000..5568a6b74 Binary files /dev/null and b/forestry_resources/assets/forestry/textures/blocks/centrifuge_tank_resource_empty.png differ diff --git a/forestry_resources/assets/forestry/textures/blocks/engine_bronze_base.png b/forestry_resources/assets/forestry/textures/blocks/engine_bronze_base.png new file mode 100755 index 000000000..b96bb0999 Binary files /dev/null and b/forestry_resources/assets/forestry/textures/blocks/engine_bronze_base.png differ diff --git a/forestry_resources/assets/forestry/textures/blocks/engine_bronze_extension.png b/forestry_resources/assets/forestry/textures/blocks/engine_bronze_extension.png new file mode 100755 index 000000000..23ba13338 Binary files /dev/null and b/forestry_resources/assets/forestry/textures/blocks/engine_bronze_extension.png differ diff --git a/forestry_resources/assets/forestry/textures/blocks/engine_bronze_piston.png b/forestry_resources/assets/forestry/textures/blocks/engine_bronze_piston.png new file mode 100755 index 000000000..470b0394f Binary files /dev/null and b/forestry_resources/assets/forestry/textures/blocks/engine_bronze_piston.png differ diff --git a/forestry_resources/assets/forestry/textures/blocks/engine_clock_base.png b/forestry_resources/assets/forestry/textures/blocks/engine_clock_base.png new file mode 100755 index 000000000..7e9173388 Binary files /dev/null and b/forestry_resources/assets/forestry/textures/blocks/engine_clock_base.png differ diff --git a/forestry_resources/assets/forestry/textures/blocks/engine_clock_extension.png b/forestry_resources/assets/forestry/textures/blocks/engine_clock_extension.png new file mode 100755 index 000000000..8e40f7aef Binary files /dev/null and b/forestry_resources/assets/forestry/textures/blocks/engine_clock_extension.png differ diff --git a/forestry_resources/assets/forestry/textures/blocks/engine_clock_piston.png b/forestry_resources/assets/forestry/textures/blocks/engine_clock_piston.png new file mode 100755 index 000000000..06f368e7d Binary files /dev/null and b/forestry_resources/assets/forestry/textures/blocks/engine_clock_piston.png differ diff --git a/forestry_resources/assets/forestry/textures/blocks/engine_copper_base.png b/forestry_resources/assets/forestry/textures/blocks/engine_copper_base.png new file mode 100755 index 000000000..b26eadc44 Binary files /dev/null and b/forestry_resources/assets/forestry/textures/blocks/engine_copper_base.png differ diff --git a/forestry_resources/assets/forestry/textures/blocks/engine_copper_extension.png b/forestry_resources/assets/forestry/textures/blocks/engine_copper_extension.png new file mode 100755 index 000000000..ad553062c Binary files /dev/null and b/forestry_resources/assets/forestry/textures/blocks/engine_copper_extension.png differ diff --git a/forestry_resources/assets/forestry/textures/blocks/engine_copper_piston.png b/forestry_resources/assets/forestry/textures/blocks/engine_copper_piston.png new file mode 100755 index 000000000..ab38a6e5a Binary files /dev/null and b/forestry_resources/assets/forestry/textures/blocks/engine_copper_piston.png differ diff --git a/forestry_resources/assets/forestry/textures/blocks/engine_tin_base.png b/forestry_resources/assets/forestry/textures/blocks/engine_tin_base.png new file mode 100755 index 000000000..8d29a5370 Binary files /dev/null and b/forestry_resources/assets/forestry/textures/blocks/engine_tin_base.png differ diff --git a/forestry_resources/assets/forestry/textures/blocks/engine_tin_extension.png b/forestry_resources/assets/forestry/textures/blocks/engine_tin_extension.png new file mode 100755 index 000000000..aa8f53b08 Binary files /dev/null and b/forestry_resources/assets/forestry/textures/blocks/engine_tin_extension.png differ diff --git a/forestry_resources/assets/forestry/textures/blocks/engine_tin_piston.png b/forestry_resources/assets/forestry/textures/blocks/engine_tin_piston.png new file mode 100755 index 000000000..88d381355 Binary files /dev/null and b/forestry_resources/assets/forestry/textures/blocks/engine_tin_piston.png differ diff --git a/forestry_resources/assets/forestry/textures/blocks/engine_trunk_high.png b/forestry_resources/assets/forestry/textures/blocks/engine_trunk_high.png new file mode 100755 index 000000000..848b7a783 Binary files /dev/null and b/forestry_resources/assets/forestry/textures/blocks/engine_trunk_high.png differ diff --git a/forestry_resources/assets/forestry/textures/blocks/engine_trunk_higher.png b/forestry_resources/assets/forestry/textures/blocks/engine_trunk_higher.png new file mode 100755 index 000000000..9af6e8446 Binary files /dev/null and b/forestry_resources/assets/forestry/textures/blocks/engine_trunk_higher.png differ diff --git a/forestry_resources/assets/forestry/textures/blocks/engine_trunk_highest.png b/forestry_resources/assets/forestry/textures/blocks/engine_trunk_highest.png new file mode 100755 index 000000000..b80063ddf Binary files /dev/null and b/forestry_resources/assets/forestry/textures/blocks/engine_trunk_highest.png differ diff --git a/forestry_resources/assets/forestry/textures/blocks/engine_trunk_low.png b/forestry_resources/assets/forestry/textures/blocks/engine_trunk_low.png new file mode 100755 index 000000000..d0f19e652 Binary files /dev/null and b/forestry_resources/assets/forestry/textures/blocks/engine_trunk_low.png differ diff --git a/forestry_resources/assets/forestry/textures/blocks/engine_trunk_medium.png b/forestry_resources/assets/forestry/textures/blocks/engine_trunk_medium.png new file mode 100755 index 000000000..c9f170024 Binary files /dev/null and b/forestry_resources/assets/forestry/textures/blocks/engine_trunk_medium.png differ diff --git a/forestry_resources/assets/forestry/textures/blocks/enginebronze.0.png b/forestry_resources/assets/forestry/textures/blocks/enginebronze.0.png new file mode 100755 index 000000000..752838a0a Binary files /dev/null and b/forestry_resources/assets/forestry/textures/blocks/enginebronze.0.png differ diff --git a/forestry_resources/assets/forestry/textures/blocks/engineclockwork.0.png b/forestry_resources/assets/forestry/textures/blocks/engineclockwork.0.png new file mode 100755 index 000000000..6db55645d Binary files /dev/null and b/forestry_resources/assets/forestry/textures/blocks/engineclockwork.0.png differ diff --git a/forestry_resources/assets/forestry/textures/blocks/enginecopper.0.png b/forestry_resources/assets/forestry/textures/blocks/enginecopper.0.png new file mode 100755 index 000000000..a99fa4b58 Binary files /dev/null and b/forestry_resources/assets/forestry/textures/blocks/enginecopper.0.png differ diff --git a/forestry_resources/assets/forestry/textures/blocks/enginetin.0.png b/forestry_resources/assets/forestry/textures/blocks/enginetin.0.png new file mode 100755 index 000000000..dfa868c70 Binary files /dev/null and b/forestry_resources/assets/forestry/textures/blocks/enginetin.0.png differ diff --git a/forestry_resources/assets/forestry/textures/blocks/escritoire.0.png b/forestry_resources/assets/forestry/textures/blocks/escritoire.0.png new file mode 100755 index 000000000..b98a16547 Binary files /dev/null and b/forestry_resources/assets/forestry/textures/blocks/escritoire.0.png differ diff --git a/forestry_resources/assets/forestry/textures/blocks/escritoire.png b/forestry_resources/assets/forestry/textures/blocks/escritoire.png new file mode 100755 index 000000000..a16f6c97e Binary files /dev/null and b/forestry_resources/assets/forestry/textures/blocks/escritoire.png differ diff --git a/forestry_resources/assets/forestry/textures/blocks/fabricator.0.png b/forestry_resources/assets/forestry/textures/blocks/fabricator.0.png new file mode 100755 index 000000000..dfa868c70 Binary files /dev/null and b/forestry_resources/assets/forestry/textures/blocks/fabricator.0.png differ diff --git a/forestry_resources/assets/forestry/textures/blocks/fabricator.1.png b/forestry_resources/assets/forestry/textures/blocks/fabricator.1.png new file mode 100755 index 000000000..c993c11db Binary files /dev/null and b/forestry_resources/assets/forestry/textures/blocks/fabricator.1.png differ diff --git a/forestry_resources/assets/forestry/textures/blocks/fabricator.2.png b/forestry_resources/assets/forestry/textures/blocks/fabricator.2.png new file mode 100755 index 000000000..22202cfd0 Binary files /dev/null and b/forestry_resources/assets/forestry/textures/blocks/fabricator.2.png differ diff --git a/forestry_resources/assets/forestry/textures/blocks/fabricator.3.png b/forestry_resources/assets/forestry/textures/blocks/fabricator.3.png new file mode 100755 index 000000000..d5f132a06 Binary files /dev/null and b/forestry_resources/assets/forestry/textures/blocks/fabricator.3.png differ diff --git a/forestry_resources/assets/forestry/textures/blocks/fabricator.4.png b/forestry_resources/assets/forestry/textures/blocks/fabricator.4.png new file mode 100755 index 000000000..15714c83c Binary files /dev/null and b/forestry_resources/assets/forestry/textures/blocks/fabricator.4.png differ diff --git a/forestry_resources/assets/forestry/textures/blocks/farm/band.png b/forestry_resources/assets/forestry/textures/blocks/farm/band.png new file mode 100755 index 000000000..4247e1a05 Binary files /dev/null and b/forestry_resources/assets/forestry/textures/blocks/farm/band.png differ diff --git a/forestry_resources/assets/forestry/textures/blocks/farm/control.png b/forestry_resources/assets/forestry/textures/blocks/farm/control.png new file mode 100755 index 000000000..0751bccfa Binary files /dev/null and b/forestry_resources/assets/forestry/textures/blocks/farm/control.png differ diff --git a/forestry_resources/assets/forestry/textures/blocks/farm/gears.png b/forestry_resources/assets/forestry/textures/blocks/farm/gears.png new file mode 100755 index 000000000..6b4e15cb8 Binary files /dev/null and b/forestry_resources/assets/forestry/textures/blocks/farm/gears.png differ diff --git a/forestry_resources/assets/forestry/textures/blocks/farm/hatch.png b/forestry_resources/assets/forestry/textures/blocks/farm/hatch.png new file mode 100755 index 000000000..0613b5d6d Binary files /dev/null and b/forestry_resources/assets/forestry/textures/blocks/farm/hatch.png differ diff --git a/forestry_resources/assets/forestry/textures/blocks/farm/plain.png b/forestry_resources/assets/forestry/textures/blocks/farm/plain.png new file mode 100755 index 000000000..1ea526f79 Binary files /dev/null and b/forestry_resources/assets/forestry/textures/blocks/farm/plain.png differ diff --git a/forestry_resources/assets/forestry/textures/blocks/farm/reverse.png b/forestry_resources/assets/forestry/textures/blocks/farm/reverse.png new file mode 100755 index 000000000..08ec6e028 Binary files /dev/null and b/forestry_resources/assets/forestry/textures/blocks/farm/reverse.png differ diff --git a/forestry_resources/assets/forestry/textures/blocks/farm/top.png b/forestry_resources/assets/forestry/textures/blocks/farm/top.png new file mode 100755 index 000000000..8714519f9 Binary files /dev/null and b/forestry_resources/assets/forestry/textures/blocks/farm/top.png differ diff --git a/forestry_resources/assets/forestry/textures/blocks/farm/valve.png b/forestry_resources/assets/forestry/textures/blocks/farm/valve.png new file mode 100755 index 000000000..c5fbe90be Binary files /dev/null and b/forestry_resources/assets/forestry/textures/blocks/farm/valve.png differ diff --git a/forestry_resources/assets/forestry/textures/blocks/fermenter.0.png b/forestry_resources/assets/forestry/textures/blocks/fermenter.0.png new file mode 100755 index 000000000..abe46e768 Binary files /dev/null and b/forestry_resources/assets/forestry/textures/blocks/fermenter.0.png differ diff --git a/forestry_resources/assets/forestry/textures/blocks/fermenter_base.png b/forestry_resources/assets/forestry/textures/blocks/fermenter_base.png new file mode 100755 index 000000000..18247c7ac Binary files /dev/null and b/forestry_resources/assets/forestry/textures/blocks/fermenter_base.png differ diff --git a/forestry_resources/assets/forestry/textures/blocks/fermenter_tank_product_empty.png b/forestry_resources/assets/forestry/textures/blocks/fermenter_tank_product_empty.png new file mode 100755 index 000000000..bb05307e2 Binary files /dev/null and b/forestry_resources/assets/forestry/textures/blocks/fermenter_tank_product_empty.png differ diff --git a/forestry_resources/assets/forestry/textures/blocks/fermenter_tank_product_high.png b/forestry_resources/assets/forestry/textures/blocks/fermenter_tank_product_high.png new file mode 100755 index 000000000..3a23d9765 Binary files /dev/null and b/forestry_resources/assets/forestry/textures/blocks/fermenter_tank_product_high.png differ diff --git a/forestry_resources/assets/forestry/textures/blocks/fermenter_tank_product_low.png b/forestry_resources/assets/forestry/textures/blocks/fermenter_tank_product_low.png new file mode 100755 index 000000000..f711a8d79 Binary files /dev/null and b/forestry_resources/assets/forestry/textures/blocks/fermenter_tank_product_low.png differ diff --git a/forestry_resources/assets/forestry/textures/blocks/fermenter_tank_product_maximum.png b/forestry_resources/assets/forestry/textures/blocks/fermenter_tank_product_maximum.png new file mode 100755 index 000000000..0657019c8 Binary files /dev/null and b/forestry_resources/assets/forestry/textures/blocks/fermenter_tank_product_maximum.png differ diff --git a/forestry_resources/assets/forestry/textures/blocks/fermenter_tank_product_medium.png b/forestry_resources/assets/forestry/textures/blocks/fermenter_tank_product_medium.png new file mode 100755 index 000000000..def3b4bf9 Binary files /dev/null and b/forestry_resources/assets/forestry/textures/blocks/fermenter_tank_product_medium.png differ diff --git a/forestry_resources/assets/forestry/textures/blocks/fermenter_tank_resource_empty.png b/forestry_resources/assets/forestry/textures/blocks/fermenter_tank_resource_empty.png new file mode 100755 index 000000000..bb05307e2 Binary files /dev/null and b/forestry_resources/assets/forestry/textures/blocks/fermenter_tank_resource_empty.png differ diff --git a/forestry_resources/assets/forestry/textures/blocks/fermenter_tank_resource_high.png b/forestry_resources/assets/forestry/textures/blocks/fermenter_tank_resource_high.png new file mode 100755 index 000000000..f03465092 Binary files /dev/null and b/forestry_resources/assets/forestry/textures/blocks/fermenter_tank_resource_high.png differ diff --git a/forestry_resources/assets/forestry/textures/blocks/fermenter_tank_resource_low.png b/forestry_resources/assets/forestry/textures/blocks/fermenter_tank_resource_low.png new file mode 100755 index 000000000..2570afe57 Binary files /dev/null and b/forestry_resources/assets/forestry/textures/blocks/fermenter_tank_resource_low.png differ diff --git a/forestry_resources/assets/forestry/textures/blocks/fermenter_tank_resource_maximum.png b/forestry_resources/assets/forestry/textures/blocks/fermenter_tank_resource_maximum.png new file mode 100755 index 000000000..7e3e8bbb2 Binary files /dev/null and b/forestry_resources/assets/forestry/textures/blocks/fermenter_tank_resource_maximum.png differ diff --git a/forestry_resources/assets/forestry/textures/blocks/fermenter_tank_resource_medium.png b/forestry_resources/assets/forestry/textures/blocks/fermenter_tank_resource_medium.png new file mode 100755 index 000000000..d7452191e Binary files /dev/null and b/forestry_resources/assets/forestry/textures/blocks/fermenter_tank_resource_medium.png differ diff --git a/forestry_resources/assets/forestry/textures/blocks/generator.0.png b/forestry_resources/assets/forestry/textures/blocks/generator.0.png new file mode 100755 index 000000000..dfa868c70 Binary files /dev/null and b/forestry_resources/assets/forestry/textures/blocks/generator.0.png differ diff --git a/forestry_resources/assets/forestry/textures/blocks/generator_base.png b/forestry_resources/assets/forestry/textures/blocks/generator_base.png new file mode 100755 index 000000000..3c80f3d54 Binary files /dev/null and b/forestry_resources/assets/forestry/textures/blocks/generator_base.png differ diff --git a/forestry_resources/assets/forestry/textures/blocks/generator_tank_product_empty.png b/forestry_resources/assets/forestry/textures/blocks/generator_tank_product_empty.png new file mode 100755 index 000000000..753eaf246 Binary files /dev/null and b/forestry_resources/assets/forestry/textures/blocks/generator_tank_product_empty.png differ diff --git a/forestry_resources/assets/forestry/textures/blocks/generator_tank_resource_empty.png b/forestry_resources/assets/forestry/textures/blocks/generator_tank_resource_empty.png new file mode 100755 index 000000000..953708f34 Binary files /dev/null and b/forestry_resources/assets/forestry/textures/blocks/generator_tank_resource_empty.png differ diff --git a/forestry_resources/assets/forestry/textures/blocks/generator_tank_resource_high.png b/forestry_resources/assets/forestry/textures/blocks/generator_tank_resource_high.png new file mode 100755 index 000000000..9c86c0edd Binary files /dev/null and b/forestry_resources/assets/forestry/textures/blocks/generator_tank_resource_high.png differ diff --git a/forestry_resources/assets/forestry/textures/blocks/generator_tank_resource_low.png b/forestry_resources/assets/forestry/textures/blocks/generator_tank_resource_low.png new file mode 100755 index 000000000..b76fba48d Binary files /dev/null and b/forestry_resources/assets/forestry/textures/blocks/generator_tank_resource_low.png differ diff --git a/forestry_resources/assets/forestry/textures/blocks/generator_tank_resource_maximum.png b/forestry_resources/assets/forestry/textures/blocks/generator_tank_resource_maximum.png new file mode 100755 index 000000000..4693dd6cd Binary files /dev/null and b/forestry_resources/assets/forestry/textures/blocks/generator_tank_resource_maximum.png differ diff --git a/forestry_resources/assets/forestry/textures/blocks/generator_tank_resource_medium.png b/forestry_resources/assets/forestry/textures/blocks/generator_tank_resource_medium.png new file mode 100755 index 000000000..255bc1f9c Binary files /dev/null and b/forestry_resources/assets/forestry/textures/blocks/generator_tank_resource_medium.png differ diff --git a/forestry_resources/assets/forestry/textures/blocks/germlings/sapling.treeAcacia.png b/forestry_resources/assets/forestry/textures/blocks/germlings/sapling.treeAcacia.png new file mode 100755 index 000000000..521999644 Binary files /dev/null and b/forestry_resources/assets/forestry/textures/blocks/germlings/sapling.treeAcacia.png differ diff --git a/forestry_resources/assets/forestry/textures/blocks/germlings/sapling.treeBalsa.png b/forestry_resources/assets/forestry/textures/blocks/germlings/sapling.treeBalsa.png new file mode 100755 index 000000000..17e102b91 Binary files /dev/null and b/forestry_resources/assets/forestry/textures/blocks/germlings/sapling.treeBalsa.png differ diff --git a/forestry_resources/assets/forestry/textures/blocks/germlings/sapling.treeBaobab.png b/forestry_resources/assets/forestry/textures/blocks/germlings/sapling.treeBaobab.png new file mode 100755 index 000000000..8b1bd62b7 Binary files /dev/null and b/forestry_resources/assets/forestry/textures/blocks/germlings/sapling.treeBaobab.png differ diff --git a/forestry_resources/assets/forestry/textures/blocks/germlings/sapling.treeCherry.png b/forestry_resources/assets/forestry/textures/blocks/germlings/sapling.treeCherry.png new file mode 100755 index 000000000..2fb5166bd Binary files /dev/null and b/forestry_resources/assets/forestry/textures/blocks/germlings/sapling.treeCherry.png differ diff --git a/forestry_resources/assets/forestry/textures/blocks/germlings/sapling.treeChestnut.png b/forestry_resources/assets/forestry/textures/blocks/germlings/sapling.treeChestnut.png new file mode 100755 index 000000000..5dcb61562 Binary files /dev/null and b/forestry_resources/assets/forestry/textures/blocks/germlings/sapling.treeChestnut.png differ diff --git a/forestry_resources/assets/forestry/textures/blocks/germlings/sapling.treeDate.png b/forestry_resources/assets/forestry/textures/blocks/germlings/sapling.treeDate.png new file mode 100755 index 000000000..e1471a6dd Binary files /dev/null and b/forestry_resources/assets/forestry/textures/blocks/germlings/sapling.treeDate.png differ diff --git a/forestry_resources/assets/forestry/textures/blocks/germlings/sapling.treeEbony.png b/forestry_resources/assets/forestry/textures/blocks/germlings/sapling.treeEbony.png new file mode 100755 index 000000000..5abe90c29 Binary files /dev/null and b/forestry_resources/assets/forestry/textures/blocks/germlings/sapling.treeEbony.png differ diff --git a/forestry_resources/assets/forestry/textures/blocks/germlings/sapling.treeGigant.png b/forestry_resources/assets/forestry/textures/blocks/germlings/sapling.treeGigant.png new file mode 100755 index 000000000..403a85b62 Binary files /dev/null and b/forestry_resources/assets/forestry/textures/blocks/germlings/sapling.treeGigant.png differ diff --git a/forestry_resources/assets/forestry/textures/blocks/germlings/sapling.treeKapok.png b/forestry_resources/assets/forestry/textures/blocks/germlings/sapling.treeKapok.png new file mode 100755 index 000000000..1f25f9b41 Binary files /dev/null and b/forestry_resources/assets/forestry/textures/blocks/germlings/sapling.treeKapok.png differ diff --git a/forestry_resources/assets/forestry/textures/blocks/germlings/sapling.treeLarch.png b/forestry_resources/assets/forestry/textures/blocks/germlings/sapling.treeLarch.png new file mode 100755 index 000000000..6ff0f57e0 Binary files /dev/null and b/forestry_resources/assets/forestry/textures/blocks/germlings/sapling.treeLarch.png differ diff --git a/forestry_resources/assets/forestry/textures/blocks/germlings/sapling.treeLemon.png b/forestry_resources/assets/forestry/textures/blocks/germlings/sapling.treeLemon.png new file mode 100755 index 000000000..bc9bdb8f2 Binary files /dev/null and b/forestry_resources/assets/forestry/textures/blocks/germlings/sapling.treeLemon.png differ diff --git a/forestry_resources/assets/forestry/textures/blocks/germlings/sapling.treeLime.png b/forestry_resources/assets/forestry/textures/blocks/germlings/sapling.treeLime.png new file mode 100755 index 000000000..f727cc0d3 Binary files /dev/null and b/forestry_resources/assets/forestry/textures/blocks/germlings/sapling.treeLime.png differ diff --git a/forestry_resources/assets/forestry/textures/blocks/germlings/sapling.treeMahoe.png b/forestry_resources/assets/forestry/textures/blocks/germlings/sapling.treeMahoe.png new file mode 100755 index 000000000..e39fe638d Binary files /dev/null and b/forestry_resources/assets/forestry/textures/blocks/germlings/sapling.treeMahoe.png differ diff --git a/forestry_resources/assets/forestry/textures/blocks/germlings/sapling.treeMahogony.png b/forestry_resources/assets/forestry/textures/blocks/germlings/sapling.treeMahogony.png new file mode 100755 index 000000000..68f207b11 Binary files /dev/null and b/forestry_resources/assets/forestry/textures/blocks/germlings/sapling.treeMahogony.png differ diff --git a/forestry_resources/assets/forestry/textures/blocks/germlings/sapling.treeMaple.png b/forestry_resources/assets/forestry/textures/blocks/germlings/sapling.treeMaple.png new file mode 100755 index 000000000..a021476ca Binary files /dev/null and b/forestry_resources/assets/forestry/textures/blocks/germlings/sapling.treeMaple.png differ diff --git a/forestry_resources/assets/forestry/textures/blocks/germlings/sapling.treePapaya.png b/forestry_resources/assets/forestry/textures/blocks/germlings/sapling.treePapaya.png new file mode 100755 index 000000000..8c14f02d4 Binary files /dev/null and b/forestry_resources/assets/forestry/textures/blocks/germlings/sapling.treePapaya.png differ diff --git a/forestry_resources/assets/forestry/textures/blocks/germlings/sapling.treePine.png b/forestry_resources/assets/forestry/textures/blocks/germlings/sapling.treePine.png new file mode 100755 index 000000000..e9f6177de Binary files /dev/null and b/forestry_resources/assets/forestry/textures/blocks/germlings/sapling.treePine.png differ diff --git a/forestry_resources/assets/forestry/textures/blocks/germlings/sapling.treePlum.png b/forestry_resources/assets/forestry/textures/blocks/germlings/sapling.treePlum.png new file mode 100755 index 000000000..22e4be359 Binary files /dev/null and b/forestry_resources/assets/forestry/textures/blocks/germlings/sapling.treePlum.png differ diff --git a/forestry_resources/assets/forestry/textures/blocks/germlings/sapling.treePoplar.png b/forestry_resources/assets/forestry/textures/blocks/germlings/sapling.treePoplar.png new file mode 100755 index 000000000..8f4a62ddb Binary files /dev/null and b/forestry_resources/assets/forestry/textures/blocks/germlings/sapling.treePoplar.png differ diff --git a/forestry_resources/assets/forestry/textures/blocks/germlings/sapling.treeRubber.png b/forestry_resources/assets/forestry/textures/blocks/germlings/sapling.treeRubber.png new file mode 100755 index 000000000..09f7bf036 Binary files /dev/null and b/forestry_resources/assets/forestry/textures/blocks/germlings/sapling.treeRubber.png differ diff --git a/forestry_resources/assets/forestry/textures/blocks/germlings/sapling.treeSequioa.png b/forestry_resources/assets/forestry/textures/blocks/germlings/sapling.treeSequioa.png new file mode 100755 index 000000000..9254883e4 Binary files /dev/null and b/forestry_resources/assets/forestry/textures/blocks/germlings/sapling.treeSequioa.png differ diff --git a/forestry_resources/assets/forestry/textures/blocks/germlings/sapling.treeSipiri.png b/forestry_resources/assets/forestry/textures/blocks/germlings/sapling.treeSipiri.png new file mode 100755 index 000000000..6f4118e74 Binary files /dev/null and b/forestry_resources/assets/forestry/textures/blocks/germlings/sapling.treeSipiri.png differ diff --git a/forestry_resources/assets/forestry/textures/blocks/germlings/sapling.treeTeak.png b/forestry_resources/assets/forestry/textures/blocks/germlings/sapling.treeTeak.png new file mode 100755 index 000000000..100095ac0 Binary files /dev/null and b/forestry_resources/assets/forestry/textures/blocks/germlings/sapling.treeTeak.png differ diff --git a/forestry_resources/assets/forestry/textures/blocks/germlings/sapling.treeWalnut.png b/forestry_resources/assets/forestry/textures/blocks/germlings/sapling.treeWalnut.png new file mode 100755 index 000000000..50e60305e Binary files /dev/null and b/forestry_resources/assets/forestry/textures/blocks/germlings/sapling.treeWalnut.png differ diff --git a/forestry_resources/assets/forestry/textures/blocks/germlings/sapling.treeWenge.png b/forestry_resources/assets/forestry/textures/blocks/germlings/sapling.treeWenge.png new file mode 100755 index 000000000..ac53cfe95 Binary files /dev/null and b/forestry_resources/assets/forestry/textures/blocks/germlings/sapling.treeWenge.png differ diff --git a/forestry_resources/assets/forestry/textures/blocks/germlings/sapling.treeWillow.png b/forestry_resources/assets/forestry/textures/blocks/germlings/sapling.treeWillow.png new file mode 100755 index 000000000..34ac27523 Binary files /dev/null and b/forestry_resources/assets/forestry/textures/blocks/germlings/sapling.treeWillow.png differ diff --git a/forestry_resources/assets/forestry/textures/blocks/leaves/conifers.changed.png b/forestry_resources/assets/forestry/textures/blocks/leaves/conifers.changed.png new file mode 100755 index 000000000..d316478e4 Binary files /dev/null and b/forestry_resources/assets/forestry/textures/blocks/leaves/conifers.changed.png differ diff --git a/forestry_resources/assets/forestry/textures/blocks/leaves/conifers.fancy.png b/forestry_resources/assets/forestry/textures/blocks/leaves/conifers.fancy.png new file mode 100755 index 000000000..4004fdc1f Binary files /dev/null and b/forestry_resources/assets/forestry/textures/blocks/leaves/conifers.fancy.png differ diff --git a/forestry_resources/assets/forestry/textures/blocks/leaves/conifers.plain.png b/forestry_resources/assets/forestry/textures/blocks/leaves/conifers.plain.png new file mode 100755 index 000000000..7c692d6a9 Binary files /dev/null and b/forestry_resources/assets/forestry/textures/blocks/leaves/conifers.plain.png differ diff --git a/forestry_resources/assets/forestry/textures/blocks/leaves/deciduous.changed.png b/forestry_resources/assets/forestry/textures/blocks/leaves/deciduous.changed.png new file mode 100755 index 000000000..6a9a05c90 Binary files /dev/null and b/forestry_resources/assets/forestry/textures/blocks/leaves/deciduous.changed.png differ diff --git a/forestry_resources/assets/forestry/textures/blocks/leaves/deciduous.fancy.png b/forestry_resources/assets/forestry/textures/blocks/leaves/deciduous.fancy.png new file mode 100755 index 000000000..c5b7c2947 Binary files /dev/null and b/forestry_resources/assets/forestry/textures/blocks/leaves/deciduous.fancy.png differ diff --git a/forestry_resources/assets/forestry/textures/blocks/leaves/deciduous.plain.png b/forestry_resources/assets/forestry/textures/blocks/leaves/deciduous.plain.png new file mode 100755 index 000000000..966407f9d Binary files /dev/null and b/forestry_resources/assets/forestry/textures/blocks/leaves/deciduous.plain.png differ diff --git a/forestry_resources/assets/forestry/textures/blocks/leaves/fruits.berries.png b/forestry_resources/assets/forestry/textures/blocks/leaves/fruits.berries.png new file mode 100755 index 000000000..7c01fce91 Binary files /dev/null and b/forestry_resources/assets/forestry/textures/blocks/leaves/fruits.berries.png differ diff --git a/forestry_resources/assets/forestry/textures/blocks/leaves/fruits.citrus.png b/forestry_resources/assets/forestry/textures/blocks/leaves/fruits.citrus.png new file mode 100755 index 000000000..757a75cfa Binary files /dev/null and b/forestry_resources/assets/forestry/textures/blocks/leaves/fruits.citrus.png differ diff --git a/forestry_resources/assets/forestry/textures/blocks/leaves/fruits.nuts.png b/forestry_resources/assets/forestry/textures/blocks/leaves/fruits.nuts.png new file mode 100755 index 000000000..62026ca99 Binary files /dev/null and b/forestry_resources/assets/forestry/textures/blocks/leaves/fruits.nuts.png differ diff --git a/forestry_resources/assets/forestry/textures/blocks/leaves/fruits.plums.png b/forestry_resources/assets/forestry/textures/blocks/leaves/fruits.plums.png new file mode 100755 index 000000000..dbc78e42d Binary files /dev/null and b/forestry_resources/assets/forestry/textures/blocks/leaves/fruits.plums.png differ diff --git a/forestry_resources/assets/forestry/textures/blocks/leaves/fruits.pomes.png b/forestry_resources/assets/forestry/textures/blocks/leaves/fruits.pomes.png new file mode 100755 index 000000000..6e0e04195 Binary files /dev/null and b/forestry_resources/assets/forestry/textures/blocks/leaves/fruits.pomes.png differ diff --git a/forestry_resources/assets/forestry/textures/blocks/leaves/jungle.changed.png b/forestry_resources/assets/forestry/textures/blocks/leaves/jungle.changed.png new file mode 100755 index 000000000..3e525ed67 Binary files /dev/null and b/forestry_resources/assets/forestry/textures/blocks/leaves/jungle.changed.png differ diff --git a/forestry_resources/assets/forestry/textures/blocks/leaves/jungle.fancy.png b/forestry_resources/assets/forestry/textures/blocks/leaves/jungle.fancy.png new file mode 100755 index 000000000..0b7603425 Binary files /dev/null and b/forestry_resources/assets/forestry/textures/blocks/leaves/jungle.fancy.png differ diff --git a/forestry_resources/assets/forestry/textures/blocks/leaves/jungle.plain.png b/forestry_resources/assets/forestry/textures/blocks/leaves/jungle.plain.png new file mode 100755 index 000000000..5279c5372 Binary files /dev/null and b/forestry_resources/assets/forestry/textures/blocks/leaves/jungle.plain.png differ diff --git a/forestry_resources/assets/forestry/textures/blocks/leaves/maple.changed.png b/forestry_resources/assets/forestry/textures/blocks/leaves/maple.changed.png new file mode 100755 index 000000000..e7a04055c Binary files /dev/null and b/forestry_resources/assets/forestry/textures/blocks/leaves/maple.changed.png differ diff --git a/forestry_resources/assets/forestry/textures/blocks/leaves/maple.fancy.png b/forestry_resources/assets/forestry/textures/blocks/leaves/maple.fancy.png new file mode 100755 index 000000000..e7a04055c Binary files /dev/null and b/forestry_resources/assets/forestry/textures/blocks/leaves/maple.fancy.png differ diff --git a/forestry_resources/assets/forestry/textures/blocks/leaves/maple.plain.png b/forestry_resources/assets/forestry/textures/blocks/leaves/maple.plain.png new file mode 100755 index 000000000..0f429b4c5 Binary files /dev/null and b/forestry_resources/assets/forestry/textures/blocks/leaves/maple.plain.png differ diff --git a/forestry_resources/assets/forestry/textures/blocks/leaves/palm.changed.png b/forestry_resources/assets/forestry/textures/blocks/leaves/palm.changed.png new file mode 100755 index 000000000..afcffc52a Binary files /dev/null and b/forestry_resources/assets/forestry/textures/blocks/leaves/palm.changed.png differ diff --git a/forestry_resources/assets/forestry/textures/blocks/leaves/palm.fancy.png b/forestry_resources/assets/forestry/textures/blocks/leaves/palm.fancy.png new file mode 100755 index 000000000..87f2d43a0 Binary files /dev/null and b/forestry_resources/assets/forestry/textures/blocks/leaves/palm.fancy.png differ diff --git a/forestry_resources/assets/forestry/textures/blocks/leaves/palm.plain.png b/forestry_resources/assets/forestry/textures/blocks/leaves/palm.plain.png new file mode 100755 index 000000000..3362512e2 Binary files /dev/null and b/forestry_resources/assets/forestry/textures/blocks/leaves/palm.plain.png differ diff --git a/forestry_resources/assets/forestry/textures/blocks/leaves/tile]-103.png b/forestry_resources/assets/forestry/textures/blocks/leaves/tile]-103.png new file mode 100755 index 000000000..18e0d9c7f Binary files /dev/null and b/forestry_resources/assets/forestry/textures/blocks/leaves/tile]-103.png differ diff --git a/forestry_resources/assets/forestry/textures/blocks/leaves/tile]-52.png b/forestry_resources/assets/forestry/textures/blocks/leaves/tile]-52.png new file mode 100755 index 000000000..ba8367f0b Binary files /dev/null and b/forestry_resources/assets/forestry/textures/blocks/leaves/tile]-52.png differ diff --git a/forestry_resources/assets/forestry/textures/blocks/leaves/tile]-68.png b/forestry_resources/assets/forestry/textures/blocks/leaves/tile]-68.png new file mode 100755 index 000000000..212791fdd Binary files /dev/null and b/forestry_resources/assets/forestry/textures/blocks/leaves/tile]-68.png differ diff --git a/forestry_resources/assets/forestry/textures/blocks/leaves/tile]-98.png b/forestry_resources/assets/forestry/textures/blocks/leaves/tile]-98.png new file mode 100755 index 000000000..dea306a17 Binary files /dev/null and b/forestry_resources/assets/forestry/textures/blocks/leaves/tile]-98.png differ diff --git a/forestry_resources/assets/forestry/textures/blocks/leaves/willow.changed.png b/forestry_resources/assets/forestry/textures/blocks/leaves/willow.changed.png new file mode 100755 index 000000000..d4ad816dd Binary files /dev/null and b/forestry_resources/assets/forestry/textures/blocks/leaves/willow.changed.png differ diff --git a/forestry_resources/assets/forestry/textures/blocks/leaves/willow.fancy.png b/forestry_resources/assets/forestry/textures/blocks/leaves/willow.fancy.png new file mode 100755 index 000000000..d4ad816dd Binary files /dev/null and b/forestry_resources/assets/forestry/textures/blocks/leaves/willow.fancy.png differ diff --git a/forestry_resources/assets/forestry/textures/blocks/leaves/willow.plain.png b/forestry_resources/assets/forestry/textures/blocks/leaves/willow.plain.png new file mode 100755 index 000000000..d906d8e88 Binary files /dev/null and b/forestry_resources/assets/forestry/textures/blocks/leaves/willow.plain.png differ diff --git a/forestry_resources/assets/forestry/textures/blocks/lepichest.0.png b/forestry_resources/assets/forestry/textures/blocks/lepichest.0.png new file mode 100755 index 000000000..26bd0f31e Binary files /dev/null and b/forestry_resources/assets/forestry/textures/blocks/lepichest.0.png differ diff --git a/forestry_resources/assets/forestry/textures/blocks/lepichest.1.png b/forestry_resources/assets/forestry/textures/blocks/lepichest.1.png new file mode 100755 index 000000000..71a5e3a18 Binary files /dev/null and b/forestry_resources/assets/forestry/textures/blocks/lepichest.1.png differ diff --git a/forestry_resources/assets/forestry/textures/blocks/lepichest.2.png b/forestry_resources/assets/forestry/textures/blocks/lepichest.2.png new file mode 100755 index 000000000..3e27ce8e7 Binary files /dev/null and b/forestry_resources/assets/forestry/textures/blocks/lepichest.2.png differ diff --git a/forestry_resources/assets/forestry/textures/blocks/lepichest.3.png b/forestry_resources/assets/forestry/textures/blocks/lepichest.3.png new file mode 100755 index 000000000..2241f5ff5 Binary files /dev/null and b/forestry_resources/assets/forestry/textures/blocks/lepichest.3.png differ diff --git a/forestry_resources/assets/forestry/textures/blocks/lepichest.4.png b/forestry_resources/assets/forestry/textures/blocks/lepichest.4.png new file mode 100755 index 000000000..325874ce8 Binary files /dev/null and b/forestry_resources/assets/forestry/textures/blocks/lepichest.4.png differ diff --git a/forestry_resources/assets/forestry/textures/blocks/lepichest.7.png b/forestry_resources/assets/forestry/textures/blocks/lepichest.7.png new file mode 100755 index 000000000..bc9f9fddc Binary files /dev/null and b/forestry_resources/assets/forestry/textures/blocks/lepichest.7.png differ diff --git a/forestry_resources/assets/forestry/textures/blocks/liquid/bioethanol.png b/forestry_resources/assets/forestry/textures/blocks/liquid/bioethanol.png new file mode 100755 index 000000000..f3908169b Binary files /dev/null and b/forestry_resources/assets/forestry/textures/blocks/liquid/bioethanol.png differ diff --git a/forestry_resources/assets/forestry/textures/blocks/liquid/bioethanol.png.mcmeta b/forestry_resources/assets/forestry/textures/blocks/liquid/bioethanol.png.mcmeta new file mode 100755 index 000000000..0c36dcaa8 --- /dev/null +++ b/forestry_resources/assets/forestry/textures/blocks/liquid/bioethanol.png.mcmeta @@ -0,0 +1 @@ +{"animation":{"width":1,"height":32,"frametime":1,"frames":[{"index":0,"time":2},{"index":1,"time":2},{"index":2,"time":2},{"index":3,"time":2},{"index":4,"time":2},{"index":5,"time":2},{"index":6,"time":2},{"index":7,"time":2},{"index":8,"time":2},{"index":9,"time":2},{"index":10,"time":2},{"index":11,"time":2},{"index":12,"time":2},{"index":13,"time":2},{"index":14,"time":2},{"index":15,"time":2},{"index":16,"time":2},{"index":17,"time":2},{"index":18,"time":2},{"index":19,"time":2},{"index":20,"time":2},{"index":21,"time":2},{"index":22,"time":2},{"index":23,"time":2},{"index":24,"time":2},{"index":25,"time":2},{"index":26,"time":2},{"index":27,"time":2},{"index":28,"time":2},{"index":29,"time":2},{"index":30,"time":2},{"index":31,"time":2}]}} \ No newline at end of file diff --git a/forestry_resources/assets/forestry/textures/blocks/liquid/biomass.png b/forestry_resources/assets/forestry/textures/blocks/liquid/biomass.png new file mode 100755 index 000000000..ac7ece8e0 Binary files /dev/null and b/forestry_resources/assets/forestry/textures/blocks/liquid/biomass.png differ diff --git a/forestry_resources/assets/forestry/textures/blocks/liquid/biomass.png.mcmeta b/forestry_resources/assets/forestry/textures/blocks/liquid/biomass.png.mcmeta new file mode 100755 index 000000000..0c36dcaa8 --- /dev/null +++ b/forestry_resources/assets/forestry/textures/blocks/liquid/biomass.png.mcmeta @@ -0,0 +1 @@ +{"animation":{"width":1,"height":32,"frametime":1,"frames":[{"index":0,"time":2},{"index":1,"time":2},{"index":2,"time":2},{"index":3,"time":2},{"index":4,"time":2},{"index":5,"time":2},{"index":6,"time":2},{"index":7,"time":2},{"index":8,"time":2},{"index":9,"time":2},{"index":10,"time":2},{"index":11,"time":2},{"index":12,"time":2},{"index":13,"time":2},{"index":14,"time":2},{"index":15,"time":2},{"index":16,"time":2},{"index":17,"time":2},{"index":18,"time":2},{"index":19,"time":2},{"index":20,"time":2},{"index":21,"time":2},{"index":22,"time":2},{"index":23,"time":2},{"index":24,"time":2},{"index":25,"time":2},{"index":26,"time":2},{"index":27,"time":2},{"index":28,"time":2},{"index":29,"time":2},{"index":30,"time":2},{"index":31,"time":2}]}} \ No newline at end of file diff --git a/forestry_resources/assets/forestry/textures/blocks/liquid/glass.png b/forestry_resources/assets/forestry/textures/blocks/liquid/glass.png new file mode 100755 index 000000000..da2051220 Binary files /dev/null and b/forestry_resources/assets/forestry/textures/blocks/liquid/glass.png differ diff --git a/forestry_resources/assets/forestry/textures/blocks/liquid/glass.png.mcmeta b/forestry_resources/assets/forestry/textures/blocks/liquid/glass.png.mcmeta new file mode 100755 index 000000000..0c36dcaa8 --- /dev/null +++ b/forestry_resources/assets/forestry/textures/blocks/liquid/glass.png.mcmeta @@ -0,0 +1 @@ +{"animation":{"width":1,"height":32,"frametime":1,"frames":[{"index":0,"time":2},{"index":1,"time":2},{"index":2,"time":2},{"index":3,"time":2},{"index":4,"time":2},{"index":5,"time":2},{"index":6,"time":2},{"index":7,"time":2},{"index":8,"time":2},{"index":9,"time":2},{"index":10,"time":2},{"index":11,"time":2},{"index":12,"time":2},{"index":13,"time":2},{"index":14,"time":2},{"index":15,"time":2},{"index":16,"time":2},{"index":17,"time":2},{"index":18,"time":2},{"index":19,"time":2},{"index":20,"time":2},{"index":21,"time":2},{"index":22,"time":2},{"index":23,"time":2},{"index":24,"time":2},{"index":25,"time":2},{"index":26,"time":2},{"index":27,"time":2},{"index":28,"time":2},{"index":29,"time":2},{"index":30,"time":2},{"index":31,"time":2}]}} \ No newline at end of file diff --git a/forestry_resources/assets/forestry/textures/blocks/liquid/honey.png b/forestry_resources/assets/forestry/textures/blocks/liquid/honey.png new file mode 100755 index 000000000..1930202f8 Binary files /dev/null and b/forestry_resources/assets/forestry/textures/blocks/liquid/honey.png differ diff --git a/forestry_resources/assets/forestry/textures/blocks/liquid/honey.png.mcmeta b/forestry_resources/assets/forestry/textures/blocks/liquid/honey.png.mcmeta new file mode 100755 index 000000000..0c36dcaa8 --- /dev/null +++ b/forestry_resources/assets/forestry/textures/blocks/liquid/honey.png.mcmeta @@ -0,0 +1 @@ +{"animation":{"width":1,"height":32,"frametime":1,"frames":[{"index":0,"time":2},{"index":1,"time":2},{"index":2,"time":2},{"index":3,"time":2},{"index":4,"time":2},{"index":5,"time":2},{"index":6,"time":2},{"index":7,"time":2},{"index":8,"time":2},{"index":9,"time":2},{"index":10,"time":2},{"index":11,"time":2},{"index":12,"time":2},{"index":13,"time":2},{"index":14,"time":2},{"index":15,"time":2},{"index":16,"time":2},{"index":17,"time":2},{"index":18,"time":2},{"index":19,"time":2},{"index":20,"time":2},{"index":21,"time":2},{"index":22,"time":2},{"index":23,"time":2},{"index":24,"time":2},{"index":25,"time":2},{"index":26,"time":2},{"index":27,"time":2},{"index":28,"time":2},{"index":29,"time":2},{"index":30,"time":2},{"index":31,"time":2}]}} \ No newline at end of file diff --git a/forestry_resources/assets/forestry/textures/blocks/liquid/ice.png b/forestry_resources/assets/forestry/textures/blocks/liquid/ice.png new file mode 100755 index 000000000..aa9a59e18 Binary files /dev/null and b/forestry_resources/assets/forestry/textures/blocks/liquid/ice.png differ diff --git a/forestry_resources/assets/forestry/textures/blocks/liquid/ice.png.mcmeta b/forestry_resources/assets/forestry/textures/blocks/liquid/ice.png.mcmeta new file mode 100755 index 000000000..0c36dcaa8 --- /dev/null +++ b/forestry_resources/assets/forestry/textures/blocks/liquid/ice.png.mcmeta @@ -0,0 +1 @@ +{"animation":{"width":1,"height":32,"frametime":1,"frames":[{"index":0,"time":2},{"index":1,"time":2},{"index":2,"time":2},{"index":3,"time":2},{"index":4,"time":2},{"index":5,"time":2},{"index":6,"time":2},{"index":7,"time":2},{"index":8,"time":2},{"index":9,"time":2},{"index":10,"time":2},{"index":11,"time":2},{"index":12,"time":2},{"index":13,"time":2},{"index":14,"time":2},{"index":15,"time":2},{"index":16,"time":2},{"index":17,"time":2},{"index":18,"time":2},{"index":19,"time":2},{"index":20,"time":2},{"index":21,"time":2},{"index":22,"time":2},{"index":23,"time":2},{"index":24,"time":2},{"index":25,"time":2},{"index":26,"time":2},{"index":27,"time":2},{"index":28,"time":2},{"index":29,"time":2},{"index":30,"time":2},{"index":31,"time":2}]}} \ No newline at end of file diff --git a/forestry_resources/assets/forestry/textures/blocks/liquid/juice.png b/forestry_resources/assets/forestry/textures/blocks/liquid/juice.png new file mode 100755 index 000000000..680abbd05 Binary files /dev/null and b/forestry_resources/assets/forestry/textures/blocks/liquid/juice.png differ diff --git a/forestry_resources/assets/forestry/textures/blocks/liquid/juice.png.mcmeta b/forestry_resources/assets/forestry/textures/blocks/liquid/juice.png.mcmeta new file mode 100755 index 000000000..0c36dcaa8 --- /dev/null +++ b/forestry_resources/assets/forestry/textures/blocks/liquid/juice.png.mcmeta @@ -0,0 +1 @@ +{"animation":{"width":1,"height":32,"frametime":1,"frames":[{"index":0,"time":2},{"index":1,"time":2},{"index":2,"time":2},{"index":3,"time":2},{"index":4,"time":2},{"index":5,"time":2},{"index":6,"time":2},{"index":7,"time":2},{"index":8,"time":2},{"index":9,"time":2},{"index":10,"time":2},{"index":11,"time":2},{"index":12,"time":2},{"index":13,"time":2},{"index":14,"time":2},{"index":15,"time":2},{"index":16,"time":2},{"index":17,"time":2},{"index":18,"time":2},{"index":19,"time":2},{"index":20,"time":2},{"index":21,"time":2},{"index":22,"time":2},{"index":23,"time":2},{"index":24,"time":2},{"index":25,"time":2},{"index":26,"time":2},{"index":27,"time":2},{"index":28,"time":2},{"index":29,"time":2},{"index":30,"time":2},{"index":31,"time":2}]}} \ No newline at end of file diff --git a/forestry_resources/assets/forestry/textures/blocks/liquid/milk.png b/forestry_resources/assets/forestry/textures/blocks/liquid/milk.png new file mode 100755 index 000000000..a0e5d982b Binary files /dev/null and b/forestry_resources/assets/forestry/textures/blocks/liquid/milk.png differ diff --git a/forestry_resources/assets/forestry/textures/blocks/liquid/seedoil.png b/forestry_resources/assets/forestry/textures/blocks/liquid/seedoil.png new file mode 100755 index 000000000..05e40abfd Binary files /dev/null and b/forestry_resources/assets/forestry/textures/blocks/liquid/seedoil.png differ diff --git a/forestry_resources/assets/forestry/textures/blocks/liquid/seedoil.png.mcmeta b/forestry_resources/assets/forestry/textures/blocks/liquid/seedoil.png.mcmeta new file mode 100755 index 000000000..0c36dcaa8 --- /dev/null +++ b/forestry_resources/assets/forestry/textures/blocks/liquid/seedoil.png.mcmeta @@ -0,0 +1 @@ +{"animation":{"width":1,"height":32,"frametime":1,"frames":[{"index":0,"time":2},{"index":1,"time":2},{"index":2,"time":2},{"index":3,"time":2},{"index":4,"time":2},{"index":5,"time":2},{"index":6,"time":2},{"index":7,"time":2},{"index":8,"time":2},{"index":9,"time":2},{"index":10,"time":2},{"index":11,"time":2},{"index":12,"time":2},{"index":13,"time":2},{"index":14,"time":2},{"index":15,"time":2},{"index":16,"time":2},{"index":17,"time":2},{"index":18,"time":2},{"index":19,"time":2},{"index":20,"time":2},{"index":21,"time":2},{"index":22,"time":2},{"index":23,"time":2},{"index":24,"time":2},{"index":25,"time":2},{"index":26,"time":2},{"index":27,"time":2},{"index":28,"time":2},{"index":29,"time":2},{"index":30,"time":2},{"index":31,"time":2}]}} \ No newline at end of file diff --git a/forestry_resources/assets/forestry/textures/blocks/liquid/short.mead.png b/forestry_resources/assets/forestry/textures/blocks/liquid/short.mead.png new file mode 100755 index 000000000..595689671 Binary files /dev/null and b/forestry_resources/assets/forestry/textures/blocks/liquid/short.mead.png differ diff --git a/forestry_resources/assets/forestry/textures/blocks/liquid/short.mead.png.mcmeta b/forestry_resources/assets/forestry/textures/blocks/liquid/short.mead.png.mcmeta new file mode 100755 index 000000000..0c36dcaa8 --- /dev/null +++ b/forestry_resources/assets/forestry/textures/blocks/liquid/short.mead.png.mcmeta @@ -0,0 +1 @@ +{"animation":{"width":1,"height":32,"frametime":1,"frames":[{"index":0,"time":2},{"index":1,"time":2},{"index":2,"time":2},{"index":3,"time":2},{"index":4,"time":2},{"index":5,"time":2},{"index":6,"time":2},{"index":7,"time":2},{"index":8,"time":2},{"index":9,"time":2},{"index":10,"time":2},{"index":11,"time":2},{"index":12,"time":2},{"index":13,"time":2},{"index":14,"time":2},{"index":15,"time":2},{"index":16,"time":2},{"index":17,"time":2},{"index":18,"time":2},{"index":19,"time":2},{"index":20,"time":2},{"index":21,"time":2},{"index":22,"time":2},{"index":23,"time":2},{"index":24,"time":2},{"index":25,"time":2},{"index":26,"time":2},{"index":27,"time":2},{"index":28,"time":2},{"index":29,"time":2},{"index":30,"time":2},{"index":31,"time":2}]}} \ No newline at end of file diff --git a/forestry_resources/assets/forestry/textures/blocks/mailbox.0.png b/forestry_resources/assets/forestry/textures/blocks/mailbox.0.png new file mode 100755 index 000000000..053849719 Binary files /dev/null and b/forestry_resources/assets/forestry/textures/blocks/mailbox.0.png differ diff --git a/forestry_resources/assets/forestry/textures/blocks/mailbox.1.png b/forestry_resources/assets/forestry/textures/blocks/mailbox.1.png new file mode 100755 index 000000000..46b0be63d Binary files /dev/null and b/forestry_resources/assets/forestry/textures/blocks/mailbox.1.png differ diff --git a/forestry_resources/assets/forestry/textures/blocks/mailbox.2.png b/forestry_resources/assets/forestry/textures/blocks/mailbox.2.png new file mode 100755 index 000000000..b923a6377 Binary files /dev/null and b/forestry_resources/assets/forestry/textures/blocks/mailbox.2.png differ diff --git a/forestry_resources/assets/forestry/textures/blocks/mailbox.7.png b/forestry_resources/assets/forestry/textures/blocks/mailbox.7.png new file mode 100755 index 000000000..e00bad970 Binary files /dev/null and b/forestry_resources/assets/forestry/textures/blocks/mailbox.7.png differ diff --git a/forestry_resources/assets/forestry/textures/blocks/moistener.0.png b/forestry_resources/assets/forestry/textures/blocks/moistener.0.png new file mode 100755 index 000000000..a99fa4b58 Binary files /dev/null and b/forestry_resources/assets/forestry/textures/blocks/moistener.0.png differ diff --git a/forestry_resources/assets/forestry/textures/blocks/moistener_base.png b/forestry_resources/assets/forestry/textures/blocks/moistener_base.png new file mode 100755 index 000000000..545997175 Binary files /dev/null and b/forestry_resources/assets/forestry/textures/blocks/moistener_base.png differ diff --git a/forestry_resources/assets/forestry/textures/blocks/moistener_tank_product_empty.png b/forestry_resources/assets/forestry/textures/blocks/moistener_tank_product_empty.png new file mode 100755 index 000000000..b9bfa775a Binary files /dev/null and b/forestry_resources/assets/forestry/textures/blocks/moistener_tank_product_empty.png differ diff --git a/forestry_resources/assets/forestry/textures/blocks/moistener_tank_resource_empty.png b/forestry_resources/assets/forestry/textures/blocks/moistener_tank_resource_empty.png new file mode 100755 index 000000000..154c0eefb Binary files /dev/null and b/forestry_resources/assets/forestry/textures/blocks/moistener_tank_resource_empty.png differ diff --git a/forestry_resources/assets/forestry/textures/blocks/moistener_tank_resource_high.png b/forestry_resources/assets/forestry/textures/blocks/moistener_tank_resource_high.png new file mode 100755 index 000000000..eddf4ba55 Binary files /dev/null and b/forestry_resources/assets/forestry/textures/blocks/moistener_tank_resource_high.png differ diff --git a/forestry_resources/assets/forestry/textures/blocks/moistener_tank_resource_low.png b/forestry_resources/assets/forestry/textures/blocks/moistener_tank_resource_low.png new file mode 100755 index 000000000..8bd981d8a Binary files /dev/null and b/forestry_resources/assets/forestry/textures/blocks/moistener_tank_resource_low.png differ diff --git a/forestry_resources/assets/forestry/textures/blocks/moistener_tank_resource_maximum.png b/forestry_resources/assets/forestry/textures/blocks/moistener_tank_resource_maximum.png new file mode 100755 index 000000000..405b23547 Binary files /dev/null and b/forestry_resources/assets/forestry/textures/blocks/moistener_tank_resource_maximum.png differ diff --git a/forestry_resources/assets/forestry/textures/blocks/moistener_tank_resource_medium.png b/forestry_resources/assets/forestry/textures/blocks/moistener_tank_resource_medium.png new file mode 100755 index 000000000..6d8393972 Binary files /dev/null and b/forestry_resources/assets/forestry/textures/blocks/moistener_tank_resource_medium.png differ diff --git a/forestry_resources/assets/forestry/textures/blocks/ores/apatite.png b/forestry_resources/assets/forestry/textures/blocks/ores/apatite.png new file mode 100755 index 000000000..5a9f0fb1d Binary files /dev/null and b/forestry_resources/assets/forestry/textures/blocks/ores/apatite.png differ diff --git a/forestry_resources/assets/forestry/textures/blocks/ores/copper.png b/forestry_resources/assets/forestry/textures/blocks/ores/copper.png new file mode 100755 index 000000000..84efec7af Binary files /dev/null and b/forestry_resources/assets/forestry/textures/blocks/ores/copper.png differ diff --git a/forestry_resources/assets/forestry/textures/blocks/ores/tin.png b/forestry_resources/assets/forestry/textures/blocks/ores/tin.png new file mode 100755 index 000000000..097284940 Binary files /dev/null and b/forestry_resources/assets/forestry/textures/blocks/ores/tin.png differ diff --git a/forestry_resources/assets/forestry/textures/blocks/philatelist.0.png b/forestry_resources/assets/forestry/textures/blocks/philatelist.0.png new file mode 100755 index 000000000..053849719 Binary files /dev/null and b/forestry_resources/assets/forestry/textures/blocks/philatelist.0.png differ diff --git a/forestry_resources/assets/forestry/textures/blocks/philatelist.1.png b/forestry_resources/assets/forestry/textures/blocks/philatelist.1.png new file mode 100755 index 000000000..46b0be63d Binary files /dev/null and b/forestry_resources/assets/forestry/textures/blocks/philatelist.1.png differ diff --git a/forestry_resources/assets/forestry/textures/blocks/philatelist.2.png b/forestry_resources/assets/forestry/textures/blocks/philatelist.2.png new file mode 100755 index 000000000..92205f71e Binary files /dev/null and b/forestry_resources/assets/forestry/textures/blocks/philatelist.2.png differ diff --git a/forestry_resources/assets/forestry/textures/blocks/philatelist.3.png b/forestry_resources/assets/forestry/textures/blocks/philatelist.3.png new file mode 100755 index 000000000..5139f19d2 Binary files /dev/null and b/forestry_resources/assets/forestry/textures/blocks/philatelist.3.png differ diff --git a/forestry_resources/assets/forestry/textures/blocks/philatelist.7.png b/forestry_resources/assets/forestry/textures/blocks/philatelist.7.png new file mode 100755 index 000000000..e00bad970 Binary files /dev/null and b/forestry_resources/assets/forestry/textures/blocks/philatelist.7.png differ diff --git a/forestry_resources/assets/forestry/textures/blocks/pipes/pipe_prop.black.png b/forestry_resources/assets/forestry/textures/blocks/pipes/pipe_prop.black.png new file mode 100755 index 000000000..82ff6a01c Binary files /dev/null and b/forestry_resources/assets/forestry/textures/blocks/pipes/pipe_prop.black.png differ diff --git a/forestry_resources/assets/forestry/textures/blocks/pipes/pipe_prop.blue.png b/forestry_resources/assets/forestry/textures/blocks/pipes/pipe_prop.blue.png new file mode 100755 index 000000000..c0b37ceb7 Binary files /dev/null and b/forestry_resources/assets/forestry/textures/blocks/pipes/pipe_prop.blue.png differ diff --git a/forestry_resources/assets/forestry/textures/blocks/pipes/pipe_prop.empty.png b/forestry_resources/assets/forestry/textures/blocks/pipes/pipe_prop.empty.png new file mode 100755 index 000000000..f38573fc2 Binary files /dev/null and b/forestry_resources/assets/forestry/textures/blocks/pipes/pipe_prop.empty.png differ diff --git a/forestry_resources/assets/forestry/textures/blocks/pipes/pipe_prop.green.png b/forestry_resources/assets/forestry/textures/blocks/pipes/pipe_prop.green.png new file mode 100755 index 000000000..7124311e9 Binary files /dev/null and b/forestry_resources/assets/forestry/textures/blocks/pipes/pipe_prop.green.png differ diff --git a/forestry_resources/assets/forestry/textures/blocks/pipes/pipe_prop.red.png b/forestry_resources/assets/forestry/textures/blocks/pipes/pipe_prop.red.png new file mode 100755 index 000000000..b8b86e8fd Binary files /dev/null and b/forestry_resources/assets/forestry/textures/blocks/pipes/pipe_prop.red.png differ diff --git a/forestry_resources/assets/forestry/textures/blocks/pipes/pipe_prop.white.png b/forestry_resources/assets/forestry/textures/blocks/pipes/pipe_prop.white.png new file mode 100755 index 000000000..86ec1d3e0 Binary files /dev/null and b/forestry_resources/assets/forestry/textures/blocks/pipes/pipe_prop.white.png differ diff --git a/forestry_resources/assets/forestry/textures/blocks/pipes/pipe_prop.yellow.png b/forestry_resources/assets/forestry/textures/blocks/pipes/pipe_prop.yellow.png new file mode 100755 index 000000000..b7ba66f51 Binary files /dev/null and b/forestry_resources/assets/forestry/textures/blocks/pipes/pipe_prop.yellow.png differ diff --git a/forestry_resources/assets/forestry/textures/blocks/pods/dates.0.png b/forestry_resources/assets/forestry/textures/blocks/pods/dates.0.png new file mode 100755 index 000000000..2f9d2c7a7 Binary files /dev/null and b/forestry_resources/assets/forestry/textures/blocks/pods/dates.0.png differ diff --git a/forestry_resources/assets/forestry/textures/blocks/pods/dates.1.png b/forestry_resources/assets/forestry/textures/blocks/pods/dates.1.png new file mode 100755 index 000000000..55c5ffdbe Binary files /dev/null and b/forestry_resources/assets/forestry/textures/blocks/pods/dates.1.png differ diff --git a/forestry_resources/assets/forestry/textures/blocks/pods/dates.2.png b/forestry_resources/assets/forestry/textures/blocks/pods/dates.2.png new file mode 100755 index 000000000..4680395a7 Binary files /dev/null and b/forestry_resources/assets/forestry/textures/blocks/pods/dates.2.png differ diff --git a/forestry_resources/assets/forestry/textures/blocks/pods/papaya.0.png b/forestry_resources/assets/forestry/textures/blocks/pods/papaya.0.png new file mode 100755 index 000000000..ef8d66ef1 Binary files /dev/null and b/forestry_resources/assets/forestry/textures/blocks/pods/papaya.0.png differ diff --git a/forestry_resources/assets/forestry/textures/blocks/pods/papaya.1.png b/forestry_resources/assets/forestry/textures/blocks/pods/papaya.1.png new file mode 100755 index 000000000..8cc25d086 Binary files /dev/null and b/forestry_resources/assets/forestry/textures/blocks/pods/papaya.1.png differ diff --git a/forestry_resources/assets/forestry/textures/blocks/pods/papaya.2.png b/forestry_resources/assets/forestry/textures/blocks/pods/papaya.2.png new file mode 100755 index 000000000..bb10f28a8 Binary files /dev/null and b/forestry_resources/assets/forestry/textures/blocks/pods/papaya.2.png differ diff --git a/forestry_resources/assets/forestry/textures/blocks/rainmaker.0.png b/forestry_resources/assets/forestry/textures/blocks/rainmaker.0.png new file mode 100755 index 000000000..dfa868c70 Binary files /dev/null and b/forestry_resources/assets/forestry/textures/blocks/rainmaker.0.png differ diff --git a/forestry_resources/assets/forestry/textures/blocks/rainmaker_blade1.png b/forestry_resources/assets/forestry/textures/blocks/rainmaker_blade1.png new file mode 100755 index 000000000..6a7f0f352 Binary files /dev/null and b/forestry_resources/assets/forestry/textures/blocks/rainmaker_blade1.png differ diff --git a/forestry_resources/assets/forestry/textures/blocks/rainmaker_blade2.png b/forestry_resources/assets/forestry/textures/blocks/rainmaker_blade2.png new file mode 100755 index 000000000..099ab13cf Binary files /dev/null and b/forestry_resources/assets/forestry/textures/blocks/rainmaker_blade2.png differ diff --git a/forestry_resources/assets/forestry/textures/blocks/rainmaker_column_0.png b/forestry_resources/assets/forestry/textures/blocks/rainmaker_column_0.png new file mode 100755 index 000000000..30060b516 Binary files /dev/null and b/forestry_resources/assets/forestry/textures/blocks/rainmaker_column_0.png differ diff --git a/forestry_resources/assets/forestry/textures/blocks/rainmaker_column_1.png b/forestry_resources/assets/forestry/textures/blocks/rainmaker_column_1.png new file mode 100755 index 000000000..3bf293fcd Binary files /dev/null and b/forestry_resources/assets/forestry/textures/blocks/rainmaker_column_1.png differ diff --git a/forestry_resources/assets/forestry/textures/blocks/rainmaker_column_2.png b/forestry_resources/assets/forestry/textures/blocks/rainmaker_column_2.png new file mode 100755 index 000000000..6e17ecc0d Binary files /dev/null and b/forestry_resources/assets/forestry/textures/blocks/rainmaker_column_2.png differ diff --git a/forestry_resources/assets/forestry/textures/blocks/rainmaker_column_3.png b/forestry_resources/assets/forestry/textures/blocks/rainmaker_column_3.png new file mode 100755 index 000000000..1159b4240 Binary files /dev/null and b/forestry_resources/assets/forestry/textures/blocks/rainmaker_column_3.png differ diff --git a/forestry_resources/assets/forestry/textures/blocks/rainmaker_column_4.png b/forestry_resources/assets/forestry/textures/blocks/rainmaker_column_4.png new file mode 100755 index 000000000..52a44a309 Binary files /dev/null and b/forestry_resources/assets/forestry/textures/blocks/rainmaker_column_4.png differ diff --git a/forestry_resources/assets/forestry/textures/blocks/rainmaker_column_5.png b/forestry_resources/assets/forestry/textures/blocks/rainmaker_column_5.png new file mode 100755 index 000000000..c739ec24f Binary files /dev/null and b/forestry_resources/assets/forestry/textures/blocks/rainmaker_column_5.png differ diff --git a/forestry_resources/assets/forestry/textures/blocks/rainmaker_column_6.png b/forestry_resources/assets/forestry/textures/blocks/rainmaker_column_6.png new file mode 100755 index 000000000..186b5707f Binary files /dev/null and b/forestry_resources/assets/forestry/textures/blocks/rainmaker_column_6.png differ diff --git a/forestry_resources/assets/forestry/textures/blocks/rainmaker_column_7.png b/forestry_resources/assets/forestry/textures/blocks/rainmaker_column_7.png new file mode 100755 index 000000000..0f96167f5 Binary files /dev/null and b/forestry_resources/assets/forestry/textures/blocks/rainmaker_column_7.png differ diff --git a/forestry_resources/assets/forestry/textures/blocks/rainmaker_extension.png b/forestry_resources/assets/forestry/textures/blocks/rainmaker_extension.png new file mode 100755 index 000000000..c8c43032f Binary files /dev/null and b/forestry_resources/assets/forestry/textures/blocks/rainmaker_extension.png differ diff --git a/forestry_resources/assets/forestry/textures/blocks/rainmaker_pedestal.png b/forestry_resources/assets/forestry/textures/blocks/rainmaker_pedestal.png new file mode 100755 index 000000000..7ad8ace85 Binary files /dev/null and b/forestry_resources/assets/forestry/textures/blocks/rainmaker_pedestal.png differ diff --git a/forestry_resources/assets/forestry/textures/blocks/raintank.0.png b/forestry_resources/assets/forestry/textures/blocks/raintank.0.png new file mode 100755 index 000000000..15e03a97c Binary files /dev/null and b/forestry_resources/assets/forestry/textures/blocks/raintank.0.png differ diff --git a/forestry_resources/assets/forestry/textures/blocks/raintank.1.png b/forestry_resources/assets/forestry/textures/blocks/raintank.1.png new file mode 100755 index 000000000..2c126d71a Binary files /dev/null and b/forestry_resources/assets/forestry/textures/blocks/raintank.1.png differ diff --git a/forestry_resources/assets/forestry/textures/blocks/soil/bog.png b/forestry_resources/assets/forestry/textures/blocks/soil/bog.png new file mode 100755 index 000000000..2ffa34aa5 Binary files /dev/null and b/forestry_resources/assets/forestry/textures/blocks/soil/bog.png differ diff --git a/forestry_resources/assets/forestry/textures/blocks/soil/humus.png b/forestry_resources/assets/forestry/textures/blocks/soil/humus.png new file mode 100755 index 000000000..144e04c37 Binary files /dev/null and b/forestry_resources/assets/forestry/textures/blocks/soil/humus.png differ diff --git a/forestry_resources/assets/forestry/textures/blocks/soil/peat.png b/forestry_resources/assets/forestry/textures/blocks/soil/peat.png new file mode 100755 index 000000000..877db4ee1 Binary files /dev/null and b/forestry_resources/assets/forestry/textures/blocks/soil/peat.png differ diff --git a/forestry_resources/assets/forestry/textures/blocks/squeezer.0.png b/forestry_resources/assets/forestry/textures/blocks/squeezer.0.png new file mode 100755 index 000000000..681473c3e Binary files /dev/null and b/forestry_resources/assets/forestry/textures/blocks/squeezer.0.png differ diff --git a/forestry_resources/assets/forestry/textures/blocks/squeezer_base.png b/forestry_resources/assets/forestry/textures/blocks/squeezer_base.png new file mode 100755 index 000000000..abae4b8f4 Binary files /dev/null and b/forestry_resources/assets/forestry/textures/blocks/squeezer_base.png differ diff --git a/forestry_resources/assets/forestry/textures/blocks/squeezer_tank_product_empty.png b/forestry_resources/assets/forestry/textures/blocks/squeezer_tank_product_empty.png new file mode 100755 index 000000000..f43e1f6d9 Binary files /dev/null and b/forestry_resources/assets/forestry/textures/blocks/squeezer_tank_product_empty.png differ diff --git a/forestry_resources/assets/forestry/textures/blocks/squeezer_tank_product_high.png b/forestry_resources/assets/forestry/textures/blocks/squeezer_tank_product_high.png new file mode 100755 index 000000000..0e283af7b Binary files /dev/null and b/forestry_resources/assets/forestry/textures/blocks/squeezer_tank_product_high.png differ diff --git a/forestry_resources/assets/forestry/textures/blocks/squeezer_tank_product_low.png b/forestry_resources/assets/forestry/textures/blocks/squeezer_tank_product_low.png new file mode 100755 index 000000000..625056d06 Binary files /dev/null and b/forestry_resources/assets/forestry/textures/blocks/squeezer_tank_product_low.png differ diff --git a/forestry_resources/assets/forestry/textures/blocks/squeezer_tank_product_maximum.png b/forestry_resources/assets/forestry/textures/blocks/squeezer_tank_product_maximum.png new file mode 100755 index 000000000..08c1652f7 Binary files /dev/null and b/forestry_resources/assets/forestry/textures/blocks/squeezer_tank_product_maximum.png differ diff --git a/forestry_resources/assets/forestry/textures/blocks/squeezer_tank_product_medium.png b/forestry_resources/assets/forestry/textures/blocks/squeezer_tank_product_medium.png new file mode 100755 index 000000000..8de98c068 Binary files /dev/null and b/forestry_resources/assets/forestry/textures/blocks/squeezer_tank_product_medium.png differ diff --git a/forestry_resources/assets/forestry/textures/blocks/squeezer_tank_resource_empty.png b/forestry_resources/assets/forestry/textures/blocks/squeezer_tank_resource_empty.png new file mode 100755 index 000000000..4e9d9f8f0 Binary files /dev/null and b/forestry_resources/assets/forestry/textures/blocks/squeezer_tank_resource_empty.png differ diff --git a/forestry_resources/assets/forestry/textures/blocks/stained/0.png b/forestry_resources/assets/forestry/textures/blocks/stained/0.png new file mode 100755 index 000000000..a0b0782a5 Binary files /dev/null and b/forestry_resources/assets/forestry/textures/blocks/stained/0.png differ diff --git a/forestry_resources/assets/forestry/textures/blocks/stained/1.png b/forestry_resources/assets/forestry/textures/blocks/stained/1.png new file mode 100755 index 000000000..00bf8c636 Binary files /dev/null and b/forestry_resources/assets/forestry/textures/blocks/stained/1.png differ diff --git a/forestry_resources/assets/forestry/textures/blocks/stained/10.png b/forestry_resources/assets/forestry/textures/blocks/stained/10.png new file mode 100755 index 000000000..f2d613c82 Binary files /dev/null and b/forestry_resources/assets/forestry/textures/blocks/stained/10.png differ diff --git a/forestry_resources/assets/forestry/textures/blocks/stained/11.png b/forestry_resources/assets/forestry/textures/blocks/stained/11.png new file mode 100755 index 000000000..88edb207e Binary files /dev/null and b/forestry_resources/assets/forestry/textures/blocks/stained/11.png differ diff --git a/forestry_resources/assets/forestry/textures/blocks/stained/12.png b/forestry_resources/assets/forestry/textures/blocks/stained/12.png new file mode 100755 index 000000000..61f10121a Binary files /dev/null and b/forestry_resources/assets/forestry/textures/blocks/stained/12.png differ diff --git a/forestry_resources/assets/forestry/textures/blocks/stained/13.png b/forestry_resources/assets/forestry/textures/blocks/stained/13.png new file mode 100755 index 000000000..8cdfacfbc Binary files /dev/null and b/forestry_resources/assets/forestry/textures/blocks/stained/13.png differ diff --git a/forestry_resources/assets/forestry/textures/blocks/stained/14.png b/forestry_resources/assets/forestry/textures/blocks/stained/14.png new file mode 100755 index 000000000..91f4c65b9 Binary files /dev/null and b/forestry_resources/assets/forestry/textures/blocks/stained/14.png differ diff --git a/forestry_resources/assets/forestry/textures/blocks/stained/15.png b/forestry_resources/assets/forestry/textures/blocks/stained/15.png new file mode 100755 index 000000000..88e7b5377 Binary files /dev/null and b/forestry_resources/assets/forestry/textures/blocks/stained/15.png differ diff --git a/forestry_resources/assets/forestry/textures/blocks/stained/2.png b/forestry_resources/assets/forestry/textures/blocks/stained/2.png new file mode 100755 index 000000000..ee58b30f8 Binary files /dev/null and b/forestry_resources/assets/forestry/textures/blocks/stained/2.png differ diff --git a/forestry_resources/assets/forestry/textures/blocks/stained/3.png b/forestry_resources/assets/forestry/textures/blocks/stained/3.png new file mode 100755 index 000000000..5576d6f46 Binary files /dev/null and b/forestry_resources/assets/forestry/textures/blocks/stained/3.png differ diff --git a/forestry_resources/assets/forestry/textures/blocks/stained/4.png b/forestry_resources/assets/forestry/textures/blocks/stained/4.png new file mode 100755 index 000000000..424d3fb51 Binary files /dev/null and b/forestry_resources/assets/forestry/textures/blocks/stained/4.png differ diff --git a/forestry_resources/assets/forestry/textures/blocks/stained/5.png b/forestry_resources/assets/forestry/textures/blocks/stained/5.png new file mode 100755 index 000000000..ebbad593e Binary files /dev/null and b/forestry_resources/assets/forestry/textures/blocks/stained/5.png differ diff --git a/forestry_resources/assets/forestry/textures/blocks/stained/6.png b/forestry_resources/assets/forestry/textures/blocks/stained/6.png new file mode 100755 index 000000000..c62a09ce4 Binary files /dev/null and b/forestry_resources/assets/forestry/textures/blocks/stained/6.png differ diff --git a/forestry_resources/assets/forestry/textures/blocks/stained/7.png b/forestry_resources/assets/forestry/textures/blocks/stained/7.png new file mode 100755 index 000000000..6c25b6462 Binary files /dev/null and b/forestry_resources/assets/forestry/textures/blocks/stained/7.png differ diff --git a/forestry_resources/assets/forestry/textures/blocks/stained/8.png b/forestry_resources/assets/forestry/textures/blocks/stained/8.png new file mode 100755 index 000000000..553183165 Binary files /dev/null and b/forestry_resources/assets/forestry/textures/blocks/stained/8.png differ diff --git a/forestry_resources/assets/forestry/textures/blocks/stained/9.png b/forestry_resources/assets/forestry/textures/blocks/stained/9.png new file mode 100755 index 000000000..414730575 Binary files /dev/null and b/forestry_resources/assets/forestry/textures/blocks/stained/9.png differ diff --git a/forestry_resources/assets/forestry/textures/blocks/still.0.png b/forestry_resources/assets/forestry/textures/blocks/still.0.png new file mode 100755 index 000000000..15e03a97c Binary files /dev/null and b/forestry_resources/assets/forestry/textures/blocks/still.0.png differ diff --git a/forestry_resources/assets/forestry/textures/blocks/still_base.png b/forestry_resources/assets/forestry/textures/blocks/still_base.png new file mode 100755 index 000000000..1f8eb9588 Binary files /dev/null and b/forestry_resources/assets/forestry/textures/blocks/still_base.png differ diff --git a/forestry_resources/assets/forestry/textures/blocks/still_tank_product_empty.png b/forestry_resources/assets/forestry/textures/blocks/still_tank_product_empty.png new file mode 100755 index 000000000..b03552ad6 Binary files /dev/null and b/forestry_resources/assets/forestry/textures/blocks/still_tank_product_empty.png differ diff --git a/forestry_resources/assets/forestry/textures/blocks/still_tank_product_high.png b/forestry_resources/assets/forestry/textures/blocks/still_tank_product_high.png new file mode 100755 index 000000000..8cd4e662e Binary files /dev/null and b/forestry_resources/assets/forestry/textures/blocks/still_tank_product_high.png differ diff --git a/forestry_resources/assets/forestry/textures/blocks/still_tank_product_low.png b/forestry_resources/assets/forestry/textures/blocks/still_tank_product_low.png new file mode 100755 index 000000000..6698a0881 Binary files /dev/null and b/forestry_resources/assets/forestry/textures/blocks/still_tank_product_low.png differ diff --git a/forestry_resources/assets/forestry/textures/blocks/still_tank_product_maximum.png b/forestry_resources/assets/forestry/textures/blocks/still_tank_product_maximum.png new file mode 100755 index 000000000..4987d5372 Binary files /dev/null and b/forestry_resources/assets/forestry/textures/blocks/still_tank_product_maximum.png differ diff --git a/forestry_resources/assets/forestry/textures/blocks/still_tank_product_medium.png b/forestry_resources/assets/forestry/textures/blocks/still_tank_product_medium.png new file mode 100755 index 000000000..ae7556d34 Binary files /dev/null and b/forestry_resources/assets/forestry/textures/blocks/still_tank_product_medium.png differ diff --git a/forestry_resources/assets/forestry/textures/blocks/still_tank_resource_empty.png b/forestry_resources/assets/forestry/textures/blocks/still_tank_resource_empty.png new file mode 100755 index 000000000..b13949885 Binary files /dev/null and b/forestry_resources/assets/forestry/textures/blocks/still_tank_resource_empty.png differ diff --git a/forestry_resources/assets/forestry/textures/blocks/still_tank_resource_high.png b/forestry_resources/assets/forestry/textures/blocks/still_tank_resource_high.png new file mode 100755 index 000000000..481b313d8 Binary files /dev/null and b/forestry_resources/assets/forestry/textures/blocks/still_tank_resource_high.png differ diff --git a/forestry_resources/assets/forestry/textures/blocks/still_tank_resource_low.png b/forestry_resources/assets/forestry/textures/blocks/still_tank_resource_low.png new file mode 100755 index 000000000..69adfc1ae Binary files /dev/null and b/forestry_resources/assets/forestry/textures/blocks/still_tank_resource_low.png differ diff --git a/forestry_resources/assets/forestry/textures/blocks/still_tank_resource_maximum.png b/forestry_resources/assets/forestry/textures/blocks/still_tank_resource_maximum.png new file mode 100755 index 000000000..02fdfbb40 Binary files /dev/null and b/forestry_resources/assets/forestry/textures/blocks/still_tank_resource_maximum.png differ diff --git a/forestry_resources/assets/forestry/textures/blocks/still_tank_resource_medium.png b/forestry_resources/assets/forestry/textures/blocks/still_tank_resource_medium.png new file mode 100755 index 000000000..fd6d420cb Binary files /dev/null and b/forestry_resources/assets/forestry/textures/blocks/still_tank_resource_medium.png differ diff --git a/forestry_resources/assets/forestry/textures/blocks/stump.png b/forestry_resources/assets/forestry/textures/blocks/stump.png new file mode 100755 index 000000000..7755f321a Binary files /dev/null and b/forestry_resources/assets/forestry/textures/blocks/stump.png differ diff --git a/forestry_resources/assets/forestry/textures/blocks/tradestation.0.png b/forestry_resources/assets/forestry/textures/blocks/tradestation.0.png new file mode 100755 index 000000000..053849719 Binary files /dev/null and b/forestry_resources/assets/forestry/textures/blocks/tradestation.0.png differ diff --git a/forestry_resources/assets/forestry/textures/blocks/tradestation.1.png b/forestry_resources/assets/forestry/textures/blocks/tradestation.1.png new file mode 100755 index 000000000..46b0be63d Binary files /dev/null and b/forestry_resources/assets/forestry/textures/blocks/tradestation.1.png differ diff --git a/forestry_resources/assets/forestry/textures/blocks/tradestation.2.png b/forestry_resources/assets/forestry/textures/blocks/tradestation.2.png new file mode 100755 index 000000000..710a6e8e4 Binary files /dev/null and b/forestry_resources/assets/forestry/textures/blocks/tradestation.2.png differ diff --git a/forestry_resources/assets/forestry/textures/blocks/tradestation.3.png b/forestry_resources/assets/forestry/textures/blocks/tradestation.3.png new file mode 100755 index 000000000..a18c0460e Binary files /dev/null and b/forestry_resources/assets/forestry/textures/blocks/tradestation.3.png differ diff --git a/forestry_resources/assets/forestry/textures/blocks/tradestation.4.png b/forestry_resources/assets/forestry/textures/blocks/tradestation.4.png new file mode 100755 index 000000000..b923a6377 Binary files /dev/null and b/forestry_resources/assets/forestry/textures/blocks/tradestation.4.png differ diff --git a/forestry_resources/assets/forestry/textures/blocks/tradestation.7.png b/forestry_resources/assets/forestry/textures/blocks/tradestation.7.png new file mode 100755 index 000000000..e00bad970 Binary files /dev/null and b/forestry_resources/assets/forestry/textures/blocks/tradestation.7.png differ diff --git a/forestry_resources/assets/forestry/textures/blocks/wood/bark.acacia.png b/forestry_resources/assets/forestry/textures/blocks/wood/bark.acacia.png new file mode 100755 index 000000000..7afccacb9 Binary files /dev/null and b/forestry_resources/assets/forestry/textures/blocks/wood/bark.acacia.png differ diff --git a/forestry_resources/assets/forestry/textures/blocks/wood/bark.balsa.png b/forestry_resources/assets/forestry/textures/blocks/wood/bark.balsa.png new file mode 100755 index 000000000..126b67df9 Binary files /dev/null and b/forestry_resources/assets/forestry/textures/blocks/wood/bark.balsa.png differ diff --git a/forestry_resources/assets/forestry/textures/blocks/wood/bark.baobab.png b/forestry_resources/assets/forestry/textures/blocks/wood/bark.baobab.png new file mode 100755 index 000000000..8db776d26 Binary files /dev/null and b/forestry_resources/assets/forestry/textures/blocks/wood/bark.baobab.png differ diff --git a/forestry_resources/assets/forestry/textures/blocks/wood/bark.cherry.png b/forestry_resources/assets/forestry/textures/blocks/wood/bark.cherry.png new file mode 100755 index 000000000..e9bb79ede Binary files /dev/null and b/forestry_resources/assets/forestry/textures/blocks/wood/bark.cherry.png differ diff --git a/forestry_resources/assets/forestry/textures/blocks/wood/bark.chestnut.png b/forestry_resources/assets/forestry/textures/blocks/wood/bark.chestnut.png new file mode 100755 index 000000000..bf0357944 Binary files /dev/null and b/forestry_resources/assets/forestry/textures/blocks/wood/bark.chestnut.png differ diff --git a/forestry_resources/assets/forestry/textures/blocks/wood/bark.citrus.png b/forestry_resources/assets/forestry/textures/blocks/wood/bark.citrus.png new file mode 100755 index 000000000..f465f4ce9 Binary files /dev/null and b/forestry_resources/assets/forestry/textures/blocks/wood/bark.citrus.png differ diff --git a/forestry_resources/assets/forestry/textures/blocks/wood/bark.ebony.png b/forestry_resources/assets/forestry/textures/blocks/wood/bark.ebony.png new file mode 100755 index 000000000..80d311894 Binary files /dev/null and b/forestry_resources/assets/forestry/textures/blocks/wood/bark.ebony.png differ diff --git a/forestry_resources/assets/forestry/textures/blocks/wood/bark.giganteum.png b/forestry_resources/assets/forestry/textures/blocks/wood/bark.giganteum.png new file mode 100755 index 000000000..16ee0154f Binary files /dev/null and b/forestry_resources/assets/forestry/textures/blocks/wood/bark.giganteum.png differ diff --git a/forestry_resources/assets/forestry/textures/blocks/wood/bark.greenheart.png b/forestry_resources/assets/forestry/textures/blocks/wood/bark.greenheart.png new file mode 100755 index 000000000..5387b429b Binary files /dev/null and b/forestry_resources/assets/forestry/textures/blocks/wood/bark.greenheart.png differ diff --git a/forestry_resources/assets/forestry/textures/blocks/wood/bark.kapok.png b/forestry_resources/assets/forestry/textures/blocks/wood/bark.kapok.png new file mode 100755 index 000000000..6a8326404 Binary files /dev/null and b/forestry_resources/assets/forestry/textures/blocks/wood/bark.kapok.png differ diff --git a/forestry_resources/assets/forestry/textures/blocks/wood/bark.larch.png b/forestry_resources/assets/forestry/textures/blocks/wood/bark.larch.png new file mode 100755 index 000000000..9c2da3988 Binary files /dev/null and b/forestry_resources/assets/forestry/textures/blocks/wood/bark.larch.png differ diff --git a/forestry_resources/assets/forestry/textures/blocks/wood/bark.lime.png b/forestry_resources/assets/forestry/textures/blocks/wood/bark.lime.png new file mode 100755 index 000000000..83cd2187b Binary files /dev/null and b/forestry_resources/assets/forestry/textures/blocks/wood/bark.lime.png differ diff --git a/forestry_resources/assets/forestry/textures/blocks/wood/bark.mahoe.png b/forestry_resources/assets/forestry/textures/blocks/wood/bark.mahoe.png new file mode 100755 index 000000000..f46e0e944 Binary files /dev/null and b/forestry_resources/assets/forestry/textures/blocks/wood/bark.mahoe.png differ diff --git a/forestry_resources/assets/forestry/textures/blocks/wood/bark.mahogany.png b/forestry_resources/assets/forestry/textures/blocks/wood/bark.mahogany.png new file mode 100755 index 000000000..40d700c96 Binary files /dev/null and b/forestry_resources/assets/forestry/textures/blocks/wood/bark.mahogany.png differ diff --git a/forestry_resources/assets/forestry/textures/blocks/wood/bark.maple.png b/forestry_resources/assets/forestry/textures/blocks/wood/bark.maple.png new file mode 100755 index 000000000..22cbd7634 Binary files /dev/null and b/forestry_resources/assets/forestry/textures/blocks/wood/bark.maple.png differ diff --git a/forestry_resources/assets/forestry/textures/blocks/wood/bark.palm.png b/forestry_resources/assets/forestry/textures/blocks/wood/bark.palm.png new file mode 100755 index 000000000..c70ffb5a2 Binary files /dev/null and b/forestry_resources/assets/forestry/textures/blocks/wood/bark.palm.png differ diff --git a/forestry_resources/assets/forestry/textures/blocks/wood/bark.papaya.png b/forestry_resources/assets/forestry/textures/blocks/wood/bark.papaya.png new file mode 100755 index 000000000..587abaa39 Binary files /dev/null and b/forestry_resources/assets/forestry/textures/blocks/wood/bark.papaya.png differ diff --git a/forestry_resources/assets/forestry/textures/blocks/wood/bark.pine.png b/forestry_resources/assets/forestry/textures/blocks/wood/bark.pine.png new file mode 100755 index 000000000..c2adb3a6c Binary files /dev/null and b/forestry_resources/assets/forestry/textures/blocks/wood/bark.pine.png differ diff --git a/forestry_resources/assets/forestry/textures/blocks/wood/bark.plum.png b/forestry_resources/assets/forestry/textures/blocks/wood/bark.plum.png new file mode 100755 index 000000000..d25454ab0 Binary files /dev/null and b/forestry_resources/assets/forestry/textures/blocks/wood/bark.plum.png differ diff --git a/forestry_resources/assets/forestry/textures/blocks/wood/bark.poplar.png b/forestry_resources/assets/forestry/textures/blocks/wood/bark.poplar.png new file mode 100755 index 000000000..6fff2d17f Binary files /dev/null and b/forestry_resources/assets/forestry/textures/blocks/wood/bark.poplar.png differ diff --git a/forestry_resources/assets/forestry/textures/blocks/wood/bark.sequoia.png b/forestry_resources/assets/forestry/textures/blocks/wood/bark.sequoia.png new file mode 100755 index 000000000..c52bb59b8 Binary files /dev/null and b/forestry_resources/assets/forestry/textures/blocks/wood/bark.sequoia.png differ diff --git a/forestry_resources/assets/forestry/textures/blocks/wood/bark.teak.png b/forestry_resources/assets/forestry/textures/blocks/wood/bark.teak.png new file mode 100755 index 000000000..cf97d8999 Binary files /dev/null and b/forestry_resources/assets/forestry/textures/blocks/wood/bark.teak.png differ diff --git a/forestry_resources/assets/forestry/textures/blocks/wood/bark.walnut.png b/forestry_resources/assets/forestry/textures/blocks/wood/bark.walnut.png new file mode 100755 index 000000000..2731313ce Binary files /dev/null and b/forestry_resources/assets/forestry/textures/blocks/wood/bark.walnut.png differ diff --git a/forestry_resources/assets/forestry/textures/blocks/wood/bark.wenge.png b/forestry_resources/assets/forestry/textures/blocks/wood/bark.wenge.png new file mode 100755 index 000000000..5116eb5c9 Binary files /dev/null and b/forestry_resources/assets/forestry/textures/blocks/wood/bark.wenge.png differ diff --git a/forestry_resources/assets/forestry/textures/blocks/wood/bark.willow.png b/forestry_resources/assets/forestry/textures/blocks/wood/bark.willow.png new file mode 100755 index 000000000..7a585b1cc Binary files /dev/null and b/forestry_resources/assets/forestry/textures/blocks/wood/bark.willow.png differ diff --git a/forestry_resources/assets/forestry/textures/blocks/wood/heart.acacia.png b/forestry_resources/assets/forestry/textures/blocks/wood/heart.acacia.png new file mode 100755 index 000000000..d51dc0fc2 Binary files /dev/null and b/forestry_resources/assets/forestry/textures/blocks/wood/heart.acacia.png differ diff --git a/forestry_resources/assets/forestry/textures/blocks/wood/heart.balsa.png b/forestry_resources/assets/forestry/textures/blocks/wood/heart.balsa.png new file mode 100755 index 000000000..c0b5e53bc Binary files /dev/null and b/forestry_resources/assets/forestry/textures/blocks/wood/heart.balsa.png differ diff --git a/forestry_resources/assets/forestry/textures/blocks/wood/heart.baobab.png b/forestry_resources/assets/forestry/textures/blocks/wood/heart.baobab.png new file mode 100755 index 000000000..7f06c7a14 Binary files /dev/null and b/forestry_resources/assets/forestry/textures/blocks/wood/heart.baobab.png differ diff --git a/forestry_resources/assets/forestry/textures/blocks/wood/heart.cherry.png b/forestry_resources/assets/forestry/textures/blocks/wood/heart.cherry.png new file mode 100755 index 000000000..c2d911ac0 Binary files /dev/null and b/forestry_resources/assets/forestry/textures/blocks/wood/heart.cherry.png differ diff --git a/forestry_resources/assets/forestry/textures/blocks/wood/heart.chestnut.png b/forestry_resources/assets/forestry/textures/blocks/wood/heart.chestnut.png new file mode 100755 index 000000000..b232098f8 Binary files /dev/null and b/forestry_resources/assets/forestry/textures/blocks/wood/heart.chestnut.png differ diff --git a/forestry_resources/assets/forestry/textures/blocks/wood/heart.citrus.png b/forestry_resources/assets/forestry/textures/blocks/wood/heart.citrus.png new file mode 100755 index 000000000..93dc75d4e Binary files /dev/null and b/forestry_resources/assets/forestry/textures/blocks/wood/heart.citrus.png differ diff --git a/forestry_resources/assets/forestry/textures/blocks/wood/heart.ebony.png b/forestry_resources/assets/forestry/textures/blocks/wood/heart.ebony.png new file mode 100755 index 000000000..a508f35e8 Binary files /dev/null and b/forestry_resources/assets/forestry/textures/blocks/wood/heart.ebony.png differ diff --git a/forestry_resources/assets/forestry/textures/blocks/wood/heart.giganteum.png b/forestry_resources/assets/forestry/textures/blocks/wood/heart.giganteum.png new file mode 100755 index 000000000..ce257788b Binary files /dev/null and b/forestry_resources/assets/forestry/textures/blocks/wood/heart.giganteum.png differ diff --git a/forestry_resources/assets/forestry/textures/blocks/wood/heart.greenheart.png b/forestry_resources/assets/forestry/textures/blocks/wood/heart.greenheart.png new file mode 100755 index 000000000..2a18661ff Binary files /dev/null and b/forestry_resources/assets/forestry/textures/blocks/wood/heart.greenheart.png differ diff --git a/forestry_resources/assets/forestry/textures/blocks/wood/heart.kapok.png b/forestry_resources/assets/forestry/textures/blocks/wood/heart.kapok.png new file mode 100755 index 000000000..d8bb12a22 Binary files /dev/null and b/forestry_resources/assets/forestry/textures/blocks/wood/heart.kapok.png differ diff --git a/forestry_resources/assets/forestry/textures/blocks/wood/heart.larch.png b/forestry_resources/assets/forestry/textures/blocks/wood/heart.larch.png new file mode 100755 index 000000000..3083c341e Binary files /dev/null and b/forestry_resources/assets/forestry/textures/blocks/wood/heart.larch.png differ diff --git a/forestry_resources/assets/forestry/textures/blocks/wood/heart.lime.png b/forestry_resources/assets/forestry/textures/blocks/wood/heart.lime.png new file mode 100755 index 000000000..3bfcc6dfd Binary files /dev/null and b/forestry_resources/assets/forestry/textures/blocks/wood/heart.lime.png differ diff --git a/forestry_resources/assets/forestry/textures/blocks/wood/heart.mahoe.png b/forestry_resources/assets/forestry/textures/blocks/wood/heart.mahoe.png new file mode 100755 index 000000000..5b166394c Binary files /dev/null and b/forestry_resources/assets/forestry/textures/blocks/wood/heart.mahoe.png differ diff --git a/forestry_resources/assets/forestry/textures/blocks/wood/heart.mahogany.png b/forestry_resources/assets/forestry/textures/blocks/wood/heart.mahogany.png new file mode 100755 index 000000000..36416f988 Binary files /dev/null and b/forestry_resources/assets/forestry/textures/blocks/wood/heart.mahogany.png differ diff --git a/forestry_resources/assets/forestry/textures/blocks/wood/heart.maple.png b/forestry_resources/assets/forestry/textures/blocks/wood/heart.maple.png new file mode 100755 index 000000000..4f0e29658 Binary files /dev/null and b/forestry_resources/assets/forestry/textures/blocks/wood/heart.maple.png differ diff --git a/forestry_resources/assets/forestry/textures/blocks/wood/heart.palm.png b/forestry_resources/assets/forestry/textures/blocks/wood/heart.palm.png new file mode 100755 index 000000000..7590cb0e1 Binary files /dev/null and b/forestry_resources/assets/forestry/textures/blocks/wood/heart.palm.png differ diff --git a/forestry_resources/assets/forestry/textures/blocks/wood/heart.papaya.png b/forestry_resources/assets/forestry/textures/blocks/wood/heart.papaya.png new file mode 100755 index 000000000..64c1f5f28 Binary files /dev/null and b/forestry_resources/assets/forestry/textures/blocks/wood/heart.papaya.png differ diff --git a/forestry_resources/assets/forestry/textures/blocks/wood/heart.pine.png b/forestry_resources/assets/forestry/textures/blocks/wood/heart.pine.png new file mode 100755 index 000000000..fff4a7ffc Binary files /dev/null and b/forestry_resources/assets/forestry/textures/blocks/wood/heart.pine.png differ diff --git a/forestry_resources/assets/forestry/textures/blocks/wood/heart.plum.png b/forestry_resources/assets/forestry/textures/blocks/wood/heart.plum.png new file mode 100755 index 000000000..63a2f53cd Binary files /dev/null and b/forestry_resources/assets/forestry/textures/blocks/wood/heart.plum.png differ diff --git a/forestry_resources/assets/forestry/textures/blocks/wood/heart.poplar.png b/forestry_resources/assets/forestry/textures/blocks/wood/heart.poplar.png new file mode 100755 index 000000000..354b13c1c Binary files /dev/null and b/forestry_resources/assets/forestry/textures/blocks/wood/heart.poplar.png differ diff --git a/forestry_resources/assets/forestry/textures/blocks/wood/heart.sequoia.png b/forestry_resources/assets/forestry/textures/blocks/wood/heart.sequoia.png new file mode 100755 index 000000000..fd24491bf Binary files /dev/null and b/forestry_resources/assets/forestry/textures/blocks/wood/heart.sequoia.png differ diff --git a/forestry_resources/assets/forestry/textures/blocks/wood/heart.teak.png b/forestry_resources/assets/forestry/textures/blocks/wood/heart.teak.png new file mode 100755 index 000000000..93ab57e5a Binary files /dev/null and b/forestry_resources/assets/forestry/textures/blocks/wood/heart.teak.png differ diff --git a/forestry_resources/assets/forestry/textures/blocks/wood/heart.walnut.png b/forestry_resources/assets/forestry/textures/blocks/wood/heart.walnut.png new file mode 100755 index 000000000..368720fbd Binary files /dev/null and b/forestry_resources/assets/forestry/textures/blocks/wood/heart.walnut.png differ diff --git a/forestry_resources/assets/forestry/textures/blocks/wood/heart.wenge.png b/forestry_resources/assets/forestry/textures/blocks/wood/heart.wenge.png new file mode 100755 index 000000000..7a566ee5c Binary files /dev/null and b/forestry_resources/assets/forestry/textures/blocks/wood/heart.wenge.png differ diff --git a/forestry_resources/assets/forestry/textures/blocks/wood/heart.willow.png b/forestry_resources/assets/forestry/textures/blocks/wood/heart.willow.png new file mode 100755 index 000000000..29f6db6d4 Binary files /dev/null and b/forestry_resources/assets/forestry/textures/blocks/wood/heart.willow.png differ diff --git a/forestry_resources/assets/forestry/textures/blocks/wood/planks.acacia.png b/forestry_resources/assets/forestry/textures/blocks/wood/planks.acacia.png new file mode 100755 index 000000000..92b4edbe8 Binary files /dev/null and b/forestry_resources/assets/forestry/textures/blocks/wood/planks.acacia.png differ diff --git a/forestry_resources/assets/forestry/textures/blocks/wood/planks.balsa.png b/forestry_resources/assets/forestry/textures/blocks/wood/planks.balsa.png new file mode 100755 index 000000000..16ce9407d Binary files /dev/null and b/forestry_resources/assets/forestry/textures/blocks/wood/planks.balsa.png differ diff --git a/forestry_resources/assets/forestry/textures/blocks/wood/planks.baobab.png b/forestry_resources/assets/forestry/textures/blocks/wood/planks.baobab.png new file mode 100755 index 000000000..fd67cf55d Binary files /dev/null and b/forestry_resources/assets/forestry/textures/blocks/wood/planks.baobab.png differ diff --git a/forestry_resources/assets/forestry/textures/blocks/wood/planks.cherry.png b/forestry_resources/assets/forestry/textures/blocks/wood/planks.cherry.png new file mode 100755 index 000000000..617b9a4cf Binary files /dev/null and b/forestry_resources/assets/forestry/textures/blocks/wood/planks.cherry.png differ diff --git a/forestry_resources/assets/forestry/textures/blocks/wood/planks.chestnut.png b/forestry_resources/assets/forestry/textures/blocks/wood/planks.chestnut.png new file mode 100755 index 000000000..c8d0961d1 Binary files /dev/null and b/forestry_resources/assets/forestry/textures/blocks/wood/planks.chestnut.png differ diff --git a/forestry_resources/assets/forestry/textures/blocks/wood/planks.citrus.png b/forestry_resources/assets/forestry/textures/blocks/wood/planks.citrus.png new file mode 100755 index 000000000..7e1628004 Binary files /dev/null and b/forestry_resources/assets/forestry/textures/blocks/wood/planks.citrus.png differ diff --git a/forestry_resources/assets/forestry/textures/blocks/wood/planks.ebony.png b/forestry_resources/assets/forestry/textures/blocks/wood/planks.ebony.png new file mode 100755 index 000000000..7b192e40f Binary files /dev/null and b/forestry_resources/assets/forestry/textures/blocks/wood/planks.ebony.png differ diff --git a/forestry_resources/assets/forestry/textures/blocks/wood/planks.greenheart.png b/forestry_resources/assets/forestry/textures/blocks/wood/planks.greenheart.png new file mode 100755 index 000000000..122ed5fc4 Binary files /dev/null and b/forestry_resources/assets/forestry/textures/blocks/wood/planks.greenheart.png differ diff --git a/forestry_resources/assets/forestry/textures/blocks/wood/planks.kapok.png b/forestry_resources/assets/forestry/textures/blocks/wood/planks.kapok.png new file mode 100755 index 000000000..efce0c953 Binary files /dev/null and b/forestry_resources/assets/forestry/textures/blocks/wood/planks.kapok.png differ diff --git a/forestry_resources/assets/forestry/textures/blocks/wood/planks.larch.png b/forestry_resources/assets/forestry/textures/blocks/wood/planks.larch.png new file mode 100755 index 000000000..d0236f8c8 Binary files /dev/null and b/forestry_resources/assets/forestry/textures/blocks/wood/planks.larch.png differ diff --git a/forestry_resources/assets/forestry/textures/blocks/wood/planks.lime.png b/forestry_resources/assets/forestry/textures/blocks/wood/planks.lime.png new file mode 100755 index 000000000..8e6bd70f1 Binary files /dev/null and b/forestry_resources/assets/forestry/textures/blocks/wood/planks.lime.png differ diff --git a/forestry_resources/assets/forestry/textures/blocks/wood/planks.mahoe.png b/forestry_resources/assets/forestry/textures/blocks/wood/planks.mahoe.png new file mode 100755 index 000000000..515de1d3b Binary files /dev/null and b/forestry_resources/assets/forestry/textures/blocks/wood/planks.mahoe.png differ diff --git a/forestry_resources/assets/forestry/textures/blocks/wood/planks.mahogany.png b/forestry_resources/assets/forestry/textures/blocks/wood/planks.mahogany.png new file mode 100755 index 000000000..fd0fb4269 Binary files /dev/null and b/forestry_resources/assets/forestry/textures/blocks/wood/planks.mahogany.png differ diff --git a/forestry_resources/assets/forestry/textures/blocks/wood/planks.maple.png b/forestry_resources/assets/forestry/textures/blocks/wood/planks.maple.png new file mode 100755 index 000000000..7f619ca3f Binary files /dev/null and b/forestry_resources/assets/forestry/textures/blocks/wood/planks.maple.png differ diff --git a/forestry_resources/assets/forestry/textures/blocks/wood/planks.palm.png b/forestry_resources/assets/forestry/textures/blocks/wood/planks.palm.png new file mode 100755 index 000000000..32fe041a4 Binary files /dev/null and b/forestry_resources/assets/forestry/textures/blocks/wood/planks.palm.png differ diff --git a/forestry_resources/assets/forestry/textures/blocks/wood/planks.papaya.png b/forestry_resources/assets/forestry/textures/blocks/wood/planks.papaya.png new file mode 100755 index 000000000..e8813205d Binary files /dev/null and b/forestry_resources/assets/forestry/textures/blocks/wood/planks.papaya.png differ diff --git a/forestry_resources/assets/forestry/textures/blocks/wood/planks.pine.png b/forestry_resources/assets/forestry/textures/blocks/wood/planks.pine.png new file mode 100755 index 000000000..ba82f48fb Binary files /dev/null and b/forestry_resources/assets/forestry/textures/blocks/wood/planks.pine.png differ diff --git a/forestry_resources/assets/forestry/textures/blocks/wood/planks.plum.png b/forestry_resources/assets/forestry/textures/blocks/wood/planks.plum.png new file mode 100755 index 000000000..1533d5b1e Binary files /dev/null and b/forestry_resources/assets/forestry/textures/blocks/wood/planks.plum.png differ diff --git a/forestry_resources/assets/forestry/textures/blocks/wood/planks.poplar.png b/forestry_resources/assets/forestry/textures/blocks/wood/planks.poplar.png new file mode 100755 index 000000000..eef180166 Binary files /dev/null and b/forestry_resources/assets/forestry/textures/blocks/wood/planks.poplar.png differ diff --git a/forestry_resources/assets/forestry/textures/blocks/wood/planks.sequoia.png b/forestry_resources/assets/forestry/textures/blocks/wood/planks.sequoia.png new file mode 100755 index 000000000..3363e6e0b Binary files /dev/null and b/forestry_resources/assets/forestry/textures/blocks/wood/planks.sequoia.png differ diff --git a/forestry_resources/assets/forestry/textures/blocks/wood/planks.teak.png b/forestry_resources/assets/forestry/textures/blocks/wood/planks.teak.png new file mode 100755 index 000000000..3f0719f02 Binary files /dev/null and b/forestry_resources/assets/forestry/textures/blocks/wood/planks.teak.png differ diff --git a/forestry_resources/assets/forestry/textures/blocks/wood/planks.walnut.png b/forestry_resources/assets/forestry/textures/blocks/wood/planks.walnut.png new file mode 100755 index 000000000..3c7741942 Binary files /dev/null and b/forestry_resources/assets/forestry/textures/blocks/wood/planks.walnut.png differ diff --git a/forestry_resources/assets/forestry/textures/blocks/wood/planks.wenge.png b/forestry_resources/assets/forestry/textures/blocks/wood/planks.wenge.png new file mode 100755 index 000000000..b2a2eb71b Binary files /dev/null and b/forestry_resources/assets/forestry/textures/blocks/wood/planks.wenge.png differ diff --git a/forestry_resources/assets/forestry/textures/blocks/wood/planks.willow.png b/forestry_resources/assets/forestry/textures/blocks/wood/planks.willow.png new file mode 100755 index 000000000..109ce46f2 Binary files /dev/null and b/forestry_resources/assets/forestry/textures/blocks/wood/planks.willow.png differ diff --git a/forestry_resources/assets/forestry/textures/blocks/wood/tile]-120.png b/forestry_resources/assets/forestry/textures/blocks/wood/tile]-120.png new file mode 100755 index 000000000..a19cf7bce Binary files /dev/null and b/forestry_resources/assets/forestry/textures/blocks/wood/tile]-120.png differ diff --git a/forestry_resources/assets/forestry/textures/blocks/wood/tile]-127.png b/forestry_resources/assets/forestry/textures/blocks/wood/tile]-127.png new file mode 100755 index 000000000..03f875dc4 Binary files /dev/null and b/forestry_resources/assets/forestry/textures/blocks/wood/tile]-127.png differ diff --git a/forestry_resources/assets/forestry/textures/blocks/wood/tile]-142.png b/forestry_resources/assets/forestry/textures/blocks/wood/tile]-142.png new file mode 100755 index 000000000..0ecd35838 Binary files /dev/null and b/forestry_resources/assets/forestry/textures/blocks/wood/tile]-142.png differ diff --git a/forestry_resources/assets/forestry/textures/blocks/wood/tile]-143.png b/forestry_resources/assets/forestry/textures/blocks/wood/tile]-143.png new file mode 100755 index 000000000..6ec69a47f Binary files /dev/null and b/forestry_resources/assets/forestry/textures/blocks/wood/tile]-143.png differ diff --git a/forestry_resources/assets/forestry/textures/blocks/wood/tile]-158.png b/forestry_resources/assets/forestry/textures/blocks/wood/tile]-158.png new file mode 100755 index 000000000..4e95d4894 Binary files /dev/null and b/forestry_resources/assets/forestry/textures/blocks/wood/tile]-158.png differ diff --git a/forestry_resources/assets/forestry/textures/blocks/wood/tile]-159.png b/forestry_resources/assets/forestry/textures/blocks/wood/tile]-159.png new file mode 100755 index 000000000..f8c824339 Binary files /dev/null and b/forestry_resources/assets/forestry/textures/blocks/wood/tile]-159.png differ diff --git a/forestry_resources/assets/forestry/textures/blocks/worktable.0.png b/forestry_resources/assets/forestry/textures/blocks/worktable.0.png new file mode 100755 index 000000000..d0f1b373e Binary files /dev/null and b/forestry_resources/assets/forestry/textures/blocks/worktable.0.png differ diff --git a/forestry_resources/assets/forestry/textures/blocks/worktable.1.png b/forestry_resources/assets/forestry/textures/blocks/worktable.1.png new file mode 100755 index 000000000..fdbcb2d5d Binary files /dev/null and b/forestry_resources/assets/forestry/textures/blocks/worktable.1.png differ diff --git a/forestry_resources/assets/forestry/textures/blocks/worktable.2.png b/forestry_resources/assets/forestry/textures/blocks/worktable.2.png new file mode 100755 index 000000000..9a49f125d Binary files /dev/null and b/forestry_resources/assets/forestry/textures/blocks/worktable.2.png differ diff --git a/forestry_resources/assets/forestry/textures/blocks/worktable.3.png b/forestry_resources/assets/forestry/textures/blocks/worktable.3.png new file mode 100755 index 000000000..d56c74565 Binary files /dev/null and b/forestry_resources/assets/forestry/textures/blocks/worktable.3.png differ diff --git a/forestry_resources/assets/forestry/textures/blocks/worktable.4.png b/forestry_resources/assets/forestry/textures/blocks/worktable.4.png new file mode 100755 index 000000000..5509ae76a Binary files /dev/null and b/forestry_resources/assets/forestry/textures/blocks/worktable.4.png differ diff --git a/forestry_resources/assets/forestry/textures/entity/beekeeper.png b/forestry_resources/assets/forestry/textures/entity/beekeeper.png new file mode 100755 index 000000000..71d72af98 Binary files /dev/null and b/forestry_resources/assets/forestry/textures/entity/beekeeper.png differ diff --git a/forestry_resources/assets/forestry/textures/entity/bees/endBee.png b/forestry_resources/assets/forestry/textures/entity/bees/endBee.png new file mode 100755 index 000000000..56a840c89 Binary files /dev/null and b/forestry_resources/assets/forestry/textures/entity/bees/endBee.png differ diff --git a/forestry_resources/assets/forestry/textures/entity/bees/honeyBee.png b/forestry_resources/assets/forestry/textures/entity/bees/honeyBee.png new file mode 100755 index 000000000..56b22c119 Binary files /dev/null and b/forestry_resources/assets/forestry/textures/entity/bees/honeyBee.png differ diff --git a/forestry_resources/assets/forestry/textures/entity/bees/icyBee.png b/forestry_resources/assets/forestry/textures/entity/bees/icyBee.png new file mode 100755 index 000000000..dc5c5a4b2 Binary files /dev/null and b/forestry_resources/assets/forestry/textures/entity/bees/icyBee.png differ diff --git a/forestry_resources/assets/forestry/textures/entity/bees/sinisterBee.png b/forestry_resources/assets/forestry/textures/entity/bees/sinisterBee.png new file mode 100755 index 000000000..2ed19dab1 Binary files /dev/null and b/forestry_resources/assets/forestry/textures/entity/bees/sinisterBee.png differ diff --git a/forestry_resources/assets/forestry/textures/entity/bees/tropicalBee.png b/forestry_resources/assets/forestry/textures/entity/bees/tropicalBee.png new file mode 100755 index 000000000..a27300cc3 Binary files /dev/null and b/forestry_resources/assets/forestry/textures/entity/bees/tropicalBee.png differ diff --git a/forestry_resources/assets/forestry/textures/entity/butterflies/lepiAurora.png b/forestry_resources/assets/forestry/textures/entity/butterflies/lepiAurora.png new file mode 100755 index 000000000..3259f1250 Binary files /dev/null and b/forestry_resources/assets/forestry/textures/entity/butterflies/lepiAurora.png differ diff --git a/forestry_resources/assets/forestry/textures/entity/butterflies/lepiBatesia.png b/forestry_resources/assets/forestry/textures/entity/butterflies/lepiBatesia.png new file mode 100755 index 000000000..e887ef66c Binary files /dev/null and b/forestry_resources/assets/forestry/textures/entity/butterflies/lepiBatesia.png differ diff --git a/forestry_resources/assets/forestry/textures/entity/butterflies/lepiBlackSwallow.png b/forestry_resources/assets/forestry/textures/entity/butterflies/lepiBlackSwallow.png new file mode 100755 index 000000000..65497b5be Binary files /dev/null and b/forestry_resources/assets/forestry/textures/entity/butterflies/lepiBlackSwallow.png differ diff --git a/forestry_resources/assets/forestry/textures/entity/butterflies/lepiBlueDuke.png b/forestry_resources/assets/forestry/textures/entity/butterflies/lepiBlueDuke.png new file mode 100755 index 000000000..5c4c406dd Binary files /dev/null and b/forestry_resources/assets/forestry/textures/entity/butterflies/lepiBlueDuke.png differ diff --git a/forestry_resources/assets/forestry/textures/entity/butterflies/lepiBlueWing.png b/forestry_resources/assets/forestry/textures/entity/butterflies/lepiBlueWing.png new file mode 100755 index 000000000..170802b5c Binary files /dev/null and b/forestry_resources/assets/forestry/textures/entity/butterflies/lepiBlueWing.png differ diff --git a/forestry_resources/assets/forestry/textures/entity/butterflies/lepiBrimstone.png b/forestry_resources/assets/forestry/textures/entity/butterflies/lepiBrimstone.png new file mode 100755 index 000000000..6ce67f580 Binary files /dev/null and b/forestry_resources/assets/forestry/textures/entity/butterflies/lepiBrimstone.png differ diff --git a/forestry_resources/assets/forestry/textures/entity/butterflies/lepiCSpeckledWood.png b/forestry_resources/assets/forestry/textures/entity/butterflies/lepiCSpeckledWood.png new file mode 100755 index 000000000..906afd2bb Binary files /dev/null and b/forestry_resources/assets/forestry/textures/entity/butterflies/lepiCSpeckledWood.png differ diff --git a/forestry_resources/assets/forestry/textures/entity/butterflies/lepiCabbageWhite.png b/forestry_resources/assets/forestry/textures/entity/butterflies/lepiCabbageWhite.png new file mode 100755 index 000000000..734ac52af Binary files /dev/null and b/forestry_resources/assets/forestry/textures/entity/butterflies/lepiCabbageWhite.png differ diff --git a/forestry_resources/assets/forestry/textures/entity/butterflies/lepiCitrusSwallow.png b/forestry_resources/assets/forestry/textures/entity/butterflies/lepiCitrusSwallow.png new file mode 100755 index 000000000..1bf904c60 Binary files /dev/null and b/forestry_resources/assets/forestry/textures/entity/butterflies/lepiCitrusSwallow.png differ diff --git a/forestry_resources/assets/forestry/textures/entity/butterflies/lepiComma.png b/forestry_resources/assets/forestry/textures/entity/butterflies/lepiComma.png new file mode 100755 index 000000000..bf9ffb271 Binary files /dev/null and b/forestry_resources/assets/forestry/textures/entity/butterflies/lepiComma.png differ diff --git a/forestry_resources/assets/forestry/textures/entity/butterflies/lepiDianaFrit.png b/forestry_resources/assets/forestry/textures/entity/butterflies/lepiDianaFrit.png new file mode 100755 index 000000000..05bd32683 Binary files /dev/null and b/forestry_resources/assets/forestry/textures/entity/butterflies/lepiDianaFrit.png differ diff --git a/forestry_resources/assets/forestry/textures/entity/butterflies/lepiEmeraldPeacock.png b/forestry_resources/assets/forestry/textures/entity/butterflies/lepiEmeraldPeacock.png new file mode 100755 index 000000000..574cc22d1 Binary files /dev/null and b/forestry_resources/assets/forestry/textures/entity/butterflies/lepiEmeraldPeacock.png differ diff --git a/forestry_resources/assets/forestry/textures/entity/butterflies/lepiGlasswing.png b/forestry_resources/assets/forestry/textures/entity/butterflies/lepiGlasswing.png new file mode 100755 index 000000000..97038c599 Binary files /dev/null and b/forestry_resources/assets/forestry/textures/entity/butterflies/lepiGlasswing.png differ diff --git a/forestry_resources/assets/forestry/textures/entity/butterflies/lepiGlassyTiger.png b/forestry_resources/assets/forestry/textures/entity/butterflies/lepiGlassyTiger.png new file mode 100755 index 000000000..724ae86c9 Binary files /dev/null and b/forestry_resources/assets/forestry/textures/entity/butterflies/lepiGlassyTiger.png differ diff --git a/forestry_resources/assets/forestry/textures/entity/butterflies/lepiGozoraAzure.png b/forestry_resources/assets/forestry/textures/entity/butterflies/lepiGozoraAzure.png new file mode 100755 index 000000000..208cfad44 Binary files /dev/null and b/forestry_resources/assets/forestry/textures/entity/butterflies/lepiGozoraAzure.png differ diff --git a/forestry_resources/assets/forestry/textures/entity/butterflies/lepiLLacewing.png b/forestry_resources/assets/forestry/textures/entity/butterflies/lepiLLacewing.png new file mode 100755 index 000000000..79c37d0d3 Binary files /dev/null and b/forestry_resources/assets/forestry/textures/entity/butterflies/lepiLLacewing.png differ diff --git a/forestry_resources/assets/forestry/textures/entity/butterflies/lepiMBlueMorpho.png b/forestry_resources/assets/forestry/textures/entity/butterflies/lepiMBlueMorpho.png new file mode 100755 index 000000000..251c50606 Binary files /dev/null and b/forestry_resources/assets/forestry/textures/entity/butterflies/lepiMBlueMorpho.png differ diff --git a/forestry_resources/assets/forestry/textures/entity/butterflies/lepiMSpeckledWood.png b/forestry_resources/assets/forestry/textures/entity/butterflies/lepiMSpeckledWood.png new file mode 100755 index 000000000..fbad6dc8a Binary files /dev/null and b/forestry_resources/assets/forestry/textures/entity/butterflies/lepiMSpeckledWood.png differ diff --git a/forestry_resources/assets/forestry/textures/entity/butterflies/lepiMalachite.png b/forestry_resources/assets/forestry/textures/entity/butterflies/lepiMalachite.png new file mode 100755 index 000000000..396d95959 Binary files /dev/null and b/forestry_resources/assets/forestry/textures/entity/butterflies/lepiMalachite.png differ diff --git a/forestry_resources/assets/forestry/textures/entity/butterflies/lepiMonarch.png b/forestry_resources/assets/forestry/textures/entity/butterflies/lepiMonarch.png new file mode 100755 index 000000000..61d5e5391 Binary files /dev/null and b/forestry_resources/assets/forestry/textures/entity/butterflies/lepiMonarch.png differ diff --git a/forestry_resources/assets/forestry/textures/entity/butterflies/lepiPBlueMorpho.png b/forestry_resources/assets/forestry/textures/entity/butterflies/lepiPBlueMorpho.png new file mode 100755 index 000000000..3ac7ab9ff Binary files /dev/null and b/forestry_resources/assets/forestry/textures/entity/butterflies/lepiPBlueMorpho.png differ diff --git a/forestry_resources/assets/forestry/textures/entity/butterflies/lepiPalaenoSulphur.png b/forestry_resources/assets/forestry/textures/entity/butterflies/lepiPalaenoSulphur.png new file mode 100755 index 000000000..e264b9ec8 Binary files /dev/null and b/forestry_resources/assets/forestry/textures/entity/butterflies/lepiPalaenoSulphur.png differ diff --git a/forestry_resources/assets/forestry/textures/entity/butterflies/lepiPostillion.png b/forestry_resources/assets/forestry/textures/entity/butterflies/lepiPostillion.png new file mode 100755 index 000000000..93321698b Binary files /dev/null and b/forestry_resources/assets/forestry/textures/entity/butterflies/lepiPostillion.png differ diff --git a/forestry_resources/assets/forestry/textures/entity/butterflies/lepiPostman.png b/forestry_resources/assets/forestry/textures/entity/butterflies/lepiPostman.png new file mode 100755 index 000000000..59468ebe3 Binary files /dev/null and b/forestry_resources/assets/forestry/textures/entity/butterflies/lepiPostman.png differ diff --git a/forestry_resources/assets/forestry/textures/entity/butterflies/lepiRBlueMorpho.png b/forestry_resources/assets/forestry/textures/entity/butterflies/lepiRBlueMorpho.png new file mode 100755 index 000000000..3e3490752 Binary files /dev/null and b/forestry_resources/assets/forestry/textures/entity/butterflies/lepiRBlueMorpho.png differ diff --git a/forestry_resources/assets/forestry/textures/entity/butterflies/lepiReseda.png b/forestry_resources/assets/forestry/textures/entity/butterflies/lepiReseda.png new file mode 100755 index 000000000..d0b0725c4 Binary files /dev/null and b/forestry_resources/assets/forestry/textures/entity/butterflies/lepiReseda.png differ diff --git a/forestry_resources/assets/forestry/textures/entity/butterflies/lepiSpeckledWood.png b/forestry_resources/assets/forestry/textures/entity/butterflies/lepiSpeckledWood.png new file mode 100755 index 000000000..4dd5ff98b Binary files /dev/null and b/forestry_resources/assets/forestry/textures/entity/butterflies/lepiSpeckledWood.png differ diff --git a/forestry_resources/assets/forestry/textures/entity/butterflies/lepiSpicebush.png b/forestry_resources/assets/forestry/textures/entity/butterflies/lepiSpicebush.png new file mode 100755 index 000000000..b0f335fef Binary files /dev/null and b/forestry_resources/assets/forestry/textures/entity/butterflies/lepiSpicebush.png differ diff --git a/forestry_resources/assets/forestry/textures/entity/butterflies/lepiSpringAzure.png b/forestry_resources/assets/forestry/textures/entity/butterflies/lepiSpringAzure.png new file mode 100755 index 000000000..6c642d95d Binary files /dev/null and b/forestry_resources/assets/forestry/textures/entity/butterflies/lepiSpringAzure.png differ diff --git a/forestry_resources/assets/forestry/textures/entity/butterflies/lepiThoasSwallow.png b/forestry_resources/assets/forestry/textures/entity/butterflies/lepiThoasSwallow.png new file mode 100755 index 000000000..799ebb596 Binary files /dev/null and b/forestry_resources/assets/forestry/textures/entity/butterflies/lepiThoasSwallow.png differ diff --git a/forestry_resources/assets/forestry/textures/entity/butterflies/lepiZebraSwallow.png b/forestry_resources/assets/forestry/textures/entity/butterflies/lepiZebraSwallow.png new file mode 100755 index 000000000..5018a829f Binary files /dev/null and b/forestry_resources/assets/forestry/textures/entity/butterflies/lepiZebraSwallow.png differ diff --git a/forestry_resources/assets/forestry/textures/entity/butterflies/mothAtlas.png b/forestry_resources/assets/forestry/textures/entity/butterflies/mothAtlas.png new file mode 100755 index 000000000..3ab42e309 Binary files /dev/null and b/forestry_resources/assets/forestry/textures/entity/butterflies/mothAtlas.png differ diff --git a/forestry_resources/assets/forestry/textures/entity/butterflies/mothBrimstone.png b/forestry_resources/assets/forestry/textures/entity/butterflies/mothBrimstone.png new file mode 100755 index 000000000..0bdc9d286 Binary files /dev/null and b/forestry_resources/assets/forestry/textures/entity/butterflies/mothBrimstone.png differ diff --git a/forestry_resources/assets/forestry/textures/entity/butterflies/mothLatticedHeath.png b/forestry_resources/assets/forestry/textures/entity/butterflies/mothLatticedHeath.png new file mode 100755 index 000000000..91559a116 Binary files /dev/null and b/forestry_resources/assets/forestry/textures/entity/butterflies/mothLatticedHeath.png differ diff --git a/forestry_resources/assets/forestry/textures/entity/lumberjack.png b/forestry_resources/assets/forestry/textures/entity/lumberjack.png new file mode 100755 index 000000000..78d20015c Binary files /dev/null and b/forestry_resources/assets/forestry/textures/entity/lumberjack.png differ diff --git a/forestry_resources/assets/forestry/textures/gui/alveary.png b/forestry_resources/assets/forestry/textures/gui/alveary.png new file mode 100755 index 000000000..bf4cc7f19 Binary files /dev/null and b/forestry_resources/assets/forestry/textures/gui/alveary.png differ diff --git a/forestry_resources/assets/forestry/textures/gui/alyzer.png b/forestry_resources/assets/forestry/textures/gui/alyzer.png new file mode 100755 index 000000000..8107ee076 Binary files /dev/null and b/forestry_resources/assets/forestry/textures/gui/alyzer.png differ diff --git a/forestry_resources/assets/forestry/textures/gui/analyzer.png b/forestry_resources/assets/forestry/textures/gui/analyzer.png new file mode 100755 index 000000000..51e2f4bac Binary files /dev/null and b/forestry_resources/assets/forestry/textures/gui/analyzer.png differ diff --git a/forestry_resources/assets/forestry/textures/gui/apiaristinventory.png b/forestry_resources/assets/forestry/textures/gui/apiaristinventory.png new file mode 100755 index 000000000..4ce48a043 Binary files /dev/null and b/forestry_resources/assets/forestry/textures/gui/apiaristinventory.png differ diff --git a/forestry_resources/assets/forestry/textures/gui/apiary.png b/forestry_resources/assets/forestry/textures/gui/apiary.png new file mode 100755 index 000000000..5bb72d738 Binary files /dev/null and b/forestry_resources/assets/forestry/textures/gui/apiary.png differ diff --git a/forestry_resources/assets/forestry/textures/gui/atlas.png b/forestry_resources/assets/forestry/textures/gui/atlas.png new file mode 100755 index 000000000..c9c4a247d Binary files /dev/null and b/forestry_resources/assets/forestry/textures/gui/atlas.png differ diff --git a/forestry_resources/assets/forestry/textures/gui/backpack.png b/forestry_resources/assets/forestry/textures/gui/backpack.png new file mode 100755 index 000000000..4c071c2ea Binary files /dev/null and b/forestry_resources/assets/forestry/textures/gui/backpack.png differ diff --git a/forestry_resources/assets/forestry/textures/gui/backpackT2.png b/forestry_resources/assets/forestry/textures/gui/backpackT2.png new file mode 100755 index 000000000..1d0b2e498 Binary files /dev/null and b/forestry_resources/assets/forestry/textures/gui/backpackT2.png differ diff --git a/forestry_resources/assets/forestry/textures/gui/beealyzer.png b/forestry_resources/assets/forestry/textures/gui/beealyzer.png new file mode 100755 index 000000000..726c4c757 Binary files /dev/null and b/forestry_resources/assets/forestry/textures/gui/beealyzer.png differ diff --git a/forestry_resources/assets/forestry/textures/gui/bioengine.png b/forestry_resources/assets/forestry/textures/gui/bioengine.png new file mode 100755 index 000000000..da7815313 Binary files /dev/null and b/forestry_resources/assets/forestry/textures/gui/bioengine.png differ diff --git a/forestry_resources/assets/forestry/textures/gui/biomefinder.png b/forestry_resources/assets/forestry/textures/gui/biomefinder.png new file mode 100755 index 000000000..3173e576a Binary files /dev/null and b/forestry_resources/assets/forestry/textures/gui/biomefinder.png differ diff --git a/forestry_resources/assets/forestry/textures/gui/bottler.png b/forestry_resources/assets/forestry/textures/gui/bottler.png new file mode 100755 index 000000000..ad078c256 Binary files /dev/null and b/forestry_resources/assets/forestry/textures/gui/bottler.png differ diff --git a/forestry_resources/assets/forestry/textures/gui/buttons.png b/forestry_resources/assets/forestry/textures/gui/buttons.png new file mode 100755 index 000000000..fdf37925f Binary files /dev/null and b/forestry_resources/assets/forestry/textures/gui/buttons.png differ diff --git a/forestry_resources/assets/forestry/textures/gui/carpenter.png b/forestry_resources/assets/forestry/textures/gui/carpenter.png new file mode 100755 index 000000000..880fb2be2 Binary files /dev/null and b/forestry_resources/assets/forestry/textures/gui/carpenter.png differ diff --git a/forestry_resources/assets/forestry/textures/gui/centrifuge.png b/forestry_resources/assets/forestry/textures/gui/centrifuge.png new file mode 100755 index 000000000..1ef12aa60 Binary files /dev/null and b/forestry_resources/assets/forestry/textures/gui/centrifuge.png differ diff --git a/forestry_resources/assets/forestry/textures/gui/electricalengine.png b/forestry_resources/assets/forestry/textures/gui/electricalengine.png new file mode 100755 index 000000000..5d3fd758f Binary files /dev/null and b/forestry_resources/assets/forestry/textures/gui/electricalengine.png differ diff --git a/forestry_resources/assets/forestry/textures/gui/escritoire.png b/forestry_resources/assets/forestry/textures/gui/escritoire.png new file mode 100755 index 000000000..b33afb21d Binary files /dev/null and b/forestry_resources/assets/forestry/textures/gui/escritoire.png differ diff --git a/forestry_resources/assets/forestry/textures/gui/fabricator.png b/forestry_resources/assets/forestry/textures/gui/fabricator.png new file mode 100755 index 000000000..ab992c799 Binary files /dev/null and b/forestry_resources/assets/forestry/textures/gui/fabricator.png differ diff --git a/forestry_resources/assets/forestry/textures/gui/fermenter.png b/forestry_resources/assets/forestry/textures/gui/fermenter.png new file mode 100755 index 000000000..f2aafa388 Binary files /dev/null and b/forestry_resources/assets/forestry/textures/gui/fermenter.png differ diff --git a/forestry_resources/assets/forestry/textures/gui/generator.png b/forestry_resources/assets/forestry/textures/gui/generator.png new file mode 100755 index 000000000..313184078 Binary files /dev/null and b/forestry_resources/assets/forestry/textures/gui/generator.png differ diff --git a/forestry_resources/assets/forestry/textures/gui/hygroregulator.png b/forestry_resources/assets/forestry/textures/gui/hygroregulator.png new file mode 100755 index 000000000..1b421d12d Binary files /dev/null and b/forestry_resources/assets/forestry/textures/gui/hygroregulator.png differ diff --git a/forestry_resources/assets/forestry/textures/gui/imprinter.png b/forestry_resources/assets/forestry/textures/gui/imprinter.png new file mode 100755 index 000000000..e419f8069 Binary files /dev/null and b/forestry_resources/assets/forestry/textures/gui/imprinter.png differ diff --git a/forestry_resources/assets/forestry/textures/gui/infuser.png b/forestry_resources/assets/forestry/textures/gui/infuser.png new file mode 100755 index 000000000..28ce0183c Binary files /dev/null and b/forestry_resources/assets/forestry/textures/gui/infuser.png differ diff --git a/forestry_resources/assets/forestry/textures/gui/ledger.png b/forestry_resources/assets/forestry/textures/gui/ledger.png new file mode 100755 index 000000000..721ca8ba0 Binary files /dev/null and b/forestry_resources/assets/forestry/textures/gui/ledger.png differ diff --git a/forestry_resources/assets/forestry/textures/gui/letter.png b/forestry_resources/assets/forestry/textures/gui/letter.png new file mode 100755 index 000000000..bd4441b3d Binary files /dev/null and b/forestry_resources/assets/forestry/textures/gui/letter.png differ diff --git a/forestry_resources/assets/forestry/textures/gui/mailalert.png b/forestry_resources/assets/forestry/textures/gui/mailalert.png new file mode 100755 index 000000000..f9c2caf3c Binary files /dev/null and b/forestry_resources/assets/forestry/textures/gui/mailalert.png differ diff --git a/forestry_resources/assets/forestry/textures/gui/mailbox.png b/forestry_resources/assets/forestry/textures/gui/mailbox.png new file mode 100755 index 000000000..3fc8b3bc3 Binary files /dev/null and b/forestry_resources/assets/forestry/textures/gui/mailbox.png differ diff --git a/forestry_resources/assets/forestry/textures/gui/mailtrader.png b/forestry_resources/assets/forestry/textures/gui/mailtrader.png new file mode 100755 index 000000000..534268b95 Binary files /dev/null and b/forestry_resources/assets/forestry/textures/gui/mailtrader.png differ diff --git a/forestry_resources/assets/forestry/textures/gui/mfarm.png b/forestry_resources/assets/forestry/textures/gui/mfarm.png new file mode 100755 index 000000000..af640b5df Binary files /dev/null and b/forestry_resources/assets/forestry/textures/gui/mfarm.png differ diff --git a/forestry_resources/assets/forestry/textures/gui/moistener.png b/forestry_resources/assets/forestry/textures/gui/moistener.png new file mode 100755 index 000000000..7d222a15a Binary files /dev/null and b/forestry_resources/assets/forestry/textures/gui/moistener.png differ diff --git a/forestry_resources/assets/forestry/textures/gui/peatengine.png b/forestry_resources/assets/forestry/textures/gui/peatengine.png new file mode 100755 index 000000000..a6a319a73 Binary files /dev/null and b/forestry_resources/assets/forestry/textures/gui/peatengine.png differ diff --git a/forestry_resources/assets/forestry/textures/gui/philatelist.png b/forestry_resources/assets/forestry/textures/gui/philatelist.png new file mode 100755 index 000000000..dd7a9df0c Binary files /dev/null and b/forestry_resources/assets/forestry/textures/gui/philatelist.png differ diff --git a/forestry_resources/assets/forestry/textures/gui/raintank.png b/forestry_resources/assets/forestry/textures/gui/raintank.png new file mode 100755 index 000000000..d31a1c881 Binary files /dev/null and b/forestry_resources/assets/forestry/textures/gui/raintank.png differ diff --git a/forestry_resources/assets/forestry/textures/gui/sieve.png b/forestry_resources/assets/forestry/textures/gui/sieve.png new file mode 100755 index 000000000..e05677ed9 Binary files /dev/null and b/forestry_resources/assets/forestry/textures/gui/sieve.png differ diff --git a/forestry_resources/assets/forestry/textures/gui/solder.png b/forestry_resources/assets/forestry/textures/gui/solder.png new file mode 100755 index 000000000..4eb44cac0 Binary files /dev/null and b/forestry_resources/assets/forestry/textures/gui/solder.png differ diff --git a/forestry_resources/assets/forestry/textures/gui/squeezer.png b/forestry_resources/assets/forestry/textures/gui/squeezer.png new file mode 100755 index 000000000..3021bdffe Binary files /dev/null and b/forestry_resources/assets/forestry/textures/gui/squeezer.png differ diff --git a/forestry_resources/assets/forestry/textures/gui/still.png b/forestry_resources/assets/forestry/textures/gui/still.png new file mode 100755 index 000000000..66bc10122 Binary files /dev/null and b/forestry_resources/assets/forestry/textures/gui/still.png differ diff --git a/forestry_resources/assets/forestry/textures/gui/swarmer.png b/forestry_resources/assets/forestry/textures/gui/swarmer.png new file mode 100755 index 000000000..d5d54cf19 Binary files /dev/null and b/forestry_resources/assets/forestry/textures/gui/swarmer.png differ diff --git a/forestry_resources/assets/forestry/textures/gui/tradername.png b/forestry_resources/assets/forestry/textures/gui/tradername.png new file mode 100755 index 000000000..fa57454fc Binary files /dev/null and b/forestry_resources/assets/forestry/textures/gui/tradername.png differ diff --git a/forestry_resources/assets/forestry/textures/gui/worktable.png b/forestry_resources/assets/forestry/textures/gui/worktable.png new file mode 100755 index 000000000..dd59d8ff0 Binary files /dev/null and b/forestry_resources/assets/forestry/textures/gui/worktable.png differ diff --git a/forestry_resources/assets/forestry/textures/items/ambrosia.png b/forestry_resources/assets/forestry/textures/items/ambrosia.png new file mode 100755 index 000000000..e2b84fde3 Binary files /dev/null and b/forestry_resources/assets/forestry/textures/items/ambrosia.png differ diff --git a/forestry_resources/assets/forestry/textures/items/analyzer/anything.png b/forestry_resources/assets/forestry/textures/items/analyzer/anything.png new file mode 100755 index 000000000..d91d29a41 Binary files /dev/null and b/forestry_resources/assets/forestry/textures/items/analyzer/anything.png differ diff --git a/forestry_resources/assets/forestry/textures/items/analyzer/bee.png b/forestry_resources/assets/forestry/textures/items/analyzer/bee.png new file mode 100755 index 000000000..839915061 Binary files /dev/null and b/forestry_resources/assets/forestry/textures/items/analyzer/bee.png differ diff --git a/forestry_resources/assets/forestry/textures/items/analyzer/cave.png b/forestry_resources/assets/forestry/textures/items/analyzer/cave.png new file mode 100755 index 000000000..1fca561d8 Binary files /dev/null and b/forestry_resources/assets/forestry/textures/items/analyzer/cave.png differ diff --git a/forestry_resources/assets/forestry/textures/items/analyzer/closed.png b/forestry_resources/assets/forestry/textures/items/analyzer/closed.png new file mode 100755 index 000000000..35dcaa0d9 Binary files /dev/null and b/forestry_resources/assets/forestry/textures/items/analyzer/closed.png differ diff --git a/forestry_resources/assets/forestry/textures/items/analyzer/drone.png b/forestry_resources/assets/forestry/textures/items/analyzer/drone.png new file mode 100755 index 000000000..260f8417d Binary files /dev/null and b/forestry_resources/assets/forestry/textures/items/analyzer/drone.png differ diff --git a/forestry_resources/assets/forestry/textures/items/analyzer/flyer.png b/forestry_resources/assets/forestry/textures/items/analyzer/flyer.png new file mode 100755 index 000000000..7732b6207 Binary files /dev/null and b/forestry_resources/assets/forestry/textures/items/analyzer/flyer.png differ diff --git a/forestry_resources/assets/forestry/textures/items/analyzer/item.png b/forestry_resources/assets/forestry/textures/items/analyzer/item.png new file mode 100755 index 000000000..be126e646 Binary files /dev/null and b/forestry_resources/assets/forestry/textures/items/analyzer/item.png differ diff --git a/forestry_resources/assets/forestry/textures/items/analyzer/nocturnal.png b/forestry_resources/assets/forestry/textures/items/analyzer/nocturnal.png new file mode 100755 index 000000000..b8228fee6 Binary files /dev/null and b/forestry_resources/assets/forestry/textures/items/analyzer/nocturnal.png differ diff --git a/forestry_resources/assets/forestry/textures/items/analyzer/princess.png b/forestry_resources/assets/forestry/textures/items/analyzer/princess.png new file mode 100755 index 000000000..1bea47783 Binary files /dev/null and b/forestry_resources/assets/forestry/textures/items/analyzer/princess.png differ diff --git a/forestry_resources/assets/forestry/textures/items/analyzer/pure_breed.png b/forestry_resources/assets/forestry/textures/items/analyzer/pure_breed.png new file mode 100755 index 000000000..64118a9e2 Binary files /dev/null and b/forestry_resources/assets/forestry/textures/items/analyzer/pure_breed.png differ diff --git a/forestry_resources/assets/forestry/textures/items/analyzer/pure_cave.png b/forestry_resources/assets/forestry/textures/items/analyzer/pure_cave.png new file mode 100755 index 000000000..12e7e38cb Binary files /dev/null and b/forestry_resources/assets/forestry/textures/items/analyzer/pure_cave.png differ diff --git a/forestry_resources/assets/forestry/textures/items/analyzer/pure_flyer.png b/forestry_resources/assets/forestry/textures/items/analyzer/pure_flyer.png new file mode 100755 index 000000000..0f96a478a Binary files /dev/null and b/forestry_resources/assets/forestry/textures/items/analyzer/pure_flyer.png differ diff --git a/forestry_resources/assets/forestry/textures/items/analyzer/pure_nocturnal.png b/forestry_resources/assets/forestry/textures/items/analyzer/pure_nocturnal.png new file mode 100755 index 000000000..297225ef2 Binary files /dev/null and b/forestry_resources/assets/forestry/textures/items/analyzer/pure_nocturnal.png differ diff --git a/forestry_resources/assets/forestry/textures/items/analyzer/queen.png b/forestry_resources/assets/forestry/textures/items/analyzer/queen.png new file mode 100755 index 000000000..4b0ace511 Binary files /dev/null and b/forestry_resources/assets/forestry/textures/items/analyzer/queen.png differ diff --git a/forestry_resources/assets/forestry/textures/items/apatite.png b/forestry_resources/assets/forestry/textures/items/apatite.png new file mode 100755 index 000000000..0271bf8f9 Binary files /dev/null and b/forestry_resources/assets/forestry/textures/items/apatite.png differ diff --git a/forestry_resources/assets/forestry/textures/items/apiaristBoots.png b/forestry_resources/assets/forestry/textures/items/apiaristBoots.png new file mode 100755 index 000000000..b0c6dd792 Binary files /dev/null and b/forestry_resources/assets/forestry/textures/items/apiaristBoots.png differ diff --git a/forestry_resources/assets/forestry/textures/items/apiaristChest.png b/forestry_resources/assets/forestry/textures/items/apiaristChest.png new file mode 100755 index 000000000..03af3fd88 Binary files /dev/null and b/forestry_resources/assets/forestry/textures/items/apiaristChest.png differ diff --git a/forestry_resources/assets/forestry/textures/items/apiaristHelmet.png b/forestry_resources/assets/forestry/textures/items/apiaristHelmet.png new file mode 100755 index 000000000..06d538d5c Binary files /dev/null and b/forestry_resources/assets/forestry/textures/items/apiaristHelmet.png differ diff --git a/forestry_resources/assets/forestry/textures/items/apiaristLegs.png b/forestry_resources/assets/forestry/textures/items/apiaristLegs.png new file mode 100755 index 000000000..eaa9c6760 Binary files /dev/null and b/forestry_resources/assets/forestry/textures/items/apiaristLegs.png differ diff --git a/forestry_resources/assets/forestry/textures/items/apiarist_armor_1.png b/forestry_resources/assets/forestry/textures/items/apiarist_armor_1.png new file mode 100755 index 000000000..44acd5221 Binary files /dev/null and b/forestry_resources/assets/forestry/textures/items/apiarist_armor_1.png differ diff --git a/forestry_resources/assets/forestry/textures/items/apiarist_armor_2.png b/forestry_resources/assets/forestry/textures/items/apiarist_armor_2.png new file mode 100755 index 000000000..43ce12a6f Binary files /dev/null and b/forestry_resources/assets/forestry/textures/items/apiarist_armor_2.png differ diff --git a/forestry_resources/assets/forestry/textures/items/ash.png b/forestry_resources/assets/forestry/textures/items/ash.png new file mode 100755 index 000000000..a6daf7baf Binary files /dev/null and b/forestry_resources/assets/forestry/textures/items/ash.png differ diff --git a/forestry_resources/assets/forestry/textures/items/backpacks/locked.png b/forestry_resources/assets/forestry/textures/items/backpacks/locked.png new file mode 100755 index 000000000..3bb8f80f0 Binary files /dev/null and b/forestry_resources/assets/forestry/textures/items/backpacks/locked.png differ diff --git a/forestry_resources/assets/forestry/textures/items/backpacks/neutral.png b/forestry_resources/assets/forestry/textures/items/backpacks/neutral.png new file mode 100755 index 000000000..6443635d6 Binary files /dev/null and b/forestry_resources/assets/forestry/textures/items/backpacks/neutral.png differ diff --git a/forestry_resources/assets/forestry/textures/items/backpacks/receive.png b/forestry_resources/assets/forestry/textures/items/backpacks/receive.png new file mode 100755 index 000000000..c12a90451 Binary files /dev/null and b/forestry_resources/assets/forestry/textures/items/backpacks/receive.png differ diff --git a/forestry_resources/assets/forestry/textures/items/backpacks/resupply.png b/forestry_resources/assets/forestry/textures/items/backpacks/resupply.png new file mode 100755 index 000000000..4f33154cc Binary files /dev/null and b/forestry_resources/assets/forestry/textures/items/backpacks/resupply.png differ diff --git a/forestry_resources/assets/forestry/textures/items/backpacks/t1.cloth.png b/forestry_resources/assets/forestry/textures/items/backpacks/t1.cloth.png new file mode 100755 index 000000000..c179ef3ea Binary files /dev/null and b/forestry_resources/assets/forestry/textures/items/backpacks/t1.cloth.png differ diff --git a/forestry_resources/assets/forestry/textures/items/backpacks/t1.outline.png b/forestry_resources/assets/forestry/textures/items/backpacks/t1.outline.png new file mode 100755 index 000000000..18ffa69eb Binary files /dev/null and b/forestry_resources/assets/forestry/textures/items/backpacks/t1.outline.png differ diff --git a/forestry_resources/assets/forestry/textures/items/backpacks/t2.cloth.png b/forestry_resources/assets/forestry/textures/items/backpacks/t2.cloth.png new file mode 100755 index 000000000..c179ef3ea Binary files /dev/null and b/forestry_resources/assets/forestry/textures/items/backpacks/t2.cloth.png differ diff --git a/forestry_resources/assets/forestry/textures/items/backpacks/t2.outline.png b/forestry_resources/assets/forestry/textures/items/backpacks/t2.outline.png new file mode 100755 index 000000000..c617d3967 Binary files /dev/null and b/forestry_resources/assets/forestry/textures/items/backpacks/t2.outline.png differ diff --git a/forestry_resources/assets/forestry/textures/items/beeCombs.0.png b/forestry_resources/assets/forestry/textures/items/beeCombs.0.png new file mode 100755 index 000000000..9f3a69aeb Binary files /dev/null and b/forestry_resources/assets/forestry/textures/items/beeCombs.0.png differ diff --git a/forestry_resources/assets/forestry/textures/items/beeCombs.1.png b/forestry_resources/assets/forestry/textures/items/beeCombs.1.png new file mode 100755 index 000000000..95147bb12 Binary files /dev/null and b/forestry_resources/assets/forestry/textures/items/beeCombs.1.png differ diff --git a/forestry_resources/assets/forestry/textures/items/beealyzer.png b/forestry_resources/assets/forestry/textures/items/beealyzer.png new file mode 100755 index 000000000..5e1240029 Binary files /dev/null and b/forestry_resources/assets/forestry/textures/items/beealyzer.png differ diff --git a/forestry_resources/assets/forestry/textures/items/bees/default/body1.png b/forestry_resources/assets/forestry/textures/items/bees/default/body1.png new file mode 100755 index 000000000..a400d7c9d Binary files /dev/null and b/forestry_resources/assets/forestry/textures/items/bees/default/body1.png differ diff --git a/forestry_resources/assets/forestry/textures/items/bees/default/drone.body2.png b/forestry_resources/assets/forestry/textures/items/bees/default/drone.body2.png new file mode 100755 index 000000000..bf43cf611 Binary files /dev/null and b/forestry_resources/assets/forestry/textures/items/bees/default/drone.body2.png differ diff --git a/forestry_resources/assets/forestry/textures/items/bees/default/drone.body2.png.mcmeta b/forestry_resources/assets/forestry/textures/items/bees/default/drone.body2.png.mcmeta new file mode 100755 index 000000000..0e1c12b68 --- /dev/null +++ b/forestry_resources/assets/forestry/textures/items/bees/default/drone.body2.png.mcmeta @@ -0,0 +1 @@ +{"animation":{"width":1,"height":5,"frametime":1,"frames":[{"index":0,"time":64},{"index":1,"time":2},{"index":2,"time":2},{"index":1,"time":2},{"index":0,"time":96},{"index":3,"time":4},{"index":0,"time":128},{"index":4,"time":2}]}} \ No newline at end of file diff --git a/forestry_resources/assets/forestry/textures/items/bees/default/drone.body2.txt b/forestry_resources/assets/forestry/textures/items/bees/default/drone.body2.txt new file mode 100755 index 000000000..1ec941484 --- /dev/null +++ b/forestry_resources/assets/forestry/textures/items/bees/default/drone.body2.txt @@ -0,0 +1,8 @@ +0*64 +1*2 +2*2 +1*2 +0*96 +3*4 +0*128 +4*2 diff --git a/forestry_resources/assets/forestry/textures/items/bees/default/drone.outline.png b/forestry_resources/assets/forestry/textures/items/bees/default/drone.outline.png new file mode 100755 index 000000000..494920b75 Binary files /dev/null and b/forestry_resources/assets/forestry/textures/items/bees/default/drone.outline.png differ diff --git a/forestry_resources/assets/forestry/textures/items/bees/default/drone.outline.png.mcmeta b/forestry_resources/assets/forestry/textures/items/bees/default/drone.outline.png.mcmeta new file mode 100755 index 000000000..0e1c12b68 --- /dev/null +++ b/forestry_resources/assets/forestry/textures/items/bees/default/drone.outline.png.mcmeta @@ -0,0 +1 @@ +{"animation":{"width":1,"height":5,"frametime":1,"frames":[{"index":0,"time":64},{"index":1,"time":2},{"index":2,"time":2},{"index":1,"time":2},{"index":0,"time":96},{"index":3,"time":4},{"index":0,"time":128},{"index":4,"time":2}]}} \ No newline at end of file diff --git a/forestry_resources/assets/forestry/textures/items/bees/default/drone.outline.txt b/forestry_resources/assets/forestry/textures/items/bees/default/drone.outline.txt new file mode 100755 index 000000000..1ec941484 --- /dev/null +++ b/forestry_resources/assets/forestry/textures/items/bees/default/drone.outline.txt @@ -0,0 +1,8 @@ +0*64 +1*2 +2*2 +1*2 +0*96 +3*4 +0*128 +4*2 diff --git a/forestry_resources/assets/forestry/textures/items/bees/default/larvae.body.png b/forestry_resources/assets/forestry/textures/items/bees/default/larvae.body.png new file mode 100755 index 000000000..0f63aaf51 Binary files /dev/null and b/forestry_resources/assets/forestry/textures/items/bees/default/larvae.body.png differ diff --git a/forestry_resources/assets/forestry/textures/items/bees/default/larvae.body.png.mcmeta b/forestry_resources/assets/forestry/textures/items/bees/default/larvae.body.png.mcmeta new file mode 100755 index 000000000..952d5f222 --- /dev/null +++ b/forestry_resources/assets/forestry/textures/items/bees/default/larvae.body.png.mcmeta @@ -0,0 +1 @@ +{"animation":{"width":1,"height":2,"frametime":1,"frames":[{"index":0,"time":64},{"index":1,"time":2},{"index":0,"time":48},{"index":1,"time":2}]}} \ No newline at end of file diff --git a/forestry_resources/assets/forestry/textures/items/bees/default/larvae.body.txt b/forestry_resources/assets/forestry/textures/items/bees/default/larvae.body.txt new file mode 100755 index 000000000..c3822c62c --- /dev/null +++ b/forestry_resources/assets/forestry/textures/items/bees/default/larvae.body.txt @@ -0,0 +1,5 @@ +0*64 +1*2 +0*48 +1*2 + diff --git a/forestry_resources/assets/forestry/textures/items/bees/default/larvae.body2.png b/forestry_resources/assets/forestry/textures/items/bees/default/larvae.body2.png new file mode 100755 index 000000000..a50272330 Binary files /dev/null and b/forestry_resources/assets/forestry/textures/items/bees/default/larvae.body2.png differ diff --git a/forestry_resources/assets/forestry/textures/items/bees/default/larvae.body2.png.mcmeta b/forestry_resources/assets/forestry/textures/items/bees/default/larvae.body2.png.mcmeta new file mode 100755 index 000000000..952d5f222 --- /dev/null +++ b/forestry_resources/assets/forestry/textures/items/bees/default/larvae.body2.png.mcmeta @@ -0,0 +1 @@ +{"animation":{"width":1,"height":2,"frametime":1,"frames":[{"index":0,"time":64},{"index":1,"time":2},{"index":0,"time":48},{"index":1,"time":2}]}} \ No newline at end of file diff --git a/forestry_resources/assets/forestry/textures/items/bees/default/larvae.body2.txt b/forestry_resources/assets/forestry/textures/items/bees/default/larvae.body2.txt new file mode 100755 index 000000000..c3822c62c --- /dev/null +++ b/forestry_resources/assets/forestry/textures/items/bees/default/larvae.body2.txt @@ -0,0 +1,5 @@ +0*64 +1*2 +0*48 +1*2 + diff --git a/forestry_resources/assets/forestry/textures/items/bees/default/larvae.outline.png b/forestry_resources/assets/forestry/textures/items/bees/default/larvae.outline.png new file mode 100755 index 000000000..44430b19e Binary files /dev/null and b/forestry_resources/assets/forestry/textures/items/bees/default/larvae.outline.png differ diff --git a/forestry_resources/assets/forestry/textures/items/bees/default/larvae.outline.png.mcmeta b/forestry_resources/assets/forestry/textures/items/bees/default/larvae.outline.png.mcmeta new file mode 100755 index 000000000..952d5f222 --- /dev/null +++ b/forestry_resources/assets/forestry/textures/items/bees/default/larvae.outline.png.mcmeta @@ -0,0 +1 @@ +{"animation":{"width":1,"height":2,"frametime":1,"frames":[{"index":0,"time":64},{"index":1,"time":2},{"index":0,"time":48},{"index":1,"time":2}]}} \ No newline at end of file diff --git a/forestry_resources/assets/forestry/textures/items/bees/default/larvae.outline.txt b/forestry_resources/assets/forestry/textures/items/bees/default/larvae.outline.txt new file mode 100755 index 000000000..c3822c62c --- /dev/null +++ b/forestry_resources/assets/forestry/textures/items/bees/default/larvae.outline.txt @@ -0,0 +1,5 @@ +0*64 +1*2 +0*48 +1*2 + diff --git a/forestry_resources/assets/forestry/textures/items/bees/default/princess.body2.png b/forestry_resources/assets/forestry/textures/items/bees/default/princess.body2.png new file mode 100755 index 000000000..d23d00bb8 Binary files /dev/null and b/forestry_resources/assets/forestry/textures/items/bees/default/princess.body2.png differ diff --git a/forestry_resources/assets/forestry/textures/items/bees/default/princess.body2.png.mcmeta b/forestry_resources/assets/forestry/textures/items/bees/default/princess.body2.png.mcmeta new file mode 100755 index 000000000..66c135896 --- /dev/null +++ b/forestry_resources/assets/forestry/textures/items/bees/default/princess.body2.png.mcmeta @@ -0,0 +1 @@ +{"animation":{"width":1,"height":5,"frametime":1,"frames":[{"index":0,"time":128},{"index":3,"time":4},{"index":0,"time":96},{"index":1,"time":2},{"index":2,"time":2},{"index":1,"time":2},{"index":0,"time":64},{"index":4,"time":2}]}} \ No newline at end of file diff --git a/forestry_resources/assets/forestry/textures/items/bees/default/princess.body2.txt b/forestry_resources/assets/forestry/textures/items/bees/default/princess.body2.txt new file mode 100755 index 000000000..91fce38b1 --- /dev/null +++ b/forestry_resources/assets/forestry/textures/items/bees/default/princess.body2.txt @@ -0,0 +1,8 @@ +0*128 +3*4 +0*96 +1*2 +2*2 +1*2 +0*64 +4*2 diff --git a/forestry_resources/assets/forestry/textures/items/bees/default/princess.outline.png b/forestry_resources/assets/forestry/textures/items/bees/default/princess.outline.png new file mode 100755 index 000000000..494920b75 Binary files /dev/null and b/forestry_resources/assets/forestry/textures/items/bees/default/princess.outline.png differ diff --git a/forestry_resources/assets/forestry/textures/items/bees/default/princess.outline.png.mcmeta b/forestry_resources/assets/forestry/textures/items/bees/default/princess.outline.png.mcmeta new file mode 100755 index 000000000..66c135896 --- /dev/null +++ b/forestry_resources/assets/forestry/textures/items/bees/default/princess.outline.png.mcmeta @@ -0,0 +1 @@ +{"animation":{"width":1,"height":5,"frametime":1,"frames":[{"index":0,"time":128},{"index":3,"time":4},{"index":0,"time":96},{"index":1,"time":2},{"index":2,"time":2},{"index":1,"time":2},{"index":0,"time":64},{"index":4,"time":2}]}} \ No newline at end of file diff --git a/forestry_resources/assets/forestry/textures/items/bees/default/princess.outline.txt b/forestry_resources/assets/forestry/textures/items/bees/default/princess.outline.txt new file mode 100755 index 000000000..91fce38b1 --- /dev/null +++ b/forestry_resources/assets/forestry/textures/items/bees/default/princess.outline.txt @@ -0,0 +1,8 @@ +0*128 +3*4 +0*96 +1*2 +2*2 +1*2 +0*64 +4*2 diff --git a/forestry_resources/assets/forestry/textures/items/bees/default/queen.body2.png b/forestry_resources/assets/forestry/textures/items/bees/default/queen.body2.png new file mode 100755 index 000000000..2cf8292d4 Binary files /dev/null and b/forestry_resources/assets/forestry/textures/items/bees/default/queen.body2.png differ diff --git a/forestry_resources/assets/forestry/textures/items/bees/default/queen.body2.png.mcmeta b/forestry_resources/assets/forestry/textures/items/bees/default/queen.body2.png.mcmeta new file mode 100755 index 000000000..ec8d8cac2 --- /dev/null +++ b/forestry_resources/assets/forestry/textures/items/bees/default/queen.body2.png.mcmeta @@ -0,0 +1 @@ +{"animation":{"width":1,"height":5,"frametime":1,"frames":[{"index":0,"time":96},{"index":3,"time":4},{"index":0,"time":64},{"index":4,"time":2},{"index":0,"time":128},{"index":1,"time":2},{"index":2,"time":2},{"index":1,"time":2}]}} \ No newline at end of file diff --git a/forestry_resources/assets/forestry/textures/items/bees/default/queen.body2.txt b/forestry_resources/assets/forestry/textures/items/bees/default/queen.body2.txt new file mode 100755 index 000000000..f873d1c37 --- /dev/null +++ b/forestry_resources/assets/forestry/textures/items/bees/default/queen.body2.txt @@ -0,0 +1,8 @@ +0*96 +3*4 +0*64 +4*2 +0*128 +1*2 +2*2 +1*2 diff --git a/forestry_resources/assets/forestry/textures/items/bees/default/queen.outline.png b/forestry_resources/assets/forestry/textures/items/bees/default/queen.outline.png new file mode 100755 index 000000000..494920b75 Binary files /dev/null and b/forestry_resources/assets/forestry/textures/items/bees/default/queen.outline.png differ diff --git a/forestry_resources/assets/forestry/textures/items/bees/default/queen.outline.png.mcmeta b/forestry_resources/assets/forestry/textures/items/bees/default/queen.outline.png.mcmeta new file mode 100755 index 000000000..ec8d8cac2 --- /dev/null +++ b/forestry_resources/assets/forestry/textures/items/bees/default/queen.outline.png.mcmeta @@ -0,0 +1 @@ +{"animation":{"width":1,"height":5,"frametime":1,"frames":[{"index":0,"time":96},{"index":3,"time":4},{"index":0,"time":64},{"index":4,"time":2},{"index":0,"time":128},{"index":1,"time":2},{"index":2,"time":2},{"index":1,"time":2}]}} \ No newline at end of file diff --git a/forestry_resources/assets/forestry/textures/items/bees/default/queen.outline.txt b/forestry_resources/assets/forestry/textures/items/bees/default/queen.outline.txt new file mode 100755 index 000000000..f873d1c37 --- /dev/null +++ b/forestry_resources/assets/forestry/textures/items/bees/default/queen.outline.txt @@ -0,0 +1,8 @@ +0*96 +3*4 +0*64 +4*2 +0*128 +1*2 +2*2 +1*2 diff --git a/forestry_resources/assets/forestry/textures/items/beeswax.png b/forestry_resources/assets/forestry/textures/items/beeswax.png new file mode 100755 index 000000000..6d8a4070b Binary files /dev/null and b/forestry_resources/assets/forestry/textures/items/beeswax.png differ diff --git a/forestry_resources/assets/forestry/textures/items/bioMass.png b/forestry_resources/assets/forestry/textures/items/bioMass.png new file mode 100755 index 000000000..2448b346d Binary files /dev/null and b/forestry_resources/assets/forestry/textures/items/bioMass.png differ diff --git a/forestry_resources/assets/forestry/textures/items/biomefinder.mcmeta b/forestry_resources/assets/forestry/textures/items/biomefinder.mcmeta new file mode 100755 index 000000000..de7ddb4ff --- /dev/null +++ b/forestry_resources/assets/forestry/textures/items/biomefinder.mcmeta @@ -0,0 +1 @@ +{"animation":{"width":1,"height":1,"frametime":1,"frames":[]}} \ No newline at end of file diff --git a/forestry_resources/assets/forestry/textures/items/biomefinder.png b/forestry_resources/assets/forestry/textures/items/biomefinder.png new file mode 100755 index 000000000..2b4122bdd Binary files /dev/null and b/forestry_resources/assets/forestry/textures/items/biomefinder.png differ diff --git a/forestry_resources/assets/forestry/textures/items/biomefinder.png.mcmeta b/forestry_resources/assets/forestry/textures/items/biomefinder.png.mcmeta new file mode 100755 index 000000000..de7ddb4ff --- /dev/null +++ b/forestry_resources/assets/forestry/textures/items/biomefinder.png.mcmeta @@ -0,0 +1 @@ +{"animation":{"width":1,"height":1,"frametime":1,"frames":[]}} \ No newline at end of file diff --git a/forestry_resources/assets/forestry/textures/items/biomefinder.txt b/forestry_resources/assets/forestry/textures/items/biomefinder.txt new file mode 100755 index 000000000..e69de29bb diff --git a/forestry_resources/assets/forestry/textures/items/biomefinder.txt.mcmeta b/forestry_resources/assets/forestry/textures/items/biomefinder.txt.mcmeta new file mode 100755 index 000000000..de7ddb4ff --- /dev/null +++ b/forestry_resources/assets/forestry/textures/items/biomefinder.txt.mcmeta @@ -0,0 +1 @@ +{"animation":{"width":1,"height":1,"frametime":1,"frames":[]}} \ No newline at end of file diff --git a/forestry_resources/assets/forestry/textures/items/bituminousPeat.png b/forestry_resources/assets/forestry/textures/items/bituminousPeat.png new file mode 100755 index 000000000..c821972af Binary files /dev/null and b/forestry_resources/assets/forestry/textures/items/bituminousPeat.png differ diff --git a/forestry_resources/assets/forestry/textures/items/brokenBronzePickaxe.png b/forestry_resources/assets/forestry/textures/items/brokenBronzePickaxe.png new file mode 100755 index 000000000..514193775 Binary files /dev/null and b/forestry_resources/assets/forestry/textures/items/brokenBronzePickaxe.png differ diff --git a/forestry_resources/assets/forestry/textures/items/brokenBronzeShovel.png b/forestry_resources/assets/forestry/textures/items/brokenBronzeShovel.png new file mode 100755 index 000000000..a77017331 Binary files /dev/null and b/forestry_resources/assets/forestry/textures/items/brokenBronzeShovel.png differ diff --git a/forestry_resources/assets/forestry/textures/items/bronzePickaxe.png b/forestry_resources/assets/forestry/textures/items/bronzePickaxe.png new file mode 100755 index 000000000..889879a36 Binary files /dev/null and b/forestry_resources/assets/forestry/textures/items/bronzePickaxe.png differ diff --git a/forestry_resources/assets/forestry/textures/items/bronzeShovel.png b/forestry_resources/assets/forestry/textures/items/bronzeShovel.png new file mode 100755 index 000000000..5ea56189b Binary files /dev/null and b/forestry_resources/assets/forestry/textures/items/bronzeShovel.png differ diff --git a/forestry_resources/assets/forestry/textures/items/bucketBiofuel.png b/forestry_resources/assets/forestry/textures/items/bucketBiofuel.png new file mode 100755 index 000000000..41d60b5a8 Binary files /dev/null and b/forestry_resources/assets/forestry/textures/items/bucketBiofuel.png differ diff --git a/forestry_resources/assets/forestry/textures/items/bucketBiomass.png b/forestry_resources/assets/forestry/textures/items/bucketBiomass.png new file mode 100755 index 000000000..52c1e61bc Binary files /dev/null and b/forestry_resources/assets/forestry/textures/items/bucketBiomass.png differ diff --git a/forestry_resources/assets/forestry/textures/items/carton.png b/forestry_resources/assets/forestry/textures/items/carton.png new file mode 100755 index 000000000..8e047a8a4 Binary files /dev/null and b/forestry_resources/assets/forestry/textures/items/carton.png differ diff --git a/forestry_resources/assets/forestry/textures/items/catalogue.png b/forestry_resources/assets/forestry/textures/items/catalogue.png new file mode 100755 index 000000000..2a414a180 Binary files /dev/null and b/forestry_resources/assets/forestry/textures/items/catalogue.png differ diff --git a/forestry_resources/assets/forestry/textures/items/caterpillar.body.mcmeta b/forestry_resources/assets/forestry/textures/items/caterpillar.body.mcmeta new file mode 100755 index 000000000..312732717 --- /dev/null +++ b/forestry_resources/assets/forestry/textures/items/caterpillar.body.mcmeta @@ -0,0 +1 @@ +{"animation":{"width":1,"height":2,"frametime":1,"frames":[{"index":0,"time"7},{"index":1,"time"3},{"index":0,"time"9},{"index":1,"time"2},{"index":0,"time"5},{"index":1,"time"2}]}} \ No newline at end of file diff --git a/forestry_resources/assets/forestry/textures/items/caterpillar.body.png b/forestry_resources/assets/forestry/textures/items/caterpillar.body.png new file mode 100755 index 000000000..97f60de63 Binary files /dev/null and b/forestry_resources/assets/forestry/textures/items/caterpillar.body.png differ diff --git a/forestry_resources/assets/forestry/textures/items/caterpillar.body.png.mcmeta b/forestry_resources/assets/forestry/textures/items/caterpillar.body.png.mcmeta new file mode 100755 index 000000000..3e353516f --- /dev/null +++ b/forestry_resources/assets/forestry/textures/items/caterpillar.body.png.mcmeta @@ -0,0 +1 @@ +{"animation":{"width":1,"height":2,"frametime":1,"frames":[{"index":0,"time":7},{"index":1,"time":3},{"index":0,"time":9},{"index":1,"time":2},{"index":0,"time":5},{"index":1,"time":2}]}} \ No newline at end of file diff --git a/forestry_resources/assets/forestry/textures/items/caterpillar.body.txt b/forestry_resources/assets/forestry/textures/items/caterpillar.body.txt new file mode 100755 index 000000000..1f70057f9 --- /dev/null +++ b/forestry_resources/assets/forestry/textures/items/caterpillar.body.txt @@ -0,0 +1,6 @@ +0*7 +1*3 +0*9 +1*2 +0*5 +1*2 \ No newline at end of file diff --git a/forestry_resources/assets/forestry/textures/items/caterpillar.body.txt.mcmeta b/forestry_resources/assets/forestry/textures/items/caterpillar.body.txt.mcmeta new file mode 100755 index 000000000..312732717 --- /dev/null +++ b/forestry_resources/assets/forestry/textures/items/caterpillar.body.txt.mcmeta @@ -0,0 +1 @@ +{"animation":{"width":1,"height":2,"frametime":1,"frames":[{"index":0,"time"7},{"index":1,"time"3},{"index":0,"time"9},{"index":1,"time"2},{"index":0,"time"5},{"index":1,"time"2}]}} \ No newline at end of file diff --git a/forestry_resources/assets/forestry/textures/items/caterpillar.body2.mcmeta b/forestry_resources/assets/forestry/textures/items/caterpillar.body2.mcmeta new file mode 100755 index 000000000..312732717 --- /dev/null +++ b/forestry_resources/assets/forestry/textures/items/caterpillar.body2.mcmeta @@ -0,0 +1 @@ +{"animation":{"width":1,"height":2,"frametime":1,"frames":[{"index":0,"time"7},{"index":1,"time"3},{"index":0,"time"9},{"index":1,"time"2},{"index":0,"time"5},{"index":1,"time"2}]}} \ No newline at end of file diff --git a/forestry_resources/assets/forestry/textures/items/caterpillar.body2.png b/forestry_resources/assets/forestry/textures/items/caterpillar.body2.png new file mode 100755 index 000000000..8e6f90aa8 Binary files /dev/null and b/forestry_resources/assets/forestry/textures/items/caterpillar.body2.png differ diff --git a/forestry_resources/assets/forestry/textures/items/caterpillar.body2.png.mcmeta b/forestry_resources/assets/forestry/textures/items/caterpillar.body2.png.mcmeta new file mode 100755 index 000000000..3e353516f --- /dev/null +++ b/forestry_resources/assets/forestry/textures/items/caterpillar.body2.png.mcmeta @@ -0,0 +1 @@ +{"animation":{"width":1,"height":2,"frametime":1,"frames":[{"index":0,"time":7},{"index":1,"time":3},{"index":0,"time":9},{"index":1,"time":2},{"index":0,"time":5},{"index":1,"time":2}]}} \ No newline at end of file diff --git a/forestry_resources/assets/forestry/textures/items/caterpillar.body2.txt b/forestry_resources/assets/forestry/textures/items/caterpillar.body2.txt new file mode 100755 index 000000000..1f70057f9 --- /dev/null +++ b/forestry_resources/assets/forestry/textures/items/caterpillar.body2.txt @@ -0,0 +1,6 @@ +0*7 +1*3 +0*9 +1*2 +0*5 +1*2 \ No newline at end of file diff --git a/forestry_resources/assets/forestry/textures/items/caterpillar.body2.txt.mcmeta b/forestry_resources/assets/forestry/textures/items/caterpillar.body2.txt.mcmeta new file mode 100755 index 000000000..312732717 --- /dev/null +++ b/forestry_resources/assets/forestry/textures/items/caterpillar.body2.txt.mcmeta @@ -0,0 +1 @@ +{"animation":{"width":1,"height":2,"frametime":1,"frames":[{"index":0,"time"7},{"index":1,"time"3},{"index":0,"time"9},{"index":1,"time"2},{"index":0,"time"5},{"index":1,"time"2}]}} \ No newline at end of file diff --git a/forestry_resources/assets/forestry/textures/items/chipsets.0.png b/forestry_resources/assets/forestry/textures/items/chipsets.0.png new file mode 100755 index 000000000..6ae93b3af Binary files /dev/null and b/forestry_resources/assets/forestry/textures/items/chipsets.0.png differ diff --git a/forestry_resources/assets/forestry/textures/items/chipsets.1.png b/forestry_resources/assets/forestry/textures/items/chipsets.1.png new file mode 100755 index 000000000..98d7ed2f6 Binary files /dev/null and b/forestry_resources/assets/forestry/textures/items/chipsets.1.png differ diff --git a/forestry_resources/assets/forestry/textures/items/crate.png b/forestry_resources/assets/forestry/textures/items/crate.png new file mode 100755 index 000000000..a128c000e Binary files /dev/null and b/forestry_resources/assets/forestry/textures/items/crate.png differ diff --git a/forestry_resources/assets/forestry/textures/items/crates/apatite.png b/forestry_resources/assets/forestry/textures/items/crates/apatite.png new file mode 100755 index 000000000..ba88d4ffe Binary files /dev/null and b/forestry_resources/assets/forestry/textures/items/crates/apatite.png differ diff --git a/forestry_resources/assets/forestry/textures/items/crates/apples.png b/forestry_resources/assets/forestry/textures/items/crates/apples.png new file mode 100755 index 000000000..41d47c763 Binary files /dev/null and b/forestry_resources/assets/forestry/textures/items/crates/apples.png differ diff --git a/forestry_resources/assets/forestry/textures/items/crates/ash.png b/forestry_resources/assets/forestry/textures/items/crates/ash.png new file mode 100755 index 000000000..c2d0c215d Binary files /dev/null and b/forestry_resources/assets/forestry/textures/items/crates/ash.png differ diff --git a/forestry_resources/assets/forestry/textures/items/crates/beeswax.png b/forestry_resources/assets/forestry/textures/items/crates/beeswax.png new file mode 100755 index 000000000..80ce6eeb1 Binary files /dev/null and b/forestry_resources/assets/forestry/textures/items/crates/beeswax.png differ diff --git a/forestry_resources/assets/forestry/textures/items/crates/bogearth.png b/forestry_resources/assets/forestry/textures/items/crates/bogearth.png new file mode 100755 index 000000000..cf51e0919 Binary files /dev/null and b/forestry_resources/assets/forestry/textures/items/crates/bogearth.png differ diff --git a/forestry_resources/assets/forestry/textures/items/crates/brass.png b/forestry_resources/assets/forestry/textures/items/crates/brass.png new file mode 100755 index 000000000..478a5eafd Binary files /dev/null and b/forestry_resources/assets/forestry/textures/items/crates/brass.png differ diff --git a/forestry_resources/assets/forestry/textures/items/crates/brick.png b/forestry_resources/assets/forestry/textures/items/crates/brick.png new file mode 100755 index 000000000..65c3553bd Binary files /dev/null and b/forestry_resources/assets/forestry/textures/items/crates/brick.png differ diff --git a/forestry_resources/assets/forestry/textures/items/crates/bronze.png b/forestry_resources/assets/forestry/textures/items/crates/bronze.png new file mode 100755 index 000000000..7132813e4 Binary files /dev/null and b/forestry_resources/assets/forestry/textures/items/crates/bronze.png differ diff --git a/forestry_resources/assets/forestry/textures/items/crates/cacti.png b/forestry_resources/assets/forestry/textures/items/crates/cacti.png new file mode 100755 index 000000000..9214a36d7 Binary files /dev/null and b/forestry_resources/assets/forestry/textures/items/crates/cacti.png differ diff --git a/forestry_resources/assets/forestry/textures/items/crates/charcoal.png b/forestry_resources/assets/forestry/textures/items/crates/charcoal.png new file mode 100755 index 000000000..c1ad81ca5 Binary files /dev/null and b/forestry_resources/assets/forestry/textures/items/crates/charcoal.png differ diff --git a/forestry_resources/assets/forestry/textures/items/crates/clay.png b/forestry_resources/assets/forestry/textures/items/crates/clay.png new file mode 100755 index 000000000..d8385fb7e Binary files /dev/null and b/forestry_resources/assets/forestry/textures/items/crates/clay.png differ diff --git a/forestry_resources/assets/forestry/textures/items/crates/coal.png b/forestry_resources/assets/forestry/textures/items/crates/coal.png new file mode 100755 index 000000000..c1ad81ca5 Binary files /dev/null and b/forestry_resources/assets/forestry/textures/items/crates/coal.png differ diff --git a/forestry_resources/assets/forestry/textures/items/crates/cobblestone.png b/forestry_resources/assets/forestry/textures/items/crates/cobblestone.png new file mode 100755 index 000000000..b4886b481 Binary files /dev/null and b/forestry_resources/assets/forestry/textures/items/crates/cobblestone.png differ diff --git a/forestry_resources/assets/forestry/textures/items/crates/cocoacomb.png b/forestry_resources/assets/forestry/textures/items/crates/cocoacomb.png new file mode 100755 index 000000000..1778d1c13 Binary files /dev/null and b/forestry_resources/assets/forestry/textures/items/crates/cocoacomb.png differ diff --git a/forestry_resources/assets/forestry/textures/items/crates/cookies.png b/forestry_resources/assets/forestry/textures/items/crates/cookies.png new file mode 100755 index 000000000..e0c3418c8 Binary files /dev/null and b/forestry_resources/assets/forestry/textures/items/crates/cookies.png differ diff --git a/forestry_resources/assets/forestry/textures/items/crates/copper.png b/forestry_resources/assets/forestry/textures/items/crates/copper.png new file mode 100755 index 000000000..39c0ac44d Binary files /dev/null and b/forestry_resources/assets/forestry/textures/items/crates/copper.png differ diff --git a/forestry_resources/assets/forestry/textures/items/crates/dirt.png b/forestry_resources/assets/forestry/textures/items/crates/dirt.png new file mode 100755 index 000000000..654403cae Binary files /dev/null and b/forestry_resources/assets/forestry/textures/items/crates/dirt.png differ diff --git a/forestry_resources/assets/forestry/textures/items/crates/drippingcombs.png b/forestry_resources/assets/forestry/textures/items/crates/drippingcombs.png new file mode 100755 index 000000000..56c8ae5cf Binary files /dev/null and b/forestry_resources/assets/forestry/textures/items/crates/drippingcombs.png differ diff --git a/forestry_resources/assets/forestry/textures/items/crates/fertilizer.png b/forestry_resources/assets/forestry/textures/items/crates/fertilizer.png new file mode 100755 index 000000000..5b40a22d8 Binary files /dev/null and b/forestry_resources/assets/forestry/textures/items/crates/fertilizer.png differ diff --git a/forestry_resources/assets/forestry/textures/items/crates/frozencombs.png b/forestry_resources/assets/forestry/textures/items/crates/frozencombs.png new file mode 100755 index 000000000..862f13573 Binary files /dev/null and b/forestry_resources/assets/forestry/textures/items/crates/frozencombs.png differ diff --git a/forestry_resources/assets/forestry/textures/items/crates/glowstone.png b/forestry_resources/assets/forestry/textures/items/crates/glowstone.png new file mode 100755 index 000000000..9ce23c1dd Binary files /dev/null and b/forestry_resources/assets/forestry/textures/items/crates/glowstone.png differ diff --git a/forestry_resources/assets/forestry/textures/items/crates/gravel.png b/forestry_resources/assets/forestry/textures/items/crates/gravel.png new file mode 100755 index 000000000..c9544c6f0 Binary files /dev/null and b/forestry_resources/assets/forestry/textures/items/crates/gravel.png differ diff --git a/forestry_resources/assets/forestry/textures/items/crates/honeycombs.png b/forestry_resources/assets/forestry/textures/items/crates/honeycombs.png new file mode 100755 index 000000000..d3a7a79d3 Binary files /dev/null and b/forestry_resources/assets/forestry/textures/items/crates/honeycombs.png differ diff --git a/forestry_resources/assets/forestry/textures/items/crates/honeydew.png b/forestry_resources/assets/forestry/textures/items/crates/honeydew.png new file mode 100755 index 000000000..3b33fa444 Binary files /dev/null and b/forestry_resources/assets/forestry/textures/items/crates/honeydew.png differ diff --git a/forestry_resources/assets/forestry/textures/items/crates/honeydrop.png b/forestry_resources/assets/forestry/textures/items/crates/honeydrop.png new file mode 100755 index 000000000..5b1982267 Binary files /dev/null and b/forestry_resources/assets/forestry/textures/items/crates/honeydrop.png differ diff --git a/forestry_resources/assets/forestry/textures/items/crates/humus.png b/forestry_resources/assets/forestry/textures/items/crates/humus.png new file mode 100755 index 000000000..7505bb06b Binary files /dev/null and b/forestry_resources/assets/forestry/textures/items/crates/humus.png differ diff --git a/forestry_resources/assets/forestry/textures/items/crates/iron.png b/forestry_resources/assets/forestry/textures/items/crates/iron.png new file mode 100755 index 000000000..436296eaf Binary files /dev/null and b/forestry_resources/assets/forestry/textures/items/crates/iron.png differ diff --git a/forestry_resources/assets/forestry/textures/items/crates/lapis.png b/forestry_resources/assets/forestry/textures/items/crates/lapis.png new file mode 100755 index 000000000..e8196c42f Binary files /dev/null and b/forestry_resources/assets/forestry/textures/items/crates/lapis.png differ diff --git a/forestry_resources/assets/forestry/textures/items/crates/mulch.png b/forestry_resources/assets/forestry/textures/items/crates/mulch.png new file mode 100755 index 000000000..8483579b6 Binary files /dev/null and b/forestry_resources/assets/forestry/textures/items/crates/mulch.png differ diff --git a/forestry_resources/assets/forestry/textures/items/crates/mycelium.png b/forestry_resources/assets/forestry/textures/items/crates/mycelium.png new file mode 100755 index 000000000..b5fd982d9 Binary files /dev/null and b/forestry_resources/assets/forestry/textures/items/crates/mycelium.png differ diff --git a/forestry_resources/assets/forestry/textures/items/crates/netherbrick.png b/forestry_resources/assets/forestry/textures/items/crates/netherbrick.png new file mode 100755 index 000000000..a330ec97e Binary files /dev/null and b/forestry_resources/assets/forestry/textures/items/crates/netherbrick.png differ diff --git a/forestry_resources/assets/forestry/textures/items/crates/netherrack.png b/forestry_resources/assets/forestry/textures/items/crates/netherrack.png new file mode 100755 index 000000000..abccdde16 Binary files /dev/null and b/forestry_resources/assets/forestry/textures/items/crates/netherrack.png differ diff --git a/forestry_resources/assets/forestry/textures/items/crates/netherwart.png b/forestry_resources/assets/forestry/textures/items/crates/netherwart.png new file mode 100755 index 000000000..eaff8a777 Binary files /dev/null and b/forestry_resources/assets/forestry/textures/items/crates/netherwart.png differ diff --git a/forestry_resources/assets/forestry/textures/items/crates/nikolite.png b/forestry_resources/assets/forestry/textures/items/crates/nikolite.png new file mode 100755 index 000000000..bb23c4c6f Binary files /dev/null and b/forestry_resources/assets/forestry/textures/items/crates/nikolite.png differ diff --git a/forestry_resources/assets/forestry/textures/items/crates/obsidian.png b/forestry_resources/assets/forestry/textures/items/crates/obsidian.png new file mode 100755 index 000000000..8505ddde7 Binary files /dev/null and b/forestry_resources/assets/forestry/textures/items/crates/obsidian.png differ diff --git a/forestry_resources/assets/forestry/textures/items/crates/peat.png b/forestry_resources/assets/forestry/textures/items/crates/peat.png new file mode 100755 index 000000000..579133265 Binary files /dev/null and b/forestry_resources/assets/forestry/textures/items/crates/peat.png differ diff --git a/forestry_resources/assets/forestry/textures/items/crates/phosphor.png b/forestry_resources/assets/forestry/textures/items/crates/phosphor.png new file mode 100755 index 000000000..ebdfd4b99 Binary files /dev/null and b/forestry_resources/assets/forestry/textures/items/crates/phosphor.png differ diff --git a/forestry_resources/assets/forestry/textures/items/crates/pollen.png b/forestry_resources/assets/forestry/textures/items/crates/pollen.png new file mode 100755 index 000000000..4e11ec8e4 Binary files /dev/null and b/forestry_resources/assets/forestry/textures/items/crates/pollen.png differ diff --git a/forestry_resources/assets/forestry/textures/items/crates/propolis.png b/forestry_resources/assets/forestry/textures/items/crates/propolis.png new file mode 100755 index 000000000..53971e4da Binary files /dev/null and b/forestry_resources/assets/forestry/textures/items/crates/propolis.png differ diff --git a/forestry_resources/assets/forestry/textures/items/crates/redstone.png b/forestry_resources/assets/forestry/textures/items/crates/redstone.png new file mode 100755 index 000000000..6d00a4b47 Binary files /dev/null and b/forestry_resources/assets/forestry/textures/items/crates/redstone.png differ diff --git a/forestry_resources/assets/forestry/textures/items/crates/reeds.png b/forestry_resources/assets/forestry/textures/items/crates/reeds.png new file mode 100755 index 000000000..f013d93f0 Binary files /dev/null and b/forestry_resources/assets/forestry/textures/items/crates/reeds.png differ diff --git a/forestry_resources/assets/forestry/textures/items/crates/refractorywax.png b/forestry_resources/assets/forestry/textures/items/crates/refractorywax.png new file mode 100755 index 000000000..9736cf4bb Binary files /dev/null and b/forestry_resources/assets/forestry/textures/items/crates/refractorywax.png differ diff --git a/forestry_resources/assets/forestry/textures/items/crates/resin.png b/forestry_resources/assets/forestry/textures/items/crates/resin.png new file mode 100755 index 000000000..3560a527b Binary files /dev/null and b/forestry_resources/assets/forestry/textures/items/crates/resin.png differ diff --git a/forestry_resources/assets/forestry/textures/items/crates/rubber.png b/forestry_resources/assets/forestry/textures/items/crates/rubber.png new file mode 100755 index 000000000..77d5f4be7 Binary files /dev/null and b/forestry_resources/assets/forestry/textures/items/crates/rubber.png differ diff --git a/forestry_resources/assets/forestry/textures/items/crates/sand.png b/forestry_resources/assets/forestry/textures/items/crates/sand.png new file mode 100755 index 000000000..6d9d344c2 Binary files /dev/null and b/forestry_resources/assets/forestry/textures/items/crates/sand.png differ diff --git a/forestry_resources/assets/forestry/textures/items/crates/sandstone.png b/forestry_resources/assets/forestry/textures/items/crates/sandstone.png new file mode 100755 index 000000000..f318ce53f Binary files /dev/null and b/forestry_resources/assets/forestry/textures/items/crates/sandstone.png differ diff --git a/forestry_resources/assets/forestry/textures/items/crates/saplings.png b/forestry_resources/assets/forestry/textures/items/crates/saplings.png new file mode 100755 index 000000000..58caa9acf Binary files /dev/null and b/forestry_resources/assets/forestry/textures/items/crates/saplings.png differ diff --git a/forestry_resources/assets/forestry/textures/items/crates/scrap.png b/forestry_resources/assets/forestry/textures/items/crates/scrap.png new file mode 100755 index 000000000..06d3b3041 Binary files /dev/null and b/forestry_resources/assets/forestry/textures/items/crates/scrap.png differ diff --git a/forestry_resources/assets/forestry/textures/items/crates/seeds.png b/forestry_resources/assets/forestry/textures/items/crates/seeds.png new file mode 100755 index 000000000..a03c4932f Binary files /dev/null and b/forestry_resources/assets/forestry/textures/items/crates/seeds.png differ diff --git a/forestry_resources/assets/forestry/textures/items/crates/simmeringcombs.png b/forestry_resources/assets/forestry/textures/items/crates/simmeringcombs.png new file mode 100755 index 000000000..615ed9399 Binary files /dev/null and b/forestry_resources/assets/forestry/textures/items/crates/simmeringcombs.png differ diff --git a/forestry_resources/assets/forestry/textures/items/crates/soulsand.png b/forestry_resources/assets/forestry/textures/items/crates/soulsand.png new file mode 100755 index 000000000..1496527d9 Binary files /dev/null and b/forestry_resources/assets/forestry/textures/items/crates/soulsand.png differ diff --git a/forestry_resources/assets/forestry/textures/items/crates/stone.png b/forestry_resources/assets/forestry/textures/items/crates/stone.png new file mode 100755 index 000000000..80e7f2c54 Binary files /dev/null and b/forestry_resources/assets/forestry/textures/items/crates/stone.png differ diff --git a/forestry_resources/assets/forestry/textures/items/crates/stringycombs.png b/forestry_resources/assets/forestry/textures/items/crates/stringycombs.png new file mode 100755 index 000000000..8e7e2b1a0 Binary files /dev/null and b/forestry_resources/assets/forestry/textures/items/crates/stringycombs.png differ diff --git a/forestry_resources/assets/forestry/textures/items/crates/tile]-16.png b/forestry_resources/assets/forestry/textures/items/crates/tile]-16.png new file mode 100755 index 000000000..b348a8687 Binary files /dev/null and b/forestry_resources/assets/forestry/textures/items/crates/tile]-16.png differ diff --git a/forestry_resources/assets/forestry/textures/items/crates/tin.png b/forestry_resources/assets/forestry/textures/items/crates/tin.png new file mode 100755 index 000000000..3e6b4af13 Binary files /dev/null and b/forestry_resources/assets/forestry/textures/items/crates/tin.png differ diff --git a/forestry_resources/assets/forestry/textures/items/crates/uum.png b/forestry_resources/assets/forestry/textures/items/crates/uum.png new file mode 100755 index 000000000..9763affcc Binary files /dev/null and b/forestry_resources/assets/forestry/textures/items/crates/uum.png differ diff --git a/forestry_resources/assets/forestry/textures/items/crates/wheat.png b/forestry_resources/assets/forestry/textures/items/crates/wheat.png new file mode 100755 index 000000000..eb4cbec77 Binary files /dev/null and b/forestry_resources/assets/forestry/textures/items/crates/wheat.png differ diff --git a/forestry_resources/assets/forestry/textures/items/crates/wood.png b/forestry_resources/assets/forestry/textures/items/crates/wood.png new file mode 100755 index 000000000..d13957f3d Binary files /dev/null and b/forestry_resources/assets/forestry/textures/items/crates/wood.png differ diff --git a/forestry_resources/assets/forestry/textures/items/decayingWheat.png b/forestry_resources/assets/forestry/textures/items/decayingWheat.png new file mode 100755 index 000000000..ae49bef1c Binary files /dev/null and b/forestry_resources/assets/forestry/textures/items/decayingWheat.png differ diff --git a/forestry_resources/assets/forestry/textures/items/dissipationCharge.png b/forestry_resources/assets/forestry/textures/items/dissipationCharge.png new file mode 100755 index 000000000..f666c7f5f Binary files /dev/null and b/forestry_resources/assets/forestry/textures/items/dissipationCharge.png differ diff --git a/forestry_resources/assets/forestry/textures/items/errors/circuitMismatch.png b/forestry_resources/assets/forestry/textures/items/errors/circuitMismatch.png new file mode 100755 index 000000000..c23ecaf89 Binary files /dev/null and b/forestry_resources/assets/forestry/textures/items/errors/circuitMismatch.png differ diff --git a/forestry_resources/assets/forestry/textures/items/errors/errored.png b/forestry_resources/assets/forestry/textures/items/errors/errored.png new file mode 100755 index 000000000..adf97e310 Binary files /dev/null and b/forestry_resources/assets/forestry/textures/items/errors/errored.png differ diff --git a/forestry_resources/assets/forestry/textures/items/errors/forcedCooldown.png b/forestry_resources/assets/forestry/textures/items/errors/forcedCooldown.png new file mode 100755 index 000000000..3765df977 Binary files /dev/null and b/forestry_resources/assets/forestry/textures/items/errors/forcedCooldown.png differ diff --git a/forestry_resources/assets/forestry/textures/items/errors/invalidBiome.png b/forestry_resources/assets/forestry/textures/items/errors/invalidBiome.png new file mode 100755 index 000000000..cf5659568 Binary files /dev/null and b/forestry_resources/assets/forestry/textures/items/errors/invalidBiome.png differ diff --git a/forestry_resources/assets/forestry/textures/items/errors/isRaining.png b/forestry_resources/assets/forestry/textures/items/errors/isRaining.png new file mode 100755 index 000000000..e09e737d1 Binary files /dev/null and b/forestry_resources/assets/forestry/textures/items/errors/isRaining.png differ diff --git a/forestry_resources/assets/forestry/textures/items/errors/noCircuitBoard.png b/forestry_resources/assets/forestry/textures/items/errors/noCircuitBoard.png new file mode 100755 index 000000000..d51a4fad0 Binary files /dev/null and b/forestry_resources/assets/forestry/textures/items/errors/noCircuitBoard.png differ diff --git a/forestry_resources/assets/forestry/textures/items/errors/noDisposal.png b/forestry_resources/assets/forestry/textures/items/errors/noDisposal.png new file mode 100755 index 000000000..2127d992a Binary files /dev/null and b/forestry_resources/assets/forestry/textures/items/errors/noDisposal.png differ diff --git a/forestry_resources/assets/forestry/textures/items/errors/noDrone.png b/forestry_resources/assets/forestry/textures/items/errors/noDrone.png new file mode 100755 index 000000000..70ca46c72 Binary files /dev/null and b/forestry_resources/assets/forestry/textures/items/errors/noDrone.png differ diff --git a/forestry_resources/assets/forestry/textures/items/errors/noEnergyNet.png b/forestry_resources/assets/forestry/textures/items/errors/noEnergyNet.png new file mode 100755 index 000000000..1ed8eacbb Binary files /dev/null and b/forestry_resources/assets/forestry/textures/items/errors/noEnergyNet.png differ diff --git a/forestry_resources/assets/forestry/textures/items/errors/noFarmland.png b/forestry_resources/assets/forestry/textures/items/errors/noFarmland.png new file mode 100755 index 000000000..ee8039fe5 Binary files /dev/null and b/forestry_resources/assets/forestry/textures/items/errors/noFarmland.png differ diff --git a/forestry_resources/assets/forestry/textures/items/errors/noFertilizer.png b/forestry_resources/assets/forestry/textures/items/errors/noFertilizer.png new file mode 100755 index 000000000..e4e9f1b8b Binary files /dev/null and b/forestry_resources/assets/forestry/textures/items/errors/noFertilizer.png differ diff --git a/forestry_resources/assets/forestry/textures/items/errors/noFlower.png b/forestry_resources/assets/forestry/textures/items/errors/noFlower.png new file mode 100755 index 000000000..c56f41308 Binary files /dev/null and b/forestry_resources/assets/forestry/textures/items/errors/noFlower.png differ diff --git a/forestry_resources/assets/forestry/textures/items/errors/noFuel.png b/forestry_resources/assets/forestry/textures/items/errors/noFuel.png new file mode 100755 index 000000000..e4e9f1b8b Binary files /dev/null and b/forestry_resources/assets/forestry/textures/items/errors/noFuel.png differ diff --git a/forestry_resources/assets/forestry/textures/items/errors/noHeat.png b/forestry_resources/assets/forestry/textures/items/errors/noHeat.png new file mode 100755 index 000000000..9e284468a Binary files /dev/null and b/forestry_resources/assets/forestry/textures/items/errors/noHeat.png differ diff --git a/forestry_resources/assets/forestry/textures/items/errors/noHoney.png b/forestry_resources/assets/forestry/textures/items/errors/noHoney.png new file mode 100755 index 000000000..8a3ff84cb Binary files /dev/null and b/forestry_resources/assets/forestry/textures/items/errors/noHoney.png differ diff --git a/forestry_resources/assets/forestry/textures/items/errors/noLiquid.png b/forestry_resources/assets/forestry/textures/items/errors/noLiquid.png new file mode 100755 index 000000000..7da1fd627 Binary files /dev/null and b/forestry_resources/assets/forestry/textures/items/errors/noLiquid.png differ diff --git a/forestry_resources/assets/forestry/textures/items/errors/noQueen.png b/forestry_resources/assets/forestry/textures/items/errors/noQueen.png new file mode 100755 index 000000000..7bceaf782 Binary files /dev/null and b/forestry_resources/assets/forestry/textures/items/errors/noQueen.png differ diff --git a/forestry_resources/assets/forestry/textures/items/errors/noRecipe.png b/forestry_resources/assets/forestry/textures/items/errors/noRecipe.png new file mode 100755 index 000000000..40be185dd Binary files /dev/null and b/forestry_resources/assets/forestry/textures/items/errors/noRecipe.png differ diff --git a/forestry_resources/assets/forestry/textures/items/errors/noRecipient.png b/forestry_resources/assets/forestry/textures/items/errors/noRecipient.png new file mode 100755 index 000000000..b4611f89c Binary files /dev/null and b/forestry_resources/assets/forestry/textures/items/errors/noRecipient.png differ diff --git a/forestry_resources/assets/forestry/textures/items/errors/noResource.png b/forestry_resources/assets/forestry/textures/items/errors/noResource.png new file mode 100755 index 000000000..bc6dca7be Binary files /dev/null and b/forestry_resources/assets/forestry/textures/items/errors/noResource.png differ diff --git a/forestry_resources/assets/forestry/textures/items/errors/noSky.png b/forestry_resources/assets/forestry/textures/items/errors/noSky.png new file mode 100755 index 000000000..5b731463f Binary files /dev/null and b/forestry_resources/assets/forestry/textures/items/errors/noSky.png differ diff --git a/forestry_resources/assets/forestry/textures/items/errors/noSpace.png b/forestry_resources/assets/forestry/textures/items/errors/noSpace.png new file mode 100755 index 000000000..f6a18e992 Binary files /dev/null and b/forestry_resources/assets/forestry/textures/items/errors/noSpace.png differ diff --git a/forestry_resources/assets/forestry/textures/items/errors/noSpecimen.png b/forestry_resources/assets/forestry/textures/items/errors/noSpecimen.png new file mode 100755 index 000000000..70ca46c72 Binary files /dev/null and b/forestry_resources/assets/forestry/textures/items/errors/noSpecimen.png differ diff --git a/forestry_resources/assets/forestry/textures/items/errors/noStamps.png b/forestry_resources/assets/forestry/textures/items/errors/noStamps.png new file mode 100755 index 000000000..2f373319d Binary files /dev/null and b/forestry_resources/assets/forestry/textures/items/errors/noStamps.png differ diff --git a/forestry_resources/assets/forestry/textures/items/errors/notAlphaNumeric.png b/forestry_resources/assets/forestry/textures/items/errors/notAlphaNumeric.png new file mode 100755 index 000000000..f58b38d7c Binary files /dev/null and b/forestry_resources/assets/forestry/textures/items/errors/notAlphaNumeric.png differ diff --git a/forestry_resources/assets/forestry/textures/items/errors/notDay.png b/forestry_resources/assets/forestry/textures/items/errors/notDay.png new file mode 100755 index 000000000..18507c0bb Binary files /dev/null and b/forestry_resources/assets/forestry/textures/items/errors/notDay.png differ diff --git a/forestry_resources/assets/forestry/textures/items/errors/notGloomy.png b/forestry_resources/assets/forestry/textures/items/errors/notGloomy.png new file mode 100755 index 000000000..ffc158fc5 Binary files /dev/null and b/forestry_resources/assets/forestry/textures/items/errors/notGloomy.png differ diff --git a/forestry_resources/assets/forestry/textures/items/errors/notLucid.png b/forestry_resources/assets/forestry/textures/items/errors/notLucid.png new file mode 100755 index 000000000..5b731463f Binary files /dev/null and b/forestry_resources/assets/forestry/textures/items/errors/notLucid.png differ diff --git a/forestry_resources/assets/forestry/textures/items/errors/notNight.png b/forestry_resources/assets/forestry/textures/items/errors/notNight.png new file mode 100755 index 000000000..bdb4730ed Binary files /dev/null and b/forestry_resources/assets/forestry/textures/items/errors/notNight.png differ diff --git a/forestry_resources/assets/forestry/textures/items/errors/notPostpaid.png b/forestry_resources/assets/forestry/textures/items/errors/notPostpaid.png new file mode 100755 index 000000000..2f373319d Binary files /dev/null and b/forestry_resources/assets/forestry/textures/items/errors/notPostpaid.png differ diff --git a/forestry_resources/assets/forestry/textures/items/errors/notRaining.png b/forestry_resources/assets/forestry/textures/items/errors/notRaining.png new file mode 100755 index 000000000..9a01ac304 Binary files /dev/null and b/forestry_resources/assets/forestry/textures/items/errors/notRaining.png differ diff --git a/forestry_resources/assets/forestry/textures/items/errors/notUnique.png b/forestry_resources/assets/forestry/textures/items/errors/notUnique.png new file mode 100755 index 000000000..c23ecaf89 Binary files /dev/null and b/forestry_resources/assets/forestry/textures/items/errors/notUnique.png differ diff --git a/forestry_resources/assets/forestry/textures/items/errors/ok.png b/forestry_resources/assets/forestry/textures/items/errors/ok.png new file mode 100755 index 000000000..01b160149 Binary files /dev/null and b/forestry_resources/assets/forestry/textures/items/errors/ok.png differ diff --git a/forestry_resources/assets/forestry/textures/items/errors/unknown.png b/forestry_resources/assets/forestry/textures/items/errors/unknown.png new file mode 100755 index 000000000..83551a001 Binary files /dev/null and b/forestry_resources/assets/forestry/textures/items/errors/unknown.png differ diff --git a/forestry_resources/assets/forestry/textures/items/errors/wrongStacksize.png b/forestry_resources/assets/forestry/textures/items/errors/wrongStacksize.png new file mode 100755 index 000000000..c23ecaf89 Binary files /dev/null and b/forestry_resources/assets/forestry/textures/items/errors/wrongStacksize.png differ diff --git a/forestry_resources/assets/forestry/textures/items/fertilizerBio.png b/forestry_resources/assets/forestry/textures/items/fertilizerBio.png new file mode 100755 index 000000000..f2471c84c Binary files /dev/null and b/forestry_resources/assets/forestry/textures/items/fertilizerBio.png differ diff --git a/forestry_resources/assets/forestry/textures/items/fertilizerCompound.png b/forestry_resources/assets/forestry/textures/items/fertilizerCompound.png new file mode 100755 index 000000000..77f34968a Binary files /dev/null and b/forestry_resources/assets/forestry/textures/items/fertilizerCompound.png differ diff --git a/forestry_resources/assets/forestry/textures/items/flutterlyzer.png b/forestry_resources/assets/forestry/textures/items/flutterlyzer.png new file mode 100755 index 000000000..1ab4ddf59 Binary files /dev/null and b/forestry_resources/assets/forestry/textures/items/flutterlyzer.png differ diff --git a/forestry_resources/assets/forestry/textures/items/frameImpregnated.png b/forestry_resources/assets/forestry/textures/items/frameImpregnated.png new file mode 100755 index 000000000..7e888ad51 Binary files /dev/null and b/forestry_resources/assets/forestry/textures/items/frameImpregnated.png differ diff --git a/forestry_resources/assets/forestry/textures/items/frameProven.png b/forestry_resources/assets/forestry/textures/items/frameProven.png new file mode 100755 index 000000000..8f4f5edea Binary files /dev/null and b/forestry_resources/assets/forestry/textures/items/frameProven.png differ diff --git a/forestry_resources/assets/forestry/textures/items/frameUntreated.png b/forestry_resources/assets/forestry/textures/items/frameUntreated.png new file mode 100755 index 000000000..f5360afbc Binary files /dev/null and b/forestry_resources/assets/forestry/textures/items/frameUntreated.png differ diff --git a/forestry_resources/assets/forestry/textures/items/fruits/cherry.png b/forestry_resources/assets/forestry/textures/items/fruits/cherry.png new file mode 100755 index 000000000..e95909732 Binary files /dev/null and b/forestry_resources/assets/forestry/textures/items/fruits/cherry.png differ diff --git a/forestry_resources/assets/forestry/textures/items/fruits/chestnut.png b/forestry_resources/assets/forestry/textures/items/fruits/chestnut.png new file mode 100755 index 000000000..b470e1bc8 Binary files /dev/null and b/forestry_resources/assets/forestry/textures/items/fruits/chestnut.png differ diff --git a/forestry_resources/assets/forestry/textures/items/fruits/dates.png b/forestry_resources/assets/forestry/textures/items/fruits/dates.png new file mode 100755 index 000000000..8a53c59ba Binary files /dev/null and b/forestry_resources/assets/forestry/textures/items/fruits/dates.png differ diff --git a/forestry_resources/assets/forestry/textures/items/fruits/lemon.png b/forestry_resources/assets/forestry/textures/items/fruits/lemon.png new file mode 100755 index 000000000..63d106ef2 Binary files /dev/null and b/forestry_resources/assets/forestry/textures/items/fruits/lemon.png differ diff --git a/forestry_resources/assets/forestry/textures/items/fruits/papaya.png b/forestry_resources/assets/forestry/textures/items/fruits/papaya.png new file mode 100755 index 000000000..50edde07b Binary files /dev/null and b/forestry_resources/assets/forestry/textures/items/fruits/papaya.png differ diff --git a/forestry_resources/assets/forestry/textures/items/fruits/plum.png b/forestry_resources/assets/forestry/textures/items/fruits/plum.png new file mode 100755 index 000000000..f10e572e4 Binary files /dev/null and b/forestry_resources/assets/forestry/textures/items/fruits/plum.png differ diff --git a/forestry_resources/assets/forestry/textures/items/fruits/walnut.png b/forestry_resources/assets/forestry/textures/items/fruits/walnut.png new file mode 100755 index 000000000..1ee1e02e2 Binary files /dev/null and b/forestry_resources/assets/forestry/textures/items/fruits/walnut.png differ diff --git a/forestry_resources/assets/forestry/textures/items/gearBronze.png b/forestry_resources/assets/forestry/textures/items/gearBronze.png new file mode 100755 index 000000000..adb151fbe Binary files /dev/null and b/forestry_resources/assets/forestry/textures/items/gearBronze.png differ diff --git a/forestry_resources/assets/forestry/textures/items/gearCopper.png b/forestry_resources/assets/forestry/textures/items/gearCopper.png new file mode 100755 index 000000000..b5e4e43fe Binary files /dev/null and b/forestry_resources/assets/forestry/textures/items/gearCopper.png differ diff --git a/forestry_resources/assets/forestry/textures/items/gearTin.png b/forestry_resources/assets/forestry/textures/items/gearTin.png new file mode 100755 index 000000000..ec7e118c3 Binary files /dev/null and b/forestry_resources/assets/forestry/textures/items/gearTin.png differ diff --git a/forestry_resources/assets/forestry/textures/items/grafter.png b/forestry_resources/assets/forestry/textures/items/grafter.png new file mode 100755 index 000000000..0851e271c Binary files /dev/null and b/forestry_resources/assets/forestry/textures/items/grafter.png differ diff --git a/forestry_resources/assets/forestry/textures/items/grafterProven.png b/forestry_resources/assets/forestry/textures/items/grafterProven.png new file mode 100755 index 000000000..fd4a676d8 Binary files /dev/null and b/forestry_resources/assets/forestry/textures/items/grafterProven.png differ diff --git a/forestry_resources/assets/forestry/textures/items/habitats/desert.png b/forestry_resources/assets/forestry/textures/items/habitats/desert.png new file mode 100755 index 000000000..bf4d8e764 Binary files /dev/null and b/forestry_resources/assets/forestry/textures/items/habitats/desert.png differ diff --git a/forestry_resources/assets/forestry/textures/items/habitats/end.png b/forestry_resources/assets/forestry/textures/items/habitats/end.png new file mode 100755 index 000000000..db9038536 Binary files /dev/null and b/forestry_resources/assets/forestry/textures/items/habitats/end.png differ diff --git a/forestry_resources/assets/forestry/textures/items/habitats/forest.png b/forestry_resources/assets/forestry/textures/items/habitats/forest.png new file mode 100755 index 000000000..038704e8b Binary files /dev/null and b/forestry_resources/assets/forestry/textures/items/habitats/forest.png differ diff --git a/forestry_resources/assets/forestry/textures/items/habitats/hills.png b/forestry_resources/assets/forestry/textures/items/habitats/hills.png new file mode 100755 index 000000000..f81317f6a Binary files /dev/null and b/forestry_resources/assets/forestry/textures/items/habitats/hills.png differ diff --git a/forestry_resources/assets/forestry/textures/items/habitats/jungle.png b/forestry_resources/assets/forestry/textures/items/habitats/jungle.png new file mode 100755 index 000000000..03f0eaab2 Binary files /dev/null and b/forestry_resources/assets/forestry/textures/items/habitats/jungle.png differ diff --git a/forestry_resources/assets/forestry/textures/items/habitats/mushroom.png b/forestry_resources/assets/forestry/textures/items/habitats/mushroom.png new file mode 100755 index 000000000..53030fd83 Binary files /dev/null and b/forestry_resources/assets/forestry/textures/items/habitats/mushroom.png differ diff --git a/forestry_resources/assets/forestry/textures/items/habitats/nether.png b/forestry_resources/assets/forestry/textures/items/habitats/nether.png new file mode 100755 index 000000000..94c0ba84f Binary files /dev/null and b/forestry_resources/assets/forestry/textures/items/habitats/nether.png differ diff --git a/forestry_resources/assets/forestry/textures/items/habitats/ocean.png b/forestry_resources/assets/forestry/textures/items/habitats/ocean.png new file mode 100755 index 000000000..feca8692f Binary files /dev/null and b/forestry_resources/assets/forestry/textures/items/habitats/ocean.png differ diff --git a/forestry_resources/assets/forestry/textures/items/habitats/plains.png b/forestry_resources/assets/forestry/textures/items/habitats/plains.png new file mode 100755 index 000000000..9fd1a5842 Binary files /dev/null and b/forestry_resources/assets/forestry/textures/items/habitats/plains.png differ diff --git a/forestry_resources/assets/forestry/textures/items/habitats/snow.png b/forestry_resources/assets/forestry/textures/items/habitats/snow.png new file mode 100755 index 000000000..0feccbf40 Binary files /dev/null and b/forestry_resources/assets/forestry/textures/items/habitats/snow.png differ diff --git a/forestry_resources/assets/forestry/textures/items/habitats/swamp.png b/forestry_resources/assets/forestry/textures/items/habitats/swamp.png new file mode 100755 index 000000000..64a15ec17 Binary files /dev/null and b/forestry_resources/assets/forestry/textures/items/habitats/swamp.png differ diff --git a/forestry_resources/assets/forestry/textures/items/habitats/taiga.png b/forestry_resources/assets/forestry/textures/items/habitats/taiga.png new file mode 100755 index 000000000..12d771524 Binary files /dev/null and b/forestry_resources/assets/forestry/textures/items/habitats/taiga.png differ diff --git a/forestry_resources/assets/forestry/textures/items/hardenedMachine.png b/forestry_resources/assets/forestry/textures/items/hardenedMachine.png new file mode 100755 index 000000000..715cfa2ec Binary files /dev/null and b/forestry_resources/assets/forestry/textures/items/hardenedMachine.png differ diff --git a/forestry_resources/assets/forestry/textures/items/honeyDrop.0.png b/forestry_resources/assets/forestry/textures/items/honeyDrop.0.png new file mode 100755 index 000000000..52ba983ee Binary files /dev/null and b/forestry_resources/assets/forestry/textures/items/honeyDrop.0.png differ diff --git a/forestry_resources/assets/forestry/textures/items/honeyDrop.1.png b/forestry_resources/assets/forestry/textures/items/honeyDrop.1.png new file mode 100755 index 000000000..685637dab Binary files /dev/null and b/forestry_resources/assets/forestry/textures/items/honeyDrop.1.png differ diff --git a/forestry_resources/assets/forestry/textures/items/honeyPot.png b/forestry_resources/assets/forestry/textures/items/honeyPot.png new file mode 100755 index 000000000..e2a08dd3c Binary files /dev/null and b/forestry_resources/assets/forestry/textures/items/honeyPot.png differ diff --git a/forestry_resources/assets/forestry/textures/items/honeydew.png b/forestry_resources/assets/forestry/textures/items/honeydew.png new file mode 100755 index 000000000..ea87e950c Binary files /dev/null and b/forestry_resources/assets/forestry/textures/items/honeydew.png differ diff --git a/forestry_resources/assets/forestry/textures/items/honeyedSlice.png b/forestry_resources/assets/forestry/textures/items/honeyedSlice.png new file mode 100755 index 000000000..c2e9f6bcf Binary files /dev/null and b/forestry_resources/assets/forestry/textures/items/honeyedSlice.png differ diff --git a/forestry_resources/assets/forestry/textures/items/iceShard.png b/forestry_resources/assets/forestry/textures/items/iceShard.png new file mode 100755 index 000000000..0ced8ba88 Binary files /dev/null and b/forestry_resources/assets/forestry/textures/items/iceShard.png differ diff --git a/forestry_resources/assets/forestry/textures/items/impregnatedCasing.png b/forestry_resources/assets/forestry/textures/items/impregnatedCasing.png new file mode 100755 index 000000000..dd46bba4a Binary files /dev/null and b/forestry_resources/assets/forestry/textures/items/impregnatedCasing.png differ diff --git a/forestry_resources/assets/forestry/textures/items/imprinter.png b/forestry_resources/assets/forestry/textures/items/imprinter.png new file mode 100755 index 000000000..75b698fee Binary files /dev/null and b/forestry_resources/assets/forestry/textures/items/imprinter.png differ diff --git a/forestry_resources/assets/forestry/textures/items/infuser.png b/forestry_resources/assets/forestry/textures/items/infuser.png new file mode 100755 index 000000000..89ef93994 Binary files /dev/null and b/forestry_resources/assets/forestry/textures/items/infuser.png differ diff --git a/forestry_resources/assets/forestry/textures/items/ingotBronze.png b/forestry_resources/assets/forestry/textures/items/ingotBronze.png new file mode 100755 index 000000000..0376acee0 Binary files /dev/null and b/forestry_resources/assets/forestry/textures/items/ingotBronze.png differ diff --git a/forestry_resources/assets/forestry/textures/items/ingotCopper.png b/forestry_resources/assets/forestry/textures/items/ingotCopper.png new file mode 100755 index 000000000..145f0d38d Binary files /dev/null and b/forestry_resources/assets/forestry/textures/items/ingotCopper.png differ diff --git a/forestry_resources/assets/forestry/textures/items/ingotTin.png b/forestry_resources/assets/forestry/textures/items/ingotTin.png new file mode 100755 index 000000000..e9ccc631e Binary files /dev/null and b/forestry_resources/assets/forestry/textures/items/ingotTin.png differ diff --git a/forestry_resources/assets/forestry/textures/items/iodineCapsule.png b/forestry_resources/assets/forestry/textures/items/iodineCapsule.png new file mode 100755 index 000000000..32628123b Binary files /dev/null and b/forestry_resources/assets/forestry/textures/items/iodineCapsule.png differ diff --git a/forestry_resources/assets/forestry/textures/items/kitPickaxe.png b/forestry_resources/assets/forestry/textures/items/kitPickaxe.png new file mode 100755 index 000000000..1b7643234 Binary files /dev/null and b/forestry_resources/assets/forestry/textures/items/kitPickaxe.png differ diff --git a/forestry_resources/assets/forestry/textures/items/kitShovel.png b/forestry_resources/assets/forestry/textures/items/kitShovel.png new file mode 100755 index 000000000..d3d66dfe9 Binary files /dev/null and b/forestry_resources/assets/forestry/textures/items/kitShovel.png differ diff --git a/forestry_resources/assets/forestry/textures/items/liquids/bucket.bottle.png b/forestry_resources/assets/forestry/textures/items/liquids/bucket.bottle.png new file mode 100755 index 000000000..30d6b0983 Binary files /dev/null and b/forestry_resources/assets/forestry/textures/items/liquids/bucket.bottle.png differ diff --git a/forestry_resources/assets/forestry/textures/items/liquids/bucket.contents.png b/forestry_resources/assets/forestry/textures/items/liquids/bucket.contents.png new file mode 100755 index 000000000..e73b04662 Binary files /dev/null and b/forestry_resources/assets/forestry/textures/items/liquids/bucket.contents.png differ diff --git a/forestry_resources/assets/forestry/textures/items/liquids/can.bottle.png b/forestry_resources/assets/forestry/textures/items/liquids/can.bottle.png new file mode 100755 index 000000000..50609e3b5 Binary files /dev/null and b/forestry_resources/assets/forestry/textures/items/liquids/can.bottle.png differ diff --git a/forestry_resources/assets/forestry/textures/items/liquids/can.contents.png b/forestry_resources/assets/forestry/textures/items/liquids/can.contents.png new file mode 100755 index 000000000..11406e0b6 Binary files /dev/null and b/forestry_resources/assets/forestry/textures/items/liquids/can.contents.png differ diff --git a/forestry_resources/assets/forestry/textures/items/liquids/capsule.bottle.png b/forestry_resources/assets/forestry/textures/items/liquids/capsule.bottle.png new file mode 100755 index 000000000..ba27c4176 Binary files /dev/null and b/forestry_resources/assets/forestry/textures/items/liquids/capsule.bottle.png differ diff --git a/forestry_resources/assets/forestry/textures/items/liquids/capsule.contents.png b/forestry_resources/assets/forestry/textures/items/liquids/capsule.contents.png new file mode 100755 index 000000000..63df1e035 Binary files /dev/null and b/forestry_resources/assets/forestry/textures/items/liquids/capsule.contents.png differ diff --git a/forestry_resources/assets/forestry/textures/items/liquids/glass.bottle.png b/forestry_resources/assets/forestry/textures/items/liquids/glass.bottle.png new file mode 100755 index 000000000..20d042faa Binary files /dev/null and b/forestry_resources/assets/forestry/textures/items/liquids/glass.bottle.png differ diff --git a/forestry_resources/assets/forestry/textures/items/liquids/glass.contents.png b/forestry_resources/assets/forestry/textures/items/liquids/glass.contents.png new file mode 100755 index 000000000..172ddec50 Binary files /dev/null and b/forestry_resources/assets/forestry/textures/items/liquids/glass.contents.png differ diff --git a/forestry_resources/assets/forestry/textures/items/liquids/jar.bottle.png b/forestry_resources/assets/forestry/textures/items/liquids/jar.bottle.png new file mode 100755 index 000000000..6e1529550 Binary files /dev/null and b/forestry_resources/assets/forestry/textures/items/liquids/jar.bottle.png differ diff --git a/forestry_resources/assets/forestry/textures/items/liquids/jar.contents.png b/forestry_resources/assets/forestry/textures/items/liquids/jar.contents.png new file mode 100755 index 000000000..b78668d21 Binary files /dev/null and b/forestry_resources/assets/forestry/textures/items/liquids/jar.contents.png differ diff --git a/forestry_resources/assets/forestry/textures/items/liquids/refractory.bottle.png b/forestry_resources/assets/forestry/textures/items/liquids/refractory.bottle.png new file mode 100755 index 000000000..45cdf9bb6 Binary files /dev/null and b/forestry_resources/assets/forestry/textures/items/liquids/refractory.bottle.png differ diff --git a/forestry_resources/assets/forestry/textures/items/liquids/refractory.contents.png b/forestry_resources/assets/forestry/textures/items/liquids/refractory.contents.png new file mode 100755 index 000000000..2a2bffd48 Binary files /dev/null and b/forestry_resources/assets/forestry/textures/items/liquids/refractory.contents.png differ diff --git a/forestry_resources/assets/forestry/textures/items/mail/carrier.player.png b/forestry_resources/assets/forestry/textures/items/mail/carrier.player.png new file mode 100755 index 000000000..0b2c5f1a4 Binary files /dev/null and b/forestry_resources/assets/forestry/textures/items/mail/carrier.player.png differ diff --git a/forestry_resources/assets/forestry/textures/items/mail/carrier.trader.png b/forestry_resources/assets/forestry/textures/items/mail/carrier.trader.png new file mode 100755 index 000000000..94da24222 Binary files /dev/null and b/forestry_resources/assets/forestry/textures/items/mail/carrier.trader.png differ diff --git a/forestry_resources/assets/forestry/textures/items/mail/letter.0.emptied.png b/forestry_resources/assets/forestry/textures/items/mail/letter.0.emptied.png new file mode 100755 index 000000000..90c99308b Binary files /dev/null and b/forestry_resources/assets/forestry/textures/items/mail/letter.0.emptied.png differ diff --git a/forestry_resources/assets/forestry/textures/items/mail/letter.0.fresh.png b/forestry_resources/assets/forestry/textures/items/mail/letter.0.fresh.png new file mode 100755 index 000000000..b2a149b30 Binary files /dev/null and b/forestry_resources/assets/forestry/textures/items/mail/letter.0.fresh.png differ diff --git a/forestry_resources/assets/forestry/textures/items/mail/letter.0.opened.png b/forestry_resources/assets/forestry/textures/items/mail/letter.0.opened.png new file mode 100755 index 000000000..bb591d577 Binary files /dev/null and b/forestry_resources/assets/forestry/textures/items/mail/letter.0.opened.png differ diff --git a/forestry_resources/assets/forestry/textures/items/mail/letter.0.stamped.png b/forestry_resources/assets/forestry/textures/items/mail/letter.0.stamped.png new file mode 100755 index 000000000..99b1bbab7 Binary files /dev/null and b/forestry_resources/assets/forestry/textures/items/mail/letter.0.stamped.png differ diff --git a/forestry_resources/assets/forestry/textures/items/mail/letter.1.emptied.png b/forestry_resources/assets/forestry/textures/items/mail/letter.1.emptied.png new file mode 100755 index 000000000..a1526f9df Binary files /dev/null and b/forestry_resources/assets/forestry/textures/items/mail/letter.1.emptied.png differ diff --git a/forestry_resources/assets/forestry/textures/items/mail/letter.1.fresh.png b/forestry_resources/assets/forestry/textures/items/mail/letter.1.fresh.png new file mode 100755 index 000000000..e543e0e3c Binary files /dev/null and b/forestry_resources/assets/forestry/textures/items/mail/letter.1.fresh.png differ diff --git a/forestry_resources/assets/forestry/textures/items/mail/letter.1.opened.png b/forestry_resources/assets/forestry/textures/items/mail/letter.1.opened.png new file mode 100755 index 000000000..9630743c6 Binary files /dev/null and b/forestry_resources/assets/forestry/textures/items/mail/letter.1.opened.png differ diff --git a/forestry_resources/assets/forestry/textures/items/mail/letter.1.stamped.png b/forestry_resources/assets/forestry/textures/items/mail/letter.1.stamped.png new file mode 100755 index 000000000..823ed5a7c Binary files /dev/null and b/forestry_resources/assets/forestry/textures/items/mail/letter.1.stamped.png differ diff --git a/forestry_resources/assets/forestry/textures/items/mail/letter.2.emptied.png b/forestry_resources/assets/forestry/textures/items/mail/letter.2.emptied.png new file mode 100755 index 000000000..815fa3ec4 Binary files /dev/null and b/forestry_resources/assets/forestry/textures/items/mail/letter.2.emptied.png differ diff --git a/forestry_resources/assets/forestry/textures/items/mail/letter.2.fresh.png b/forestry_resources/assets/forestry/textures/items/mail/letter.2.fresh.png new file mode 100755 index 000000000..b80c9cbfb Binary files /dev/null and b/forestry_resources/assets/forestry/textures/items/mail/letter.2.fresh.png differ diff --git a/forestry_resources/assets/forestry/textures/items/mail/letter.2.opened.png b/forestry_resources/assets/forestry/textures/items/mail/letter.2.opened.png new file mode 100755 index 000000000..1be9353e7 Binary files /dev/null and b/forestry_resources/assets/forestry/textures/items/mail/letter.2.opened.png differ diff --git a/forestry_resources/assets/forestry/textures/items/mail/letter.2.stamped.png b/forestry_resources/assets/forestry/textures/items/mail/letter.2.stamped.png new file mode 100755 index 000000000..8785fc339 Binary files /dev/null and b/forestry_resources/assets/forestry/textures/items/mail/letter.2.stamped.png differ diff --git a/forestry_resources/assets/forestry/textures/items/misc/access.private.png b/forestry_resources/assets/forestry/textures/items/misc/access.private.png new file mode 100755 index 000000000..8d269150d Binary files /dev/null and b/forestry_resources/assets/forestry/textures/items/misc/access.private.png differ diff --git a/forestry_resources/assets/forestry/textures/items/misc/access.shared.png b/forestry_resources/assets/forestry/textures/items/misc/access.shared.png new file mode 100755 index 000000000..4fe8754a9 Binary files /dev/null and b/forestry_resources/assets/forestry/textures/items/misc/access.shared.png differ diff --git a/forestry_resources/assets/forestry/textures/items/misc/access.viewable.png b/forestry_resources/assets/forestry/textures/items/misc/access.viewable.png new file mode 100755 index 000000000..0d145c36d Binary files /dev/null and b/forestry_resources/assets/forestry/textures/items/misc/access.viewable.png differ diff --git a/forestry_resources/assets/forestry/textures/items/misc/energy.png b/forestry_resources/assets/forestry/textures/items/misc/energy.png new file mode 100755 index 000000000..f8b042dd3 Binary files /dev/null and b/forestry_resources/assets/forestry/textures/items/misc/energy.png differ diff --git a/forestry_resources/assets/forestry/textures/items/misc/hint.png b/forestry_resources/assets/forestry/textures/items/misc/hint.png new file mode 100755 index 000000000..862412f31 Binary files /dev/null and b/forestry_resources/assets/forestry/textures/items/misc/hint.png differ diff --git a/forestry_resources/assets/forestry/textures/items/mouldyWheat.png b/forestry_resources/assets/forestry/textures/items/mouldyWheat.png new file mode 100755 index 000000000..8fa5755cd Binary files /dev/null and b/forestry_resources/assets/forestry/textures/items/mouldyWheat.png differ diff --git a/forestry_resources/assets/forestry/textures/items/mulch.png b/forestry_resources/assets/forestry/textures/items/mulch.png new file mode 100755 index 000000000..4e9fae4e2 Binary files /dev/null and b/forestry_resources/assets/forestry/textures/items/mulch.png differ diff --git a/forestry_resources/assets/forestry/textures/items/naturalistHelmet.png b/forestry_resources/assets/forestry/textures/items/naturalistHelmet.png new file mode 100755 index 000000000..d979926ee Binary files /dev/null and b/forestry_resources/assets/forestry/textures/items/naturalistHelmet.png differ diff --git a/forestry_resources/assets/forestry/textures/items/naturalist_armor_1.png b/forestry_resources/assets/forestry/textures/items/naturalist_armor_1.png new file mode 100755 index 000000000..4ba3e7a52 Binary files /dev/null and b/forestry_resources/assets/forestry/textures/items/naturalist_armor_1.png differ diff --git a/forestry_resources/assets/forestry/textures/items/oakStick.png b/forestry_resources/assets/forestry/textures/items/oakStick.png new file mode 100755 index 000000000..9208738d3 Binary files /dev/null and b/forestry_resources/assets/forestry/textures/items/oakStick.png differ diff --git a/forestry_resources/assets/forestry/textures/items/particles/ember.png b/forestry_resources/assets/forestry/textures/items/particles/ember.png new file mode 100755 index 000000000..8b71b1e85 Binary files /dev/null and b/forestry_resources/assets/forestry/textures/items/particles/ember.png differ diff --git a/forestry_resources/assets/forestry/textures/items/particles/flame.png b/forestry_resources/assets/forestry/textures/items/particles/flame.png new file mode 100755 index 000000000..3f1966252 Binary files /dev/null and b/forestry_resources/assets/forestry/textures/items/particles/flame.png differ diff --git a/forestry_resources/assets/forestry/textures/items/particles/placeholder.png b/forestry_resources/assets/forestry/textures/items/particles/placeholder.png new file mode 100755 index 000000000..af9fdb463 Binary files /dev/null and b/forestry_resources/assets/forestry/textures/items/particles/placeholder.png differ diff --git a/forestry_resources/assets/forestry/textures/items/particles/poison.png b/forestry_resources/assets/forestry/textures/items/particles/poison.png new file mode 100755 index 000000000..5183d1c3d Binary files /dev/null and b/forestry_resources/assets/forestry/textures/items/particles/poison.png differ diff --git a/forestry_resources/assets/forestry/textures/items/particles/snow.1.png b/forestry_resources/assets/forestry/textures/items/particles/snow.1.png new file mode 100755 index 000000000..69fb8fbd7 Binary files /dev/null and b/forestry_resources/assets/forestry/textures/items/particles/snow.1.png differ diff --git a/forestry_resources/assets/forestry/textures/items/particles/snow.2.png b/forestry_resources/assets/forestry/textures/items/particles/snow.2.png new file mode 100755 index 000000000..5e92bb1a3 Binary files /dev/null and b/forestry_resources/assets/forestry/textures/items/particles/snow.2.png differ diff --git a/forestry_resources/assets/forestry/textures/items/particles/snow.3.png b/forestry_resources/assets/forestry/textures/items/particles/snow.3.png new file mode 100755 index 000000000..6da05f7f3 Binary files /dev/null and b/forestry_resources/assets/forestry/textures/items/particles/snow.3.png differ diff --git a/forestry_resources/assets/forestry/textures/items/particles/swarm_bee.png b/forestry_resources/assets/forestry/textures/items/particles/swarm_bee.png new file mode 100755 index 000000000..31114894b Binary files /dev/null and b/forestry_resources/assets/forestry/textures/items/particles/swarm_bee.png differ diff --git a/forestry_resources/assets/forestry/textures/items/peat.png b/forestry_resources/assets/forestry/textures/items/peat.png new file mode 100755 index 000000000..b5c81a61a Binary files /dev/null and b/forestry_resources/assets/forestry/textures/items/peat.png differ diff --git a/forestry_resources/assets/forestry/textures/items/phosphor.png b/forestry_resources/assets/forestry/textures/items/phosphor.png new file mode 100755 index 000000000..2a5159bbb Binary files /dev/null and b/forestry_resources/assets/forestry/textures/items/phosphor.png differ diff --git a/forestry_resources/assets/forestry/textures/items/pipette.0.png b/forestry_resources/assets/forestry/textures/items/pipette.0.png new file mode 100755 index 000000000..7e15207a1 Binary files /dev/null and b/forestry_resources/assets/forestry/textures/items/pipette.0.png differ diff --git a/forestry_resources/assets/forestry/textures/items/pipette.1.png b/forestry_resources/assets/forestry/textures/items/pipette.1.png new file mode 100755 index 000000000..bd9ddbd03 Binary files /dev/null and b/forestry_resources/assets/forestry/textures/items/pipette.1.png differ diff --git a/forestry_resources/assets/forestry/textures/items/pollen.0.png b/forestry_resources/assets/forestry/textures/items/pollen.0.png new file mode 100755 index 000000000..673ffffa1 Binary files /dev/null and b/forestry_resources/assets/forestry/textures/items/pollen.0.png differ diff --git a/forestry_resources/assets/forestry/textures/items/pollen.1.png b/forestry_resources/assets/forestry/textures/items/pollen.1.png new file mode 100755 index 000000000..0f1b8781c Binary files /dev/null and b/forestry_resources/assets/forestry/textures/items/pollen.1.png differ diff --git a/forestry_resources/assets/forestry/textures/items/propolis.0.png b/forestry_resources/assets/forestry/textures/items/propolis.0.png new file mode 100755 index 000000000..48570e4bb Binary files /dev/null and b/forestry_resources/assets/forestry/textures/items/propolis.0.png differ diff --git a/forestry_resources/assets/forestry/textures/items/pulsatingDust.png b/forestry_resources/assets/forestry/textures/items/pulsatingDust.png new file mode 100755 index 000000000..06951f9e5 Binary files /dev/null and b/forestry_resources/assets/forestry/textures/items/pulsatingDust.png differ diff --git a/forestry_resources/assets/forestry/textures/items/pulsatingMesh.png b/forestry_resources/assets/forestry/textures/items/pulsatingMesh.png new file mode 100755 index 000000000..50c1d7707 Binary files /dev/null and b/forestry_resources/assets/forestry/textures/items/pulsatingMesh.png differ diff --git a/forestry_resources/assets/forestry/textures/items/refractoryWax.png b/forestry_resources/assets/forestry/textures/items/refractoryWax.png new file mode 100755 index 000000000..b3eb0749b Binary files /dev/null and b/forestry_resources/assets/forestry/textures/items/refractoryWax.png differ diff --git a/forestry_resources/assets/forestry/textures/items/royalJelly.png b/forestry_resources/assets/forestry/textures/items/royalJelly.png new file mode 100755 index 000000000..119dcf270 Binary files /dev/null and b/forestry_resources/assets/forestry/textures/items/royalJelly.png differ diff --git a/forestry_resources/assets/forestry/textures/items/scentedPaneling.png b/forestry_resources/assets/forestry/textures/items/scentedPaneling.png new file mode 100755 index 000000000..006166e88 Binary files /dev/null and b/forestry_resources/assets/forestry/textures/items/scentedPaneling.png differ diff --git a/forestry_resources/assets/forestry/textures/items/scoop.png b/forestry_resources/assets/forestry/textures/items/scoop.png new file mode 100755 index 000000000..9d61124eb Binary files /dev/null and b/forestry_resources/assets/forestry/textures/items/scoop.png differ diff --git a/forestry_resources/assets/forestry/textures/items/silkWisp.png b/forestry_resources/assets/forestry/textures/items/silkWisp.png new file mode 100755 index 000000000..e1f6435ca Binary files /dev/null and b/forestry_resources/assets/forestry/textures/items/silkWisp.png differ diff --git a/forestry_resources/assets/forestry/textures/items/slots/blocked.png b/forestry_resources/assets/forestry/textures/items/slots/blocked.png new file mode 100755 index 000000000..078fe327b Binary files /dev/null and b/forestry_resources/assets/forestry/textures/items/slots/blocked.png differ diff --git a/forestry_resources/assets/forestry/textures/items/slots/blocked_2.png b/forestry_resources/assets/forestry/textures/items/slots/blocked_2.png new file mode 100755 index 000000000..cb36e1d7f Binary files /dev/null and b/forestry_resources/assets/forestry/textures/items/slots/blocked_2.png differ diff --git a/forestry_resources/assets/forestry/textures/items/slots/container.png b/forestry_resources/assets/forestry/textures/items/slots/container.png new file mode 100755 index 000000000..a6fe90e28 Binary files /dev/null and b/forestry_resources/assets/forestry/textures/items/slots/container.png differ diff --git a/forestry_resources/assets/forestry/textures/items/slots/liquid.png b/forestry_resources/assets/forestry/textures/items/slots/liquid.png new file mode 100755 index 000000000..bb4722365 Binary files /dev/null and b/forestry_resources/assets/forestry/textures/items/slots/liquid.png differ diff --git a/forestry_resources/assets/forestry/textures/items/slots/locked.png b/forestry_resources/assets/forestry/textures/items/slots/locked.png new file mode 100755 index 000000000..3bb8f80f0 Binary files /dev/null and b/forestry_resources/assets/forestry/textures/items/slots/locked.png differ diff --git a/forestry_resources/assets/forestry/textures/items/solderingIron.png b/forestry_resources/assets/forestry/textures/items/solderingIron.png new file mode 100755 index 000000000..5e5893c7c Binary files /dev/null and b/forestry_resources/assets/forestry/textures/items/solderingIron.png differ diff --git a/forestry_resources/assets/forestry/textures/items/spectacles.png b/forestry_resources/assets/forestry/textures/items/spectacles.png new file mode 100755 index 000000000..9a26b9fde Binary files /dev/null and b/forestry_resources/assets/forestry/textures/items/spectacles.png differ diff --git a/forestry_resources/assets/forestry/textures/items/stamps.0.png b/forestry_resources/assets/forestry/textures/items/stamps.0.png new file mode 100755 index 000000000..9f5df2830 Binary files /dev/null and b/forestry_resources/assets/forestry/textures/items/stamps.0.png differ diff --git a/forestry_resources/assets/forestry/textures/items/stamps.1.png b/forestry_resources/assets/forestry/textures/items/stamps.1.png new file mode 100755 index 000000000..df8732b50 Binary files /dev/null and b/forestry_resources/assets/forestry/textures/items/stamps.1.png differ diff --git a/forestry_resources/assets/forestry/textures/items/sturdyMachine.png b/forestry_resources/assets/forestry/textures/items/sturdyMachine.png new file mode 100755 index 000000000..bc95f87ea Binary files /dev/null and b/forestry_resources/assets/forestry/textures/items/sturdyMachine.png differ diff --git a/forestry_resources/assets/forestry/textures/items/thermionicTubes.0.png b/forestry_resources/assets/forestry/textures/items/thermionicTubes.0.png new file mode 100755 index 000000000..b9b585b0e Binary files /dev/null and b/forestry_resources/assets/forestry/textures/items/thermionicTubes.0.png differ diff --git a/forestry_resources/assets/forestry/textures/items/thermionicTubes.1.png b/forestry_resources/assets/forestry/textures/items/thermionicTubes.1.png new file mode 100755 index 000000000..2a0d935c0 Binary files /dev/null and b/forestry_resources/assets/forestry/textures/items/thermionicTubes.1.png differ diff --git a/forestry_resources/assets/forestry/textures/items/treealyzer.png b/forestry_resources/assets/forestry/textures/items/treealyzer.png new file mode 100755 index 000000000..c3025bcb2 Binary files /dev/null and b/forestry_resources/assets/forestry/textures/items/treealyzer.png differ diff --git a/forestry_resources/assets/forestry/textures/items/triggers/hasMail.png b/forestry_resources/assets/forestry/textures/items/triggers/hasMail.png new file mode 100755 index 000000000..86105ec1c Binary files /dev/null and b/forestry_resources/assets/forestry/textures/items/triggers/hasMail.png differ diff --git a/forestry_resources/assets/forestry/textures/items/triggers/hasWork.png b/forestry_resources/assets/forestry/textures/items/triggers/hasWork.png new file mode 100755 index 000000000..cd37e0d4b Binary files /dev/null and b/forestry_resources/assets/forestry/textures/items/triggers/hasWork.png differ diff --git a/forestry_resources/assets/forestry/textures/items/triggers/lowFertilizer.png b/forestry_resources/assets/forestry/textures/items/triggers/lowFertilizer.png new file mode 100755 index 000000000..e4e9f1b8b Binary files /dev/null and b/forestry_resources/assets/forestry/textures/items/triggers/lowFertilizer.png differ diff --git a/forestry_resources/assets/forestry/textures/items/triggers/lowFuel.png b/forestry_resources/assets/forestry/textures/items/triggers/lowFuel.png new file mode 100755 index 000000000..e4e9f1b8b Binary files /dev/null and b/forestry_resources/assets/forestry/textures/items/triggers/lowFuel.png differ diff --git a/forestry_resources/assets/forestry/textures/items/triggers/lowGermlings.png b/forestry_resources/assets/forestry/textures/items/triggers/lowGermlings.png new file mode 100755 index 000000000..fae6e5dcc Binary files /dev/null and b/forestry_resources/assets/forestry/textures/items/triggers/lowGermlings.png differ diff --git a/forestry_resources/assets/forestry/textures/items/triggers/lowInput.png b/forestry_resources/assets/forestry/textures/items/triggers/lowInput.png new file mode 100755 index 000000000..5456205de Binary files /dev/null and b/forestry_resources/assets/forestry/textures/items/triggers/lowInput.png differ diff --git a/forestry_resources/assets/forestry/textures/items/triggers/lowLiquid.png b/forestry_resources/assets/forestry/textures/items/triggers/lowLiquid.png new file mode 100755 index 000000000..c7996a85b Binary files /dev/null and b/forestry_resources/assets/forestry/textures/items/triggers/lowLiquid.png differ diff --git a/forestry_resources/assets/forestry/textures/items/triggers/lowPaper.png b/forestry_resources/assets/forestry/textures/items/triggers/lowPaper.png new file mode 100755 index 000000000..84fed158a Binary files /dev/null and b/forestry_resources/assets/forestry/textures/items/triggers/lowPaper.png differ diff --git a/forestry_resources/assets/forestry/textures/items/triggers/lowResources.png b/forestry_resources/assets/forestry/textures/items/triggers/lowResources.png new file mode 100755 index 000000000..1635fc01d Binary files /dev/null and b/forestry_resources/assets/forestry/textures/items/triggers/lowResources.png differ diff --git a/forestry_resources/assets/forestry/textures/items/triggers/lowSoil.png b/forestry_resources/assets/forestry/textures/items/triggers/lowSoil.png new file mode 100755 index 000000000..2836e4dca Binary files /dev/null and b/forestry_resources/assets/forestry/textures/items/triggers/lowSoil.png differ diff --git a/forestry_resources/assets/forestry/textures/items/triggers/lowStamps.png b/forestry_resources/assets/forestry/textures/items/triggers/lowStamps.png new file mode 100755 index 000000000..b191aa6d7 Binary files /dev/null and b/forestry_resources/assets/forestry/textures/items/triggers/lowStamps.png differ diff --git a/forestry_resources/assets/forestry/textures/items/triggers/mailBuffer.png b/forestry_resources/assets/forestry/textures/items/triggers/mailBuffer.png new file mode 100755 index 000000000..0942ed588 Binary files /dev/null and b/forestry_resources/assets/forestry/textures/items/triggers/mailBuffer.png differ diff --git a/forestry_resources/assets/forestry/textures/items/triggers/missingDrone.png b/forestry_resources/assets/forestry/textures/items/triggers/missingDrone.png new file mode 100755 index 000000000..58d55a761 Binary files /dev/null and b/forestry_resources/assets/forestry/textures/items/triggers/missingDrone.png differ diff --git a/forestry_resources/assets/forestry/textures/items/triggers/missingQueen.png b/forestry_resources/assets/forestry/textures/items/triggers/missingQueen.png new file mode 100755 index 000000000..71d5a1d21 Binary files /dev/null and b/forestry_resources/assets/forestry/textures/items/triggers/missingQueen.png differ diff --git a/forestry_resources/assets/forestry/textures/items/triggers/noFrames.png b/forestry_resources/assets/forestry/textures/items/triggers/noFrames.png new file mode 100755 index 000000000..9ea49f80f Binary files /dev/null and b/forestry_resources/assets/forestry/textures/items/triggers/noFrames.png differ diff --git a/forestry_resources/assets/forestry/textures/items/vialCatalyst.png b/forestry_resources/assets/forestry/textures/items/vialCatalyst.png new file mode 100755 index 000000000..cef169ef6 Binary files /dev/null and b/forestry_resources/assets/forestry/textures/items/vialCatalyst.png differ diff --git a/forestry_resources/assets/forestry/textures/items/waxCast.png b/forestry_resources/assets/forestry/textures/items/waxCast.png new file mode 100755 index 000000000..7a5aa1f6d Binary files /dev/null and b/forestry_resources/assets/forestry/textures/items/waxCast.png differ diff --git a/forestry_resources/assets/forestry/textures/items/woodPulp.png b/forestry_resources/assets/forestry/textures/items/woodPulp.png new file mode 100755 index 000000000..94f7cb10c Binary files /dev/null and b/forestry_resources/assets/forestry/textures/items/woodPulp.png differ diff --git a/forestry_resources/assets/forestry/textures/items/wovenSilk.png b/forestry_resources/assets/forestry/textures/items/wovenSilk.png new file mode 100755 index 000000000..22bbc1b8c Binary files /dev/null and b/forestry_resources/assets/forestry/textures/items/wovenSilk.png differ diff --git a/forestry_resources/assets/forestry/textures/items/wrench.png b/forestry_resources/assets/forestry/textures/items/wrench.png new file mode 100755 index 000000000..6c4df621b Binary files /dev/null and b/forestry_resources/assets/forestry/textures/items/wrench.png differ diff --git a/forestry_resources/assets/forestry/textures/unsorted/tile]-10.png b/forestry_resources/assets/forestry/textures/unsorted/tile]-10.png new file mode 100755 index 000000000..373882cd7 Binary files /dev/null and b/forestry_resources/assets/forestry/textures/unsorted/tile]-10.png differ diff --git a/forestry_resources/assets/forestry/textures/unsorted/tile]-105.png b/forestry_resources/assets/forestry/textures/unsorted/tile]-105.png new file mode 100755 index 000000000..161010fe2 Binary files /dev/null and b/forestry_resources/assets/forestry/textures/unsorted/tile]-105.png differ diff --git a/forestry_resources/assets/forestry/textures/unsorted/tile]-37.png b/forestry_resources/assets/forestry/textures/unsorted/tile]-37.png new file mode 100755 index 000000000..b1e60aa23 Binary files /dev/null and b/forestry_resources/assets/forestry/textures/unsorted/tile]-37.png differ diff --git a/forestry_resources/assets/forestry/textures/unsorted/tile]-88.png b/forestry_resources/assets/forestry/textures/unsorted/tile]-88.png new file mode 100755 index 000000000..c886dcda6 Binary files /dev/null and b/forestry_resources/assets/forestry/textures/unsorted/tile]-88.png differ diff --git a/forestry_resources/assets/forestry/textures/unsorted/tile]-89.png b/forestry_resources/assets/forestry/textures/unsorted/tile]-89.png new file mode 100755 index 000000000..a3a07a004 Binary files /dev/null and b/forestry_resources/assets/forestry/textures/unsorted/tile]-89.png differ diff --git a/forestry_resources/assets/forestry/textures/unsorted/tile]-90.png b/forestry_resources/assets/forestry/textures/unsorted/tile]-90.png new file mode 100755 index 000000000..82ad27be5 Binary files /dev/null and b/forestry_resources/assets/forestry/textures/unsorted/tile]-90.png differ diff --git a/forestry_resources/changelog/2.0.0.0 b/forestry_resources/changelog/2.0.0.0 new file mode 100755 index 000000000..621ebed92 --- /dev/null +++ b/forestry_resources/changelog/2.0.0.0 @@ -0,0 +1,31 @@ + +# 2.0.0.0 + +- Added: Multiblock farms with hatches, valves and gearboxes. Can be configured via circuit boards. +- Added: Added grafter item with 5 uses. +- Added: Alveary Hygroregulator to control humidity. +- Added: Stairs for Forestry woods. +- Added: Seperate tabs for Forestry mod items. +- Added: BC gate triggers for low soil and liquid on multiblock farms. Low soil will accept an item as a parameter. +- Added: Rubber plantation for multiblock farms when IC2 is installed. Works similar to an orchard. +- Added: 5x5 variant of multiblock farms. (Hi CPW!) +- Removed: Bonus to sapling drop rate on leaves. Use your grafter! +- Changed: New textures for apatite, apatite ore, fertilizer. Apatite ore now drops between 0 and 5 gems per ore block, works with fortune. +- Changed: Soldering iron can now switch between different layouts for the electrical engine, managed farms and manual farms. The layout determines the effect of an electron tube. +- Changed: Bonemeal now works on fruit leaves. +- Changed: Removed generational data from drones. Should improve stacking behaviour significantly. +- Changed: Refactored alveary to use single block id. Will update existing apiaries. +- Changed: Alvearies and farms will now keep their inventory even if broken. Only breaking the master block will eject items. +- Changed: Alvearies and farms can be owned like any other machine. +- Changed: New textures for copper and tin ore. +- Changed: Ore gen slightly. Apatite does not spawn below Y=60 anymore. Copper needs at least Y = 32, tin Y = 16. +- Changed: Ash cannot be used to create fertilizer anymore. It can be mixed with existing fertilizer to double it though. +- Bugfix: Fixed a bug that caused fruits to only drop a single time. +- Bugfix: Fixed some derpy backpack behaviour. (Thanks CovertJaguar!) +- Bugfix: Fixed a few soldering iron issues when removing chipsets. +- Bugfix: Fixed some stacking issues with bees. (Thanks Direwolf!) +- Bugfix: Fixed imprinter. + +- API: Full API to add entirely new farm logic to multiblock farms via circuits or just single crops to existing farms. + +- Localization: Added/Updated PR and CN. \ No newline at end of file diff --git a/forestry_resources/changelog/2.0.0.1 b/forestry_resources/changelog/2.0.0.1 new file mode 100755 index 000000000..f2725efd7 --- /dev/null +++ b/forestry_resources/changelog/2.0.0.1 @@ -0,0 +1,16 @@ + +# 2.0.0.1 + +- Added: 4x4 farm. +- Added: Config option to disable specific structure schemata. +- Added: Missing config option for fertilizer value in gamemodes. +- Changed: Fertilizer lasts longer in farms on easy gamemode. +- Changed: Back side of engines is now solid. +- Changed: Farm hatches now output into pipes and inventories below them. +- Changed: Managed arboretum now uses all the available space. +- Bugfix: Fixed an issue that caused BC's emerald pipes to crash. +- Bugfix: Infernal farm now actually harvests crops and doesn't just sit there looking pretty. +- Bugfix: Alveary swarmer and hygroregulator properly drop inventory contents when broken. +- Bugfix: Fixed an issue which can cause a crash in the treealyzer gui due to old sapling genetics. +- Bugfix: Fixed infernal farm not starting up without liquid in the tank. +- Bugfix: Fixed a Java 7 incompatibility. \ No newline at end of file diff --git a/forestry_resources/changelog/2.0.0.10 b/forestry_resources/changelog/2.0.0.10 new file mode 100755 index 000000000..b20ab1ae4 --- /dev/null +++ b/forestry_resources/changelog/2.0.0.10 @@ -0,0 +1,11 @@ + +# 2.0.0.10 + +- Added: Ops can now "virtualize" trade stations with the '/mail virtualize ' command. A virtual trade station does not require resources. +- Added: Genetic saplings as "treeSapling" to ore dictionary. Can now be crafted into IC2 plantballs. +- Changed: Made more trees support more fruit families. +- Changed: Increased output rate of farm hatches slightly. +- Changed: Added bituminous peat as a vanilla fuel source. +- Bugfix: Backpacks now force close the gui if they are dropped for any reason at all. Unified handling for all items with an inventory. +- Bugfix: Different types of circuit boards should not accidently stack anymore. +- Bugfix: Fixed genetic saplings not being recognized as valid vanilla fuel. \ No newline at end of file diff --git a/forestry_resources/changelog/2.0.0.11 b/forestry_resources/changelog/2.0.0.11 new file mode 100755 index 000000000..bf2d46312 --- /dev/null +++ b/forestry_resources/changelog/2.0.0.11 @@ -0,0 +1,9 @@ + +# 2.0.0.11 + +- Added: Alternate carpenter recipe for letters using six wood pulp. +- Added: Alternate carpenter recipe for stamps which omits the honey drops, but requires seed oil. +- Changed: Reduced fertilizer consumption on peat farms 10 -> 5. +- Bugfix: Fixed two potential NPEs on farms. +- Bugfix: Fixed a potential crash when opening letter gui. +- Bugfix: Fixed habitat locator not working. \ No newline at end of file diff --git a/forestry_resources/changelog/2.0.0.2 b/forestry_resources/changelog/2.0.0.2 new file mode 100755 index 000000000..371c0fe3c --- /dev/null +++ b/forestry_resources/changelog/2.0.0.2 @@ -0,0 +1,12 @@ + +# 2.0.0.2 + +- Added: Low fertilizer triggers for BC gates on farm hatches. +- Changed: Tied seed oil output for cherries, walnuts and chestnut to seed oil from wheat, with cherries giving 3x, walnuts 10x and chestnut 12x as much. +- Changed: Reduced ripening time on chestnuts and walnuts. +- Bugfix: Rubber plantation will now tap resin spots on the lowest wood block as well. +- Bugfix: Fixed orchard infighting over which fruits are harvestable and which are not. +- Bugfix: Neutered orchards ability to eat servers. +- Bugfix: Fixed rare stackoverflow crash on multiblock structures. +- Bugfix: Fixed an issue which caused extracting from alvearies to break. +- Bugfix: Fixed fruit colours incorrectly synching to client. \ No newline at end of file diff --git a/forestry_resources/changelog/2.0.0.3 b/forestry_resources/changelog/2.0.0.3 new file mode 100755 index 000000000..0d2dbf385 --- /dev/null +++ b/forestry_resources/changelog/2.0.0.3 @@ -0,0 +1,15 @@ + +# 2.0.0.3 + +- Changed: Alvearies and apiaries now accept the full stack of drones when piping into them. +- Changed: Orchards now require 10 fertilizer per operation instead of 5. Arboretums 30 instead of 40. +- Changed: Harvest phase does not consume fertilizer anymore, however actually collecting the crop will, leading to a uniform per crop cost instead of giving an advantage to tree-like crops. +- Bugfix: Fixed soldering iron eating tubes if a circuit board was inserted first. +- Bugfix: Fixed sapling placement sounds again. +- Bugfix: Fixed sipiri tree not actually being breedable. +- Bugfix: Fixed piping bees into alvearies. +- Bugfix: Moving an apiary via frames or gravigun should now also reset the biome. (RichardG) +- Bugfix: Fixed peat-fired engines not ejecting waste into pipes. +- Bugfix: Fixed stairs not removing associated tile entity when broken. +- Bugfix: Fixed stair placement consuming two stairs instead of one. +- Localization: Several updates to ES-variants, CN and others. \ No newline at end of file diff --git a/forestry_resources/changelog/2.0.0.4 b/forestry_resources/changelog/2.0.0.4 new file mode 100755 index 000000000..c0769489d --- /dev/null +++ b/forestry_resources/changelog/2.0.0.4 @@ -0,0 +1,24 @@ + +# 2.0.0.4 + +- Added: Another Forestry update? Don't be sad, have a cocoa plantation! +- Added: Disabling the crafting recipes for the old farms will now unlock uncrafting recipes to turn planters and harvesters into 30 new farmblocks. Craft one harvester or planter with a single brick-like block. They block chosen will determine the type of the resulting farmblocks. +- Added: Facades for BC pipes in all types of logs and planks now available. +- Added: Support for IC2 rubber trees in the arboretum as well. (Requires an IC2 update.) +- Added: Config option to switch farms to using a square layout instead of a diamond shaped one. Server side config controls it. +- Changed: Tweaked apatite world gen slightly. +- Changed: Removed the requirement of humus from the multifarm arboretum. Plain dirt is now required. The arboretum will mix it with fertilizer and will plant it out as humus. +- Bugfix: Fixed apiaries not displaying exact temperature and humidity. +- Bugfix: Wenge and baobab should now be breedable. +- Bugfix: Fixed potential NPE on alvearies in SMP. +- Bugfix: Fixed duplication bug in farms when collecting windfall. +- Bugfix: Fixed support stems on kapok and meranti stems replacing other blocks. +- Bugfix: Liquid pipes should now connect to a farm valve even if the farm validates after the pipe was placed. +- Bugfix: Fixed steadfast drones generating in stacks of ten. +- Bugfix: ExtraBiomesXL saplings now work in the fermenter. +- Bugfix: Fixed an issue which would cause an invalid farm block to drop when breaking a farmblock on the metal band level. +- Bugfix: Hatches do not eject into sandstone pipes anymore. +- Bugfix: Removed orphaned debug output. +- Bugfix: Made fruits with random drops instead of ripening useable in orchards. (Apples) +- API: Mods can now send an IMC with the key "add-farmable-sapling" and format "farmArboreal@saplingID.saplingDamage" or "farmArboreal@saplingID.saplingDamage.windfallID.windfallDamage" to Forestry to add a generic sapling. Will accept damage -1 as wildcard. +- API: Same as above for "add-farmable-crop" and format "farmCereal@seedID.seedDamage.cropBlockID.cropMatureMeta". diff --git a/forestry_resources/changelog/2.0.0.5 b/forestry_resources/changelog/2.0.0.5 new file mode 100755 index 000000000..af7708a0a --- /dev/null +++ b/forestry_resources/changelog/2.0.0.5 @@ -0,0 +1,4 @@ + +# 2.0.0.5 + +- Bugfix: Fixed dirt not being accepted when piped into a farm set to arboretum. \ No newline at end of file diff --git a/forestry_resources/changelog/2.0.0.6 b/forestry_resources/changelog/2.0.0.6 new file mode 100755 index 000000000..0a2a10456 --- /dev/null +++ b/forestry_resources/changelog/2.0.0.6 @@ -0,0 +1,10 @@ + +# 2.0.0.6 + +- Added: Managed and manual mushroom farm. (Apatine Electron Tube) +- Added: Some basic craftguide integration for carpenter, thermionic fabricator, squeezer and centrifuge. +- Added: FarmCraftory support for crops and vegetables. Corn is handled in the wheat farm, everything else in the vegetable farm. +- Bugfix: Fixed potential rare client crashes on Beealyzer, Habitat locator and Treealyzer. +- Bugfix: Fermenter will respect NBT data now. +- Bugfix: Fixed slight issues with sand replacement in MF arboretums. +- Localization: Updates to it_IT by Frantisek-Markov, to zh_CN by crafteverywhere. \ No newline at end of file diff --git a/forestry_resources/changelog/2.0.0.7 b/forestry_resources/changelog/2.0.0.7 new file mode 100755 index 000000000..0702d1fd8 --- /dev/null +++ b/forestry_resources/changelog/2.0.0.7 @@ -0,0 +1,4 @@ + +# 2.0.0.7 + +- Bugfix: Fixed wrong mushrooms being planted in mushroom farms. \ No newline at end of file diff --git a/forestry_resources/changelog/2.0.0.8 b/forestry_resources/changelog/2.0.0.8 new file mode 100755 index 000000000..8d76865c1 --- /dev/null +++ b/forestry_resources/changelog/2.0.0.8 @@ -0,0 +1,14 @@ + +# 2.0.0.8 + +- Added: Farm Control. Will disable farm sides according to sides with redstone signal. A redstone signal from top or bottom will shut down the whole farm. +- Added: Craftguide now displays recipes for farm blocks, still, fermenter, bottler. Better use of CraftGuide API. (RichardG) +- Added: Bare-bones '/mail trades' command. +- Changed: Crafting of old farms is now disabled by default on new installations. +- Changed: Farms should now handle their storage more intelligently. +- Changed: Forestry now auto-ops its fake player. Can be disabled in config. Login of fake player can also be changed in config. +- Changed: When opening a backpack gui, inventory slots with backpacks in them cannot be manipulated anymore in any way. Behaviour of letters has been changed to match. +- Bugfix: Capped modification by drought in farms at 2500 %. +- Bugfix: Energy modifier in game modes should now affect farm gearboxes. +- API: Changed IFarmListener around a bit for better functionality. Made StructureFarmLogic retrievable. +- Removed: Automatic display of changelog with version notice. You need to type '/forestry version' if you want to see the changelog now. \ No newline at end of file diff --git a/forestry_resources/changelog/2.0.0.9 b/forestry_resources/changelog/2.0.0.9 new file mode 100755 index 000000000..25940dab9 --- /dev/null +++ b/forestry_resources/changelog/2.0.0.9 @@ -0,0 +1,7 @@ + +# 2.0.0.9 + +- Changed: Limited iteration of arboretum and mushroom farms to +/- 5 from the tree trunk horizontally. +- Bugfix: Fixed an issue which caused arboretums to sometimes "forget" patches. +- Bugfix: Removed debug log message. +- Localization: Update to zh_CN by crafteverywhere. \ No newline at end of file diff --git a/forestry_resources/changelog/2.1.0.0 b/forestry_resources/changelog/2.1.0.0 new file mode 100755 index 000000000..fef68282c --- /dev/null +++ b/forestry_resources/changelog/2.1.0.0 @@ -0,0 +1,5 @@ + +# 2.1.0.0 + +- Added: Blue Mahoe, White Poplar and Lemon trees. Pine logs. +- Changed: Decreased chance for swarmer queens to die off by a factor of 10. \ No newline at end of file diff --git a/forestry_resources/changelog/2.2.0.0 b/forestry_resources/changelog/2.2.0.0 new file mode 100755 index 000000000..2f32a1fa6 --- /dev/null +++ b/forestry_resources/changelog/2.2.0.0 @@ -0,0 +1,25 @@ + +#2.2.0.0 + +- Added: 5 new bee species. +- Added: 8 new tree species. +- Added: Bee house as a low level alternative to the apiary. +- Added: Clockwork engine. Wind it up for early game energy. +- Added: Vanilla hopper support to all machines and engines. +- Changed: Trunk size on trees can now be inherited. That 3x3 cherry tree is now possible! +- Changed: Internal changes to several machines to improve performance and some interaction with other mods. +- Changed: Raintank is now an unpowered machine. +- Changed: Bottler now uses the liquid dictionary to dynamically populate its recipe list. +- Changed: Seed oil output has been rebalanced, reducing it further on easily obtainable seeds. +- Changed: Several changes to the default traits of several tree species. +- Changed: Sapling yield in the fermenter has changed. The amount of biomass produced from a single sapling is now determined by the sappiness trait on it. Saplings without genetic information are treated as though they have lowest sappiness. +- Changed: Adapted to new vanilla bonemeal behaviour for saplings. +- Changed: Added squeezable lemons and plums. (Sprites for both by Xizzzy.) +- Changed: Apple juice is now fruit juice. +- Changed: Increased the guaranteed drop from apatite by 1. Reduced the minimum world height required for apatite to spawn to 56. +- Changed: Reduced power requirements for farms a bit. +- Changed: Reduced fertilizer requirements on some of the more basic farms, including arboretum. +- Changed: Changed humus degradation behaviour. Now only degrades over time instead of on-growth of a tree. +- Changed: Drastically increased the potential generations artificial princesses ("swarmer princesses") can reproduce before genetic fatigue sets in. +- Changed: All work and no play makes the queen a dull girl: Forcing a queen to produce way too fast or trying too hard to mutate her may result in undesireable consequences. (Note: Only applies to outside factors, not to factors inherent in the queen's genetic makeup.) +- Changed: Minor improvements to treealyzer and to sapling tooltips. \ No newline at end of file diff --git a/forestry_resources/changelog/2.2.0.1 b/forestry_resources/changelog/2.2.0.1 new file mode 100755 index 000000000..a802a8f5d --- /dev/null +++ b/forestry_resources/changelog/2.2.0.1 @@ -0,0 +1,11 @@ + +#2.2.0.1 + +- Added: Sapling rate and yield to sapling tooltips. Extended tooltips on bees and saplings now hidden unless shift is pressed. +- Added: Papayas and dates can now be squeezed for fruit juice and/or mulch. +- Bugfix: Vanilla hoppers will now sort liquid cans through farm hatches. +- Bugfix: Biofuel now replaced by whatever the liquid dictionary returns. +- Bugfix: Fixed a crash when placing alveary hygroregulators. +- Bugfix: Fixed registration of analyzer recipes. +- Bugfix: Fixed mahoe having an incorrect sappiness allele. +- Bugfix: Fixed treealyzer not rating sapling rate, yield and maturity correctly. \ No newline at end of file diff --git a/forestry_resources/changelog/2.2.0.2 b/forestry_resources/changelog/2.2.0.2 new file mode 100755 index 000000000..1398a000d --- /dev/null +++ b/forestry_resources/changelog/2.2.0.2 @@ -0,0 +1,10 @@ + +#2.2.0.2 + +- Changed: Slight boost to output on clockwork engines. +- Changed: Biofuel is now ethanol. +- Changed: Ethanol burns at 4 MJ/t in a combustion engine for 60.000 ticks. (Biofuel was 5 MJ/t for 40.000 ticks.) +- Changed: Bio Generator produces 32 EU/t for 4000 ticks per bucket of ethanol. (Biofuel was 32 EU/t for 2000 ticks.) +- Changed: Honey is now worth 2 MJ/t in a biogas engine at 10.000 ticks. (1 MJ/t for 10.000 ticks previously.) +- Bugfix: Fixed still consuming filled cans when running out of empty cans. +- Bugfix: Fixed a crashbug in the treealyzer when a tree with different amounts of tolerances on primary and secondary allele had been bred. \ No newline at end of file diff --git a/forestry_resources/changelog/2.2.2.0 b/forestry_resources/changelog/2.2.2.0 new file mode 100755 index 000000000..2c8096406 --- /dev/null +++ b/forestry_resources/changelog/2.2.2.0 @@ -0,0 +1,9 @@ + +#2.2.2.0 + +- Upgraded: Minecraft 1.5.2. (May work on 1.5.1, unsupported.) +- Added: OP game mode. +- Changed: Sprite for royal jelly by niel. +- Changed: Handling grafters differently to re-enable normal leaf drops. A grafter may give an additional sapling now at the usual drop rate. +- Changed: Boosted proven grafter to 150 uses. +- Bugfix: Fixed an issue which caused planting in arboretums to become irregular. \ No newline at end of file diff --git a/forestry_resources/changelog/2.2.2.1 b/forestry_resources/changelog/2.2.2.1 new file mode 100755 index 000000000..eed91266b --- /dev/null +++ b/forestry_resources/changelog/2.2.2.1 @@ -0,0 +1,11 @@ + +# 2.2.2.1 + +- Added: Use the new mail order catalogue to browse trade stations on your server. Click 'Use' and open a new letter to have the address filled in. Crafted using a stamp and a book. +- Changed: Increased the default yield on some tree species. Made high yield attainable. +- Changed: Three letters of any state or size can now be converted to a piece of paper. Use to recycle at will. +- Bugfix: Bee houses now drop their contents when broken. +- Bugfix: Fixed title display in trade station gui. +- Bugfix: Fixed letter gui being cut off at the bottom. +- Bugfix: Fixed the arborist potentially selling an invalid wood plank. +- Bugfix: Fixed recipient type being changeable on sent letters. \ No newline at end of file diff --git a/forestry_resources/changelog/2.2.2.2 b/forestry_resources/changelog/2.2.2.2 new file mode 100755 index 000000000..9482840f2 --- /dev/null +++ b/forestry_resources/changelog/2.2.2.2 @@ -0,0 +1,8 @@ + +# 2.2.2.2 + +- Added: Nether quartz to miner's backpack. +- Added: To builder's backpack: All remaining stairs, slabs, planks, fences, quartz blocks, emerald block, stone walls, candles. +- Added: To forester's backpack: Remaining logs. +- Bugfix: Fixed a crash when no matching/active trade stations where found. +- Bugfix: Fixed a crash when placing a vanilla hopper below a carpenter. \ No newline at end of file diff --git a/forestry_resources/changelog/2.2.4.0 b/forestry_resources/changelog/2.2.4.0 new file mode 100755 index 000000000..264e8849c --- /dev/null +++ b/forestry_resources/changelog/2.2.4.0 @@ -0,0 +1,11 @@ + +#2.2.4.0 + +- Added: Alveary sieve to filter out pollen collected by bees. Requires woven silk as sieve material. Sieve material is destroyed and needs to be replaced when removing any pollen from the sieve. +- Added: Fertile pollen. Contains the same genetic information as saplings and can be applied directly to leaves. +- Added: Butterflies as collectible items. Forestry trees now occasionally spawn butterflies. The type of butterfly spawned depends on several factors, including biome. Butterflies do not yet serve a purpose. They are however pretty. +- Added: Flutterlyzer to take a look at the genetic traits of butterflies. You cannot breed butterflies yet though, so this serves only informational purposes. +- Changed: Rewrote certain mutations to be compatible with biome mods. (Rural, Heroic.) (RichardG) +- Changed: Fixed some textures to reduce seams on render models. +- Bugfix: Stairs can now be placed upside down. +- Bugfix: Fixed a carpenter dupe bug. \ No newline at end of file diff --git a/forestry_resources/changelog/2.2.4.1 b/forestry_resources/changelog/2.2.4.1 new file mode 100755 index 000000000..ff1168c7a --- /dev/null +++ b/forestry_resources/changelog/2.2.4.1 @@ -0,0 +1,8 @@ + +# 2.2.4.1 + +- Added: Lepidopterist's chest and backpack. +- Added: More butterflies. +- Changed: Butterflies now pollinate tree leaves. +- Bugfix: Butterflies are less interested in drowning themselves. +- Bugfix: Removed some orphaned debug output. \ No newline at end of file diff --git a/forestry_resources/changelog/2.2.4.2 b/forestry_resources/changelog/2.2.4.2 new file mode 100755 index 000000000..9eb517bb3 --- /dev/null +++ b/forestry_resources/changelog/2.2.4.2 @@ -0,0 +1,7 @@ + +#2.2.4.2 + +- Bugfix: Fixed a crash when bees try to pollinate. +- Bugfix: Fixed butterfly rendering inside item frames. + +- Updated: Localizations by crafteverywhere, VeryBigBro and mariogrip. \ No newline at end of file diff --git a/forestry_resources/changelog/2.2.4.3 b/forestry_resources/changelog/2.2.4.3 new file mode 100755 index 000000000..e6b9ba17e --- /dev/null +++ b/forestry_resources/changelog/2.2.4.3 @@ -0,0 +1,9 @@ + +#2.2.4.3 + +- Added: More butterflies. +- Updated: IC2 API. +- Changed: Only the most common butterfly species are shown in creative menu. +- Changed: Butterflies now have a minimum cooldown period between pollinations and egg laying. +- Changed: Butterflies will flee from players. Sneak to creep close enough for the scoop. +- Bugfix: Fixed the alveary sometimes dropping a seemingly invalid block when broken. \ No newline at end of file diff --git a/forestry_resources/changelog/2.2.6.0 b/forestry_resources/changelog/2.2.6.0 new file mode 100755 index 000000000..844f9c629 --- /dev/null +++ b/forestry_resources/changelog/2.2.6.0 @@ -0,0 +1,11 @@ + +#2.2.6.0 + +- Added: Escritoire to analyze butterflies, bees and saplings. If you are successful in your research, you have a chance to get hints on future mutations or other loot. +- Added: Research notes can be right clicked to memorize them. Memorizing a research note will enter the information into your apiarist's chests and other databases. +- Added: More butterflies. (3 courtesy of MysteriousAges) +- Changed: Stationary analyzer now accepts butterflies. +- Bugfix: Fixed an issue were adding other mods could cause miner backpacks to not pick up certain mod ores. (Thanks to AlgorithmX2!) +- Bugfix: Fixed rendering and network synch in stationary analyzer. +- Bugfix: Fixed an issue loading older carpenters. +- Bugfix: Fixed planks puchased from a villager placing as a different type. \ No newline at end of file diff --git a/forestry_resources/changelog/2.2.6.1 b/forestry_resources/changelog/2.2.6.1 new file mode 100755 index 000000000..508b9cfd9 --- /dev/null +++ b/forestry_resources/changelog/2.2.6.1 @@ -0,0 +1,8 @@ + +#2.2.6.1 + +- Added: Worktable. Remembers the last eight recipes used. Right-click on a memorized recipe to lock it. +- Added: More butterflies. +- Bugfix: Fixed a crash when shift-clicking out of an escritoire. +- Bugfix: Fixed fermenter manager adding broken recipes when a certain API function was used. +- Bugfix: Added additional check to prevent an ExtraBees crash. \ No newline at end of file diff --git a/forestry_resources/changelog/2.2.6.2 b/forestry_resources/changelog/2.2.6.2 new file mode 100755 index 000000000..1d40bfc23 --- /dev/null +++ b/forestry_resources/changelog/2.2.6.2 @@ -0,0 +1,7 @@ + +#2.2.6.2 + +- Bugfix: Fixed handling of container items (buckets) in the worktable. +- Bugfix: Fixed handling of crafting equivalency (ore dictionary) in the worktable. +- Bugfix: Fixed a crash when the server could not keep up with client clicks in the worktable. +- Bugfix: Fixed a text issue which could occur on tabs. \ No newline at end of file diff --git a/forestry_resources/changelog/2.2.6.3 b/forestry_resources/changelog/2.2.6.3 new file mode 100755 index 000000000..a25e28ea9 --- /dev/null +++ b/forestry_resources/changelog/2.2.6.3 @@ -0,0 +1,10 @@ + +#2.2.6.3 + +- Added: More butterflies. +- Changed: Worktable now handles damageable crafting tools (minium stone). +- Changed: Fruit pods can now be bonemealed. (Binnie) +- Changed: Catching butterflies is now actually recorded. +- Bugfix: Ensured that broken fruit leaves don't hang the game. +- Bugfix: Fixed shift-clicking into internal inventory of the worktable. +- Bugfix: Fixed papaya and date pods not dropping fruits. \ No newline at end of file diff --git a/forestry_resources/changelog/2.2.8.2 b/forestry_resources/changelog/2.2.8.2 new file mode 100755 index 000000000..d322b1a2d --- /dev/null +++ b/forestry_resources/changelog/2.2.8.2 @@ -0,0 +1,14 @@ + +#2.2.8.2 + +- Changed: Bees requiring hellish biome should now accept all types of nether biomes. +- Bugfix: Fixed leaves only dropping fruits in orchards or on natural despawn. +- Bugfix: Fixed bottler not accepting any liquid container. +- Bugfix: Fixed an issue with naturally nocturnal bees. +- Bugfix: Fixed engines not outputting to BuildCraft's new wooden conductive pipes. +- Bugfix: Fixed a crash in the apiarist's pipe gui. +- Bugfix: Fixed a crash on cyclic recipes in the worktable. +- Bugfix: Fixed slightly incorrect size on the carpenter gui. +- Bugfix: Fixed an issue which caused stacks in fabricator inventory to be eaten entirely, regardless of actually needed resources. +- Bugfix: Possibly fixed framerate issues with spectacles on SMP. +- Bugfix: Fixed an issue which caused OP mode to handle fertilizer in MultiFarms incorrectly. diff --git a/forestry_resources/changelog/2.2.8.3 b/forestry_resources/changelog/2.2.8.3 new file mode 100755 index 000000000..73bd02482 --- /dev/null +++ b/forestry_resources/changelog/2.2.8.3 @@ -0,0 +1,17 @@ + +#2.2.8.3 + +- Changed: Fertilizer can now be used as bonemeal. +- Changed: Memorizing research notes now also discovers the resulting species. +- Changed: Changed power perdition in machines to conform to new BC defaults and increased the minimum power required for input to make sure even low-energy engines can overcome the power loss. +- Changed: Species are now discovered when analyzing a specimen in tree-/bee-/flutterlyzer. (Binnie) +- Changed: Still is now meta sensitive. (Binnie) +- Changed: Worktable will now always craft the Forestry bronze recipe, unless it has been disabled in config. +- Changed: Logs now rotate according to side they are placed on, not according to view of the player. +- Bugfix: Fixed stalled biogas engines not losing heat. +- Bugfix: Fixed an issue which caused crafting to be impossible in fabricator and worktable if there was a valid itemstack without sufficient stacksize, blocking other valid itemstacks. +- Bugfix: Fixed leaves not destroying snow when despawning. +- Bugfix: Fixed an issue which may have caused items registered multiple times in the ore dictionary to not be recognized as crafting equivalents. +- Bugfix: Putting a stack of circuit boards into electric engines or multifarms will not eat the whole stack anymore. +- Bugfix: Fixed an issue which caused bio generators to disconnect from wires on save/reload. +- Localizations: Several updates to localizations by contributors. \ No newline at end of file diff --git a/forestry_resources/changelog/2.2.8.4 b/forestry_resources/changelog/2.2.8.4 new file mode 100755 index 000000000..b444dce47 --- /dev/null +++ b/forestry_resources/changelog/2.2.8.4 @@ -0,0 +1,9 @@ + +#2.2.8.4 + +- Changed: Bee Houses now triple the pollination speed of bees compared to apiaries and alvearies. +- Changed: Made arboretums pick up cocoa beans. +- Changed: Removed GregTech nag, since it doesn't interfere currently. +- Bugfix: Some fixes to pick block. +- Bugfix: Fixed bronze recipe not displaying in CraftGuide. +- Bugfix: Added a null check to prevent a crash with corrupt saplings. \ No newline at end of file diff --git a/forestry_resources/changelog/2.3.0.0 b/forestry_resources/changelog/2.3.0.0 new file mode 100755 index 000000000..3b3e23b4e --- /dev/null +++ b/forestry_resources/changelog/2.3.0.0 @@ -0,0 +1,6 @@ + +#2.3.0.0 + +- Updated: Minecraft 1.6.2. +- Updated: BC API to 4.0.1. +- Changed: Swarmer bees are gone - in a way. There are now queens of "Ignoble Stock" and "Pristine Stock". Pristine Stock: As before, but cannot be "infected" through mating with other drones. They make up ~ 20 % of the bee population. "Ignoble Stock": These have a low chance to die off. The mortality chance can be reduced via frames. They will never die off in bee houses. Amount of generations lived does not affect the chance to die off anymore. \ No newline at end of file diff --git a/forestry_resources/changelog/2.3.0.1 b/forestry_resources/changelog/2.3.0.1 new file mode 100755 index 000000000..a81c48149 --- /dev/null +++ b/forestry_resources/changelog/2.3.0.1 @@ -0,0 +1,10 @@ + +#2.3.0.1 + +- Bugfix: Fixed issue which caused items ejected into BuildCraft pipes to disappear. +- Bugfix: Fixed a stacking issue which could occur after analyzing bees, saplings and/or butterflies. +- Bugfix: Fixed hopper interaction on the fermenter. +- Bugfix: Fixed crafting results slots in carpenter and fabricator not showing products. +- Bugfix: Fixed a rainmaker crash. +- Bugfix: Fixed stairs rendering incorrectly when held in hand. +- Localizations: Several updates by contributors. (See https://github.com/SirSengir/Forestry-Localization/commits/master for details.) \ No newline at end of file diff --git a/forestry_resources/changelog/2.3.0.2 b/forestry_resources/changelog/2.3.0.2 new file mode 100755 index 000000000..15234fa78 --- /dev/null +++ b/forestry_resources/changelog/2.3.0.2 @@ -0,0 +1,3 @@ + +#2.3.0.2 +- Bugfix: Adding correct handling of Village MapGenStructure stuff to make Forestry not crash on 1.6.4 \ No newline at end of file diff --git a/forestry_resources/changelog/2.3.0.3 b/forestry_resources/changelog/2.3.0.3 new file mode 100755 index 000000000..7340b0911 --- /dev/null +++ b/forestry_resources/changelog/2.3.0.3 @@ -0,0 +1,5 @@ + +#2.3.0.3 +- Bugfix: Correcting lockups that occur when Peat-Fired engines attempt to dump ash into a nearby pipe. +- Bugfix: Ignoble bees do not die off if their generation count is too low. +- Bugfix: Analyzer block properly accepts liquid Honey from fluid pipes. \ No newline at end of file diff --git a/forestry_resources/changelog/2.3.0.4 b/forestry_resources/changelog/2.3.0.4 new file mode 100755 index 000000000..1e823c38a --- /dev/null +++ b/forestry_resources/changelog/2.3.0.4 @@ -0,0 +1,14 @@ + +#2.3.0.4 +- Change: Cut fuel values in 1/4 to align with Railcraft, IndustrialCraft standards. (From CovertJaguar) Config values available. +- Change: Making Hive spawning depend directly on Biome's temperature/humidity rather than relying on cached values. Should allow hives to spawn correctly with other biome mods such as Highlands. +- Bugfix: Adding null checks to avoid an NPE in EntityBeeFX +- Bugfix: Breaking a Farm block causes a block update. This should prevent floating levers and torches. +- Bugfix: Adding null checks in Letter code to avoid an NPE if the item is spam-right-clicked. +- Bugfix: Frames are no longer enchantable to prevent misleading enchantments on frames. (They were never checked anyway.) +- Bugfix: Multifarm Hatch should now respect ISidedInventory +- Bugfix: Preventing NPEs while listening for OreDictionary registrations that come "too soon" +- Bugfix: TileHatch should now respect ISidedInventory when outputting items to an adjacent inventory. +- Added: Squeezer recipes for Natura barley & cotton seeds -> Seed oil at same rate as wheat seeds. +- Added: Squeezer recipes for Natura berries (Overworld & Nether varieties) -> Fruit Juice at 1/25th rate as Apples +- API: Adding methods for converting from Minecraft raw temperature/rainfall into EnumTemperature & EnumHumidity \ No newline at end of file diff --git a/forestry_resources/changelog/2.3.0.5 b/forestry_resources/changelog/2.3.0.5 new file mode 100755 index 000000000..155bfe8cc --- /dev/null +++ b/forestry_resources/changelog/2.3.0.5 @@ -0,0 +1,9 @@ + +#2.3.0.5 +- Bugfix: Typo in config string (CovertJaguar) +- Bugfix: Changing missing config value defaults to -1 to prevent random interactions (CovertJaguar) +- Bugfix: Prevents farm blocks from "flashing" before settling on their correct texture (CovertJaguar) +- Bugfix: Fixed issue with GUI Rendering prorgess bars in the wrong order (CovertJaguar) +- Bugfix: Changing handling of container inventories on some devices (CovertJaguar) +- Change: Fixing up particle rendering system to use distance culling and *nix dev paths (Player) +- Change: Fixed egregious oversight where feature was missing for this time of year. >.> \ No newline at end of file diff --git a/forestry_resources/changelog/2.3.0.6 b/forestry_resources/changelog/2.3.0.6 new file mode 100755 index 000000000..630a32aa1 --- /dev/null +++ b/forestry_resources/changelog/2.3.0.6 @@ -0,0 +1,9 @@ + +#2.3.0.6 +- Change: Plugin Loader errors are now silent. +- Bugfix: Removing references to BuildCraft's SlotOutput +- Bugfix: Biogas Engine fuel usage +- Change: Apiarist's Pipe updated for revision of BC pipes +- Change: Fixing power cycles for all machines +- Change: Engines no longer show negative temperature values. +- Bugfix: BuildCraft gate triggers have unique names, and should not crash. \ No newline at end of file diff --git a/forestry_resources/changelog/2.3.0.7 b/forestry_resources/changelog/2.3.0.7 new file mode 100755 index 000000000..ab14e9aae --- /dev/null +++ b/forestry_resources/changelog/2.3.0.7 @@ -0,0 +1,13 @@ + +#2.3.0.7 +- New: Clicking on the book in a Worktable will reset the grid. (CovertJaguar) +- New: Candles can now be dyed in-world. +- Change: Habitat Locator is being removed; it's broken, probably won't be fixed soon, and buggers up other icons. +- Change: Added probe button to Escritoire to give the user more control. (CovertJaguar) +- Change: Fixing derpy progress arrow in squeezer drawing over top of tank contents. +- Change: Beekeeping Mode's lifespan modifier now being correctly observed. +- Bugfix: Fixed derpy Escritoire network sync. (CovertJaguar) +- Bugfix: Fix Fermenter wasting excess production. (Player) +- Bugfix: Threaded version checker. (CovertJaguar) +- Bugfix: Various improvements to the Worktable (CovertJaguar) +- Bugfix: Improve Carpenter and Fermenter interactions with BC Gates by removing ISpecialInventory. (CovertJaguar) diff --git a/forestry_resources/changelog/2.3.1.0 b/forestry_resources/changelog/2.3.1.0 new file mode 100755 index 000000000..e3265dea9 --- /dev/null +++ b/forestry_resources/changelog/2.3.1.0 @@ -0,0 +1,11 @@ + +#2.3.1.0 +* Added: Loot chest spawns in Villager homes. You may find (somewhat) useful Forestry items in them! +* Bugfix: Apiarist Backpacks now properly save their contents when flipping pages preventing dupes/missing items. +* Bugfix: Languages other than en_US should now work properly. +* Bugfix: Worktable should now orient correctly (CovertJaguar) +* Bugfix: All Items are now registered with FML, you must install this version or newer before upgrading your world to 1.7. (CovertJaguar) +* Change: Working around Forge problem that prevents the crafting of Forestry's wooden slabs & stairs. +* Change: Railcraft integration for Ethanol has been moved into Railcraft configs. (CovertJaguar) +* API: Adding package-info to API to use the new protection in Forge +* API: Exposing 2 villager IDs and the naturalist chest gen hook key via IForestryConstants. \ No newline at end of file diff --git a/forestry_resources/changelog/2.3.1.1 b/forestry_resources/changelog/2.3.1.1 new file mode 100755 index 000000000..d0ed0f600 --- /dev/null +++ b/forestry_resources/changelog/2.3.1.1 @@ -0,0 +1,14 @@ + +#2.3.1.1 +Bugfix: Merry Bee snow effect no longer has the pink 'HAY U R MISSING TAXTURE!!!1!!1' thing. (CovertJaguar) +Bugfix: Player inventory updates when clicking with bucket. (CovertJaguar) +Bugfix: Backpacks should obey inventory restrictions. (CovertJaguar) +Bugfix: Short Mead no longer crashes. (CovertJaguar) +Bugfix: Tipsy Bee is not breedable on Jan 1st (CovertJaguar) +Bugfix: Merry Bees Snow Effect now works and leaves snow on the ground. (CovertJaguar) +Change: Drones do not carry Pristine/Ignoble traits. This should make the jerks stack better. +Change: Beealyzer now displays "Pristine/Ignoble Stock" for bees rather than "Natural/Artificial origin". In addition, stock type is not shown for drones. +Change: Attempt to reduce the number of Chunk Renderers. (CovertJaguar) +Change: Added Dropper & Dispenser to builder's backpack by default (CovertJaguar) +Change: Sandstone items added to backpacks (CovertJaguar) +Change: Silk Touch no longer works on Humus, Bog Earth or Peat. \ No newline at end of file diff --git a/forestry_resources/changelog/2.4.0.0 b/forestry_resources/changelog/2.4.0.0 new file mode 100755 index 000000000..63683c627 --- /dev/null +++ b/forestry_resources/changelog/2.4.0.0 @@ -0,0 +1,4 @@ +Bugfix: IC2 item crates are correctly being added if the item exists. +Bugfix: Naturalist's game should no longer produce AIOOB errors. +Port to Minecraft 1.7 + diff --git a/forestry_resources/config/forestry/colour.properties b/forestry_resources/config/forestry/colour.properties new file mode 100755 index 000000000..e8eda2cf5 --- /dev/null +++ b/forestry_resources/config/forestry/colour.properties @@ -0,0 +1,46 @@ +# Add a file of this format in your texture packs zip as +# /config/forestry/colour.properties to configure font colours. +# A file at that location inside the zip of the active texture pack +# will take precedence over the default. +# +# Hex format without leading 0x + +gui.title=404040 +gui.screen=ffffff +gui.table.header=ababab +gui.table.row=ababab +gui.book=000000 + +gui.beealyzer.binomial=14d50b +gui.beealyzer.recessive=3687ec +gui.beealyzer.dominant=ec3661 + +gui.mail.lettertext=cfa738 +gui.mail.text=6689dc + +ledger.error.background=ff3535 +ledger.error.header=e1c92f +ledger.error.text=000000 + +ledger.hint.background=ea38ff +ledger.hint.header=e1c92f +ledger.hint.text=000000 + +ledger.owner.header=e1c92f +ledger.owner.subheader=aaafb8 +ledger.owner.text=000000 + +ledger.climate.background=35a4ff +ledger.climate.header=e1c92f +ledger.climate.subheader=aaafb8 +ledger.climate.text=000000 + +ledger.power.background=d46c1f +ledger.power.header=e1c92f +ledger.power.subheader=aaafb8 +ledger.power.text=000000 + +ledger.farm.background=2ca22c +ledger.farm.header=e1c92f +ledger.farm.subheader=aaafb8 +ledger.farm.text=000000 diff --git a/forestry_resources/config/forestry/gamemodes/HARD.conf b/forestry_resources/config/forestry/gamemodes/HARD.conf new file mode 100755 index 000000000..b3bf54171 --- /dev/null +++ b/forestry_resources/config/forestry/gamemodes/HARD.conf @@ -0,0 +1,95 @@ +# Forestry +# @VERSION@ (@BUILD_NUMBER@) +# +# Config files: +# base.conf - Contains Forge configuration for block and item ids +# common.conf - Contains all options common to Forestry +# apiculture.conf - Contains all options for bee breeding +# backpacks.conf - Contains custom configurations for backpacks +# pipes.conf - Configures item id for the apiarist's pipe +# gamemodes/ - Configures available gamemodes + +##################### +# ENERGY +##################### +# modifies the energy required to activate machines, as well as the max amount of energy stored and accepted. +energy.demand.modifier=4.0 +# set to false to disable the clockwork engine. +energy.engine.clockwork=true + + +##################### +# FUEL +##################### +# modifies the energy provided by ethanol in a Bio Generator. +fuel.ethanol.generator=0.5 +# modifies the energy provided by ethanol in Buildcraft Combustion Engines. +fuel.ethanol.combustion=0.5 +# modifies the energy provided by Biomass in a Bio Generator. +fuel.biomass.generator=0.5 +# modifies the energy provided by Biomass in Biogas Engines. +fuel.biomass.biogas=0.5 + + +##################### +# FARMS +##################### +# modifies the time fertilizer lasts in a farm. +farms.fertilizer.value=500 + + +##################### +# FERMENTER +##################### +# modifies the amount of cycles a fertilizer can keep a fermenter going. +fermenter.cycles.fertilizer=100 +# modifies the amount of cycles compost can keep a fermenter going. +fermenter.cycles.compost=150 +# modifies the amount of biomass per cycle a fermenter will produce using fertilizer. +fermenter.value.fertilizer=56 +# modifies the amount of biomass per cycle a fermenter will produce using compost. +fermenter.value.compost=48 +# modifies the amount of biomass a sapling will yield in a fermenter. +fermenter.yield.sapling=50 +# modifies the amount of biomass a piece of cactus will yield in a fermenter. +fermenter.yield.cactus=10 +# modifies the amount of biomass a piece of wheat will yield in a fermenter. +fermenter.yield.wheat=10 +# modifies the amount of biomass a mushroom will yield in a fermenter. +fermenter.yield.mushroom=10 +# modifies the amount of biomass a piece of sugar cane will yield in a fermenter. +fermenter.yield.cane=10 + + +##################### +# RECIPE +##################### +# amount of fertilizer yielded by the recipe using apatite. +recipe.output.fertilizer.apatite=5 +# amount of fertilizer yielded by the recipe using ash. +recipe.output.fertilizer.ash=0 +# amount of bog earth yielded by the recipe using buckets. +recipe.output.bogearth.bucket=4 +# amount of bog earth yielded by the recipes using cans, cells or capsules. +recipe.output.bogearth.can=5 +# amount yielded by the recipe for tin cans. +recipe.output.can=8 +# amount yielded by the recipe for wax capsules. +recipe.output.capsule=2 +# amount yielded by the recipe for refractory capsules. +recipe.output.refractory=2 +# amount of compost yielded by the recipe using wheat. +recipe.output.compost.wheat=1 +# amount of compost yielded by the recipe using ash. +recipe.output.compost.ash=1 +# amount of humus yielded by the recipe using fertilizer. +recipe.output.humus.fertilizer=8 +# amount of humus yielded by the recipe using compost. +recipe.output.humus.compost=8 + + +##################### +# SQUEEZER +##################### +# modifies the amount of seed oil squeezed from a single seed. +squeezer.liquid.seed=3 diff --git a/forestry_resources/config/forestry/gamemodes/NORMAL.conf b/forestry_resources/config/forestry/gamemodes/NORMAL.conf new file mode 100755 index 000000000..b1a5f8f78 --- /dev/null +++ b/forestry_resources/config/forestry/gamemodes/NORMAL.conf @@ -0,0 +1,96 @@ +# Forestry +# @VERSION@ (@BUILD_NUMBER@) +# +# Config files: +# base.conf - Contains Forge configuration for block and item ids +# common.conf - Contains all options common to Forestry +# apiculture.conf - Contains all options for bee breeding +# backpacks.conf - Contains custom configurations for backpacks +# pipes.conf - Configures item id for the apiarist's pipe +# gamemodes/ - Configures available gamemodes + +##################### +# ENERGY +##################### +# modifies the energy required to activate machines, as well as the max amount of energy stored and accepted. +energy.demand.modifier=1.5 +# set to false to disable the clockwork engine. +energy.engine.clockwork=true + + +##################### +# FUEL +##################### +# modifies the energy provided by ethanol in a Bio Generator. +fuel.ethanol.generator=0.75 +# modifies the energy provided by ethanol in Buildcraft Combustion Engines. +fuel.ethanol.combustion=0.75 +# modifies the energy provided by Biomass in a Bio Generator. +fuel.biomass.generator=0.75 +# modifies the energy provided by Biomass in Biogas Engines. +fuel.biomass.biogas=0.75 + + +##################### +# FARMS +##################### +# modifies the time fertilizer lasts in a farm. +farms.fertilizer.value=1000 + + +##################### +# FERMENTER +##################### +# modifies the amount of cycles a fertilizer can keep a fermenter going. +fermenter.cycles.fertilizer=150 +# modifies the amount of cycles compost can keep a fermenter going. +fermenter.cycles.compost=200 +# modifies the amount of biomass per cycle a fermenter will produce using fertilizer. +fermenter.value.fertilizer=56 +# modifies the amount of biomass per cycle a fermenter will produce using compost. +fermenter.value.compost=48 +# modifies the amount of biomass a sapling will yield in a fermenter. +fermenter.yield.sapling=100 +# modifies the amount of biomass a piece of cactus will yield in a fermenter. +fermenter.yield.cactus=25 +# modifies the amount of biomass a piece of wheat will yield in a fermenter. +fermenter.yield.wheat=25 +# modifies the amount of biomass a mushroom will yield in a fermenter. +fermenter.yield.mushroom=25 +# modifies the amount of biomass a piece of sugar cane will yield in a fermenter. +fermenter.yield.cane=25 + + +##################### +# RECIPE +##################### +# amount of fertilizer yielded by the recipe using apatite. +recipe.output.fertilizer.apatite=6 +# amount of fertilizer yielded by the recipe using ash. +recipe.output.fertilizer.ash=10 +# amount of bog earth yielded by the recipe using buckets. +recipe.output.bogearth.bucket=4 +# amount of bog earth yielded by the recipes using cans, cells or capsules. +recipe.output.bogearth.can=6 +# amount yielded by the recipe for tin cans. +recipe.output.can=10 +# amount yielded by the recipe for wax capsules. +recipe.output.capsule=3 +# amount yielded by the recipe for refractory capsules. +recipe.output.refractory=3 +# amount of compost yielded by the recipe using wheat. +recipe.output.compost.wheat=2 +# amount of compost yielded by the recipe using ash. +recipe.output.compost.ash=1 +# amount of humus yielded by the recipe using fertilizer. +recipe.output.humus.fertilizer=8 +# amount of humus yielded by the recipe using compost. +recipe.output.humus.compost=8 + + +##################### +# SQUEEZER +##################### +# modifies the amount of seed oil squeezed from a single seed. +squeezer.liquid.seed=5 + diff --git a/forestry_resources/config/forestry/gamemodes/OP.conf b/forestry_resources/config/forestry/gamemodes/OP.conf new file mode 100755 index 000000000..4e3261c68 --- /dev/null +++ b/forestry_resources/config/forestry/gamemodes/OP.conf @@ -0,0 +1,99 @@ +# Forestry +# @VERSION@ (@BUILD_NUMBER@) +# +# Config files: +# base.conf - Contains Forge configuration for block and item ids +# common.conf - Contains all options common to Forestry +# apiculture.conf - Contains all options for bee breeding +# backpacks.conf - Contains custom configurations for backpacks +# pipes.conf - Configures item id for the apiarist's pipe +# gamemodes/ - Configures available gamemodes + +##################### +# ENERGY +##################### +# modifies the energy required to activate machines, as well as the max amount of energy stored and accepted. +energy.demand.modifier=1.0 +# set to false to disable the clockwork engine. +energy.engine.clockwork=true + + +##################### +# FUEL +##################### +# modifies the energy provided by ethanol in a Bio Generator. +fuel.ethanol.generator=4.0 +# modifies the energy provided by ethanol in Buildcraft Combustion Engines. +fuel.ethanol.combustion=4.0 +# modifies the energy provided by Biomass in a Bio Generator. +fuel.biomass.generator=4.0 +# modifies the energy provided by Biomass in Biogas Engines. +fuel.biomass.biogas=4.0 + + +##################### +# FARMS +##################### +# modifies the time fertilizer lasts in a farm. +farms.fertilizer.value=-1 + + +##################### +# FERMENTER +##################### +# modifies the amount of cycles fertilizer can keep a fermenter going. +fermenter.cycles.fertilizer=800 +# modifies the amount of cycles compost can keep a fermenter going. +fermenter.cycles.compost=1000 +# modifies the amount of biomass per cycle a fermenter will produce using fertilizer. +fermenter.value.fertilizer=224 +# modifies the amount of biomass per cycle a fermenter will produce using compost. +fermenter.value.compost=192 +# modifies the base amount of biomass a sapling will yield in a fermenter, affected by sappiness trait. (max: 2000) +fermenter.yield.sapling=2000 +# modifies the amount of biomass a piece of cactus will yield in a fermenter. (max: 400) +fermenter.yield.cactus=400 +# modifies the amount of biomass a piece of wheat will yield in a fermenter. (max: 400) +fermenter.yield.wheat=400 +# modifies the amount of biomass a piece of sugar cane will yield in a fermenter. (max: 400) +fermenter.yield.cane=400 +# modifies the amount of biomass a mushroom will yield in a fermenter. (max: 400) +fermenter.yield.mushroom=400 + + +##################### +# RECIPE +##################### +# amount of fertilizer yielded by the recipe using apatite. +recipe.output.fertilizer.apatite=16 +# amount of fertilizer yielded by the recipe using ash. +recipe.output.fertilizer.ash=32 +# amount of compost yielded by the recipe using wheat. +recipe.output.compost.wheat=8 +# amount of compost yielded by the recipe using ash. +recipe.output.compost.ash=2 +# amount of humus yielded by the recipe using fertilizer. +recipe.output.humus.fertilizer=8 +# amount of humus yielded by the recipe using compost. +recipe.output.humus.compost=8 +# amount of bog earth yielded by the recipe using buckets. +recipe.output.bogearth.bucket=6 +# amount of bog earth yielded by the recipes using cans, cells or capsules. +recipe.output.bogearth.can=8 +# amount yielded by the recipe for tin cans. +recipe.output.can=24 +# amount yielded by the recipe for wax capsules. +recipe.output.capsule=8 +# amount yielded by the recipe for refractory capsules. +recipe.output.refractory=8 + + +##################### +# SQUEEZER +##################### +# modifies the amount of seed oil squeezed from a single seed. other sources are based off this. (max: 80) +squeezer.liquid.seed=80 +# modifies the amount of juice squeezed from a single apple. other sources are based off this. (max: 1600) +squeezer.liquid.apple=1600 +# modifies the chance of mulch per squeezed apple. (max: 160) +squeezer.mulch.apple=160 diff --git a/forestry_resources/config/forestry/hints.properties b/forestry_resources/config/forestry/hints.properties new file mode 100755 index 000000000..6ac981417 --- /dev/null +++ b/forestry_resources/config/forestry/hints.properties @@ -0,0 +1,21 @@ +alveary=accesscontrol;accessrules;accesspipe; +analyzer=nopowerrequired;accesscontrol;accessrules;accesspipe;pipette;flowerjungle;flowernether;apiaristsuit;honeyfood +apiarist.chest= +apiary=accesscontrol;accessrules;accesspipe;beebiomes;beebreeding;beejubilance;beeflowers;nopowerrequired;flowerjungle;flowernether;apiaristsuit;honeyfood +beealyzer= +bottler=powerrequired;accesscontrol;accessrules;accesspipe;pipette +carpenter=powerrequired;accesscontrol;accessrules;accesspipe;pipette;crating +centrifuge=powerrequired;accesscontrol;accessrules;accesspipe +engine.bronze=accesscontrol;accessrules;accesspipe;energyunit;energybuffer;pipette;enginebronzefuels;enginebronzeheatloss;enginebronzeoutput;enginebronzewaste +engine.copper=accesscontrol;accessrules;accesspipe;energyunit;energybuffer;forcedcooldown;cooldownloss;enginecopperfuels;usesofash;enginecopperwaste;manualpeat;peatharvest +engine.tin=accesscontrol;accessrules;accesspipe;energyunit;energybuffer;forcedcooldown;cooldownloss;enginetinbatteries;enginetinchoke +farm=accesscontrol;accessrules;accesspipe;farmland;gearbox;valve;fertilizer;hatch;circuitboard;manualfarms;farmgui +fermenter=powerrequired;accesscontrol;accessrules;accesspipe;pipette;shortmead +generator=accesscontrol;accessrules;accesspipe;energyunit;pipette;generatorfuels +habitatlocator= +letter=postage +mailbox=nopowerrequired;accesscontrol;accessrules;accesspipe;postage +moistener=nopowerrequired;accesscontrol;accessrules;accesspipe;pipette;moistenerproducts +raintank=powerraintank;accesscontrol;accessrules;accesspipe +squeezer=powerrequired;accesscontrol;accessrules;accesspipe;pipette +still=powerrequired;accesscontrol;accessrules;accesspipe;pipette \ No newline at end of file diff --git a/forestry_resources/lang/forestry/apiculture/en_US.properties b/forestry_resources/lang/forestry/apiculture/en_US.properties new file mode 100755 index 000000000..624a0f8ff --- /dev/null +++ b/forestry_resources/lang/forestry/apiculture/en_US.properties @@ -0,0 +1,163 @@ + +apiculture.effect.aggressive=Aggress. +apiculture.effect.beatific=Beatific +apiculture.effect.creeper=Creeper +apiculture.effect.exploration=Explorer +apiculture.effect.glacial=Freezing +apiculture.effect.heroic=Heroic +apiculture.effect.ignition=Flammable +apiculture.effect.misasmic=Poison +apiculture.effect.misanthrope=Ends +apiculture.effect.radioactive=Radioact. +apiculture.effect.drunkard=Drunkard +apiculture.effect.snowing=Snow +apiculture.effect.resurrection=Resurrection +apiculture.effect.reanimation=Reanimation +apiculture.effect.repulsion=Repulsion +bees.hybrid.adj.add= +bees.hyphen.adj.add= +bees.drone=Drone +bees.drone.adj.add= +bees.larvae=Larvae +bees.larvae.adj.add= +bees.princess=Princess +bees.princess.adj.add= +bees.queen=Queen +bees.queen.adj.add= +bees.stock.pristine=Pristine Stock +bees.stock.ignoble=Ignoble Stock +death.bee.end=%1$s was ended by an unfriendly sting. +death.bee.end.player=%1$s was ended by an unfriendly sting while fighting %2$s. +death.bee.radioactive=%1$s walked into Chernobyl without his helmet on. +death.bee.radioactive.player=%1$s walked into Chernobyl without his helmet on. %2$s watched and cackled. +death.bee.aggressive=%1$s encountered a swarm of bees. That had to sting. +death.bee.aggressive.player=%1$s encountered a swarm of bees. %2$s stole his apiarist's suit. +genus.bees.common=Common +genus.bees.noble=Noble +genus.bees.industrious=Industrious +genus.bees.heroic=Heroic +genus.bees.infernal=Infernal +genus.bees.austere=Austere +genus.bees.end=End +genus.bees.vengeful=Vengeful +genus.bees.tropical=Tropical +genus.bees.frozen=Frozen +genus.bees.reddened=Reddened +genus.bees.festive=Festive +genus.bees.agrarian=Agrarian +genus.bees.boggy=Boggy +genus.bees.monastic=Monastic +bees.species.forest=Forest +bees.species.meadows=Meadows +bees.species.common=Common +bees.species.cultivated=Cultivated +bees.species.noble=Noble +bees.species.majestic=Majestic +bees.species.imperial=Imperial +bees.species.diligent=Diligent +bees.species.unweary=Unweary +bees.species.industrious=Industrious +bees.species.steadfast=Steadfast +bees.species.valiant=Valiant +bees.species.heroic=Heroic +bees.species.sinister=Sinister +bees.species.fiendish=Fiendish +bees.species.demonic=Demonic +bees.species.modest=Modest +bees.species.frugal=Frugal +bees.species.austere=Austere +bees.species.tropical=Tropical +bees.species.exotic=Exotic +bees.species.edenic=Edenic +bees.species.ender=Ender +bees.species.wintry=Wintry +bees.species.icy=Icy +bees.species.glacial=Glacial +bees.species.vindictive=Vindictive +bees.species.vengeful=Vengeful +bees.species.avenging=Avenging +bees.species.darkened=Darkened +bees.species.reddened=Reddened +bees.species.omega=Omega +bees.species.leporine=Leporine +bees.species.tricky=Tricky +bees.species.rural=Rural +bees.species.marshy=Marshy +bees.species.merry=Merry +bees.species.tipsy=Tipsy +bees.species.monastic=Monastic +bees.species.secluded=Secluded +bees.species.hermitic=Hermitic +bees.species.spectral=Spectral +bees.species.phantasmal=Phantasmal +beemode.easy.desc=Simplifies beebreeding by drastically increasing mutation rate and removing the chance for genetic fatigue. +beemode.normal.desc=Recommended mode for the normal player. +beemode.hard.desc=Reducing mutation rate slightly while increasing lifespan of individual queens by 50 %. +beemode.hardcore.desc=Halves mutation rate, increases lifespan of individual queens by 500 % and reduces fertility by 20 %. +beemode.insane.desc=Cuts mutation rate to 20 %, increases lifespan tenfold and reduces fertility by 40 %. +description.speciesForest=One of the most common pests in forests; Mostly docile.|Beekeeping 101 +description.speciesMeadows=Infests mostly plains in temperate climates; Mostly docile.|Beekeeping 101 +description.speciesCommon=Considered the beginner apiarist's badge of participation.|Beekeeping 101 +description.speciesCultivated=Fast working bee; Thinks anything but opera is beneath it.|Beekeeping 101 +description.speciesNoble="There is no more noble occupation in the world than to breed another bee."|Binnie, Apiarist +description.speciesMajestic="Off with their heads!"|Queen of Hearts +description.speciesImperial=Highly sought after bee; Specialises in the production of precious royal jelly.|Beekeeping 101 +description.speciesDiligent=Mostly noted as a stepping stone for the industrious line of bees.|Beekeeping 101 +description.speciesUnweary=Unweary. Then they die.|Beekeeping 101 +description.speciesIndustrious=Highly sought after bee; Specialises in the production of exquisite pollen.|Beekeeping 101 +description.speciesSteadfast=Considered extinct until some were found by adventurers in a deep dungeon.|Apiarist's Grimoire +description.speciesValiant=A rare subspecies rarely seen cohabiting in mundane hives.|Apiarist's Grimoire +description.speciesHeroic=Elaborate legends have surrounded this species. Will defend its hive to its death against any hostiles.|Apiarist's Grimoire +description.speciesSinister=Not many bee species are able to survive in the nether. And even those are severly affected by their hellish environment.|Beekeeping 101 +description.speciesFiendish=Experienced nether apiarist's have been reporting severe attacks by their bees. Caution is advised.|Beekeeping 101 +description.speciesDemonic=Born in the fires of the nether and being a descendant of generations of nether bees has caused this species to turn into a true demon.|Beekeeping 101 +description.speciesModest=Hot and arid climates have forced this species to adapt to a degree which will not allow it to survive in significantly friendlier climates.|Beekeeping 101 +description.speciesFrugal=Generations of bees baked in the sun to produce this species.|Beekeeping 101 +description.speciesAustere=Dangerous and volatile; Beekeepers are advised to stay in full suit whenever near.|Beekeeping 101 +description.speciesTropical="My travels along the jungle river allowed me to catch many of these poisonous specimen. Unfortunately I had lost my only austere branch to crocodiles a while back."|Beekeeping 101 +description.speciesExotic="The fever shook me and my apiarist's suit was drenched with cold sweat, but with trembling hands I finally managed to pull one of these from my apiary."|Beekeeping 101 +description.speciesEdenic="I furiously scribbled in my notebook, drawing sketches of the images I felt seeping into my brain while I was watching the insects perform their strange little dance."|Beekeeping 101 +description.speciesWintry=Common, but winter-hardened bee tribe; Cultivation in warmer climates is a challenge.|Beekeeping 101 +description.speciesIcy=Temperatures inside hives inhabited by this species will drop until ice shards form.|Beekeeping 101 +description.speciesGlacial="Winter is coming!"|E. Stark, beekeeper +description.speciesVindictive="It ate my face! It ate my face!"|K.M. +description.speciesVengeful="Veni, vidi, vici!"|Apinus Julius Caesar +description.speciesAvenging="The walls of my house began to crumble and I heard the roof creaking over my head, but I cared not! I felt the stabs of a thousand little insects on my glove as I grabbed the new queen."|Anonymous +description.speciesDarkened=Attracted by the power of alchemically bound matter, this species was a powerful source of energy.|Beekeeper's Lexicon +description.speciesReddened=Requiring massive amounts of alchemically bound matter, these little fellows could flood a world in energy.|Beekeeper's Lexicon +description.speciesOmega="I am Alpha and Omega, the beginning and the end, the first and the last."|Pahimar, beekeeper +description.speciesLeporine="I swear! It was tiny, had wings and I definitely saw fluffy little rabbit ears! ... No! I am not drunk!"|"Sir" Sengir, madman +description.speciesMerry="Hohoho!"|Merry bee +description.speciesTipsy="Dance my pretties! Dance!"|Tipsy Witch of the East +description.speciesTricky="Trick or Tricky Treat!"|Tricky Bee +description.speciesRural="Rain in May promises much hay."|M. Ages, Rural Beekeeper +description.speciesMarshy="Seriously? Mushrooms? Get out of here!"|Beekeeping 101 +description.speciesMonastic="I remained austere and said to him: 'Not only a princess, but also a whole pile of emeralds for a measly drone? That's extortion!'|Beekeeping 101 +description.speciesSecluded="Crossbreeding with the desert kind was a mistake. My bees withdrew more and more from the outside world."|Beekeeping 101 +description.speciesHermitic="My dear colleague! I noticed the bees you sent me refuse to wash and are growing full beards. Care to explain?"|Binnie, Apiarist +description.speciesEnded="I found one of these seemingly hermitical insects in a villager's apiary. It was torpid, obviously ripped from its world and longing for a fragment from it."|Beekeeping 101 +description.speciesSpectral="I was unsure whether it was alive as it lay there in the palm of my hand, glimmering and pulsating, oozing a coldness I never felt before. Then I heard the pile of bones behind me rattle..."|Beekeeping 101 +description.speciesPhantasmal="Whatever you do, do not, I repeat, DO NOT drop the dragon e..."|"Sir" Sengir, Last Words +tile.alveary.0=Alveary +tile.alveary.2=Swarmer +tile.alveary.3=Alveary Fan +tile.alveary.4=Alveary Heater +tile.alveary.5=Alveary Hygroregulator +tile.alveary.6=Alveary Stabiliser +tile.alveary.7=Alveary Sieve +tile.beehives.1=Forest Hive +tile.beehives.2=Meadows Hive +tile.beehives.3=Modest Hive +tile.beehives.4=Tropical Hive +tile.beehives.5=Ender Hive +tile.beehives.6=Wintry Hive +tile.beehives.7=Marshy Hive +tile.candle.stump=Unlit Candle +tile.candle.dyed.stump=Unlit Dyed Candle +tile.candle.lit=Lit Candle +tile.candle.dyed.lit=Lit Dyed Candle +tile.stump.0=Candle Stump +tile.for.apiculture.0=Apiary +tile.for.apiculture.1=Apiarist's Chest +tile.for.apiculture.2=Bee House + diff --git a/forestry_resources/lang/forestry/arboriculture/en_US.properties b/forestry_resources/lang/forestry/arboriculture/en_US.properties new file mode 100755 index 000000000..182813f18 --- /dev/null +++ b/forestry_resources/lang/forestry/arboriculture/en_US.properties @@ -0,0 +1,69 @@ +gui.maturity=Matures +gui.treealyzer=Treealyzer +gui.treealyzer.help=Supply sapling and provide honey or honeydew as catalyst. +gui.treealyzer.overview=Analytics available +gui.saplings=Saplings +gui.yield=Yield +gui.sappiness=Sappiness +gui.height=Height +gui.fruits=Fruits +gui.supports=Supports +gui.family=Family +gui.girth=Girth +gui.native=Soil +gui.tolerated=Tolerates +gui.growth=Growth +description.treeOak=Common tree species whose apple-bearing properties are the subject of much song and dance.|Codex Lignum +description.treeBirch=Widespread birch tree, which on average is of smaller height.|Codex Lignum +description.treeLime=Tall, deciduous tree. It has been reclassified recently as being in the Malvaceae family.|Codex Lignum +description.treeWalnut=Tall, deciduous tree with large trunk. Naturally occuring walnut trees carry fruits which require some time to ripe.|Codex Lignum +description.treeChestnut=Tall, deciduous tree with large trunk. Naturally occuring chestnut trees carry fruits which require some time to ripe.|Codex Lignum +description.treeSipiri=Tall, evergreen trees with valuable timber. Wood and bark are pleasantly scented. Will only thrive in tropical climes.|Codex Lignum +description.treeWillow=Large, deciduous tree. White willows are fast-growing. Have only been observed to occur in damp climates.|Codex Lignum +description.treeCherry=Small tree. In its natural form it will bear cherries which will need to undergo a ripening period.|Codex Lignum +family.pomes=Pomes +family.prunes=Prunes +family.nuts=Nuts +family.jungle=Jungle +fruits.apple=Apple +fruits.cherry=Cherry +fruits.chestnut=Chestnut +fruits.walnut=Walnut +fruits.cocoa=Cocoa +fruits.none=None +fruits.plum=Plum +fruits.lemon=Lemon +fruits.dates=Dates +fruits.papaya=Papaya +item.grafter=Grafter +item.grafterProven=Proven Grafter +tile.log=Wood +tile.planks=Wood Planks +tile.slab=Wood Slab +tile.fences=Fence +tile.for.stairs=Stairs +wood.0=Larch +wood.1=Teak +wood.2=Acacia +wood.3=Lime +wood.4=Chestnut +wood.5=Wenge +wood.6=Baobab +wood.7=Sequoia +wood.8=Kapok +wood.9=Ebony +wood.10=Mahogany +wood.11=Balsa +wood.12=Willow +wood.13=Walnut +wood.14=Greenheart +wood.15=Cherry +wood.16=Mahoe +wood.17=Poplar +wood.18=Palm +wood.19=Papaya +wood.20=Pine +wood.21=Plum +wood.22=Maple +wood.23=Citrus +tile.for.arboriculture.0=Arborist's Chest \ No newline at end of file diff --git a/forestry_resources/lang/forestry/core/en_US.properties b/forestry_resources/lang/forestry/core/en_US.properties new file mode 100755 index 000000000..37fad6af1 --- /dev/null +++ b/forestry_resources/lang/forestry/core/en_US.properties @@ -0,0 +1,540 @@ +# Master language file + +yes=Yes +no=No +beverage.effect.alcoholic=Alcoholic +beverage.effect.antidote=Antidote +chat.accesslocked=is the owner of this machine and has locked access. +chat.memorizednote=You memorize the note and dispose of the crumpled scrap of paper. +chat.cannotmemorizeagain=You already memorized this information. +circuit.dampener.1=Fire Dampener +circuit.electric.choke.1=Electric Choke +circuit.electric.efficiency.1=Electric Efficiency +circuit.electric.boost.1=Electric Boost I +circuit.electric.boost.2=Electric Boost II +circuit.usage.engineTin=In Electrical Engines +death.engine.clockwork=%1$s was stabbed by a loose spring. +death.engine.clockwork.player=%1$s was stabbed by a loose spring. %2$s was the negligent watchmaker. +errors.unknown.desc=Unknown error +errors.unknown.help=Congratulations, you found a glitch. +errors.ok.desc=No error +errors.ok.help=Everything is fine and dandy. +errors.invalidBiome.desc=Hostile environment +errors.invalidBiome.help=Machine or inhabitants cannot work in this biome. +errors.isRaining.desc=Rain +errors.isRaining.help=Operation is only possible when it is not raining. +errors.notRaining.desc=No rain +errors.notRaining.help=Operation is only possible when it is raining. +errors.noFuel.desc=No fuel +errors.noFuel.help=Replenish this machine's fuel supplies. +errors.noHeat.desc=Not warmed up +errors.noHeat.help=Refill the heating tank. +errors.noDisposal.desc=Waste not disposable +errors.noDisposal.help=Insufficient space to dispose of waste products. +errors.noResource.desc=Missing resources +errors.noResource.help=More resources need to be supplied for operation. +errors.notGloomy.desc=Not dark enough +errors.notGloomy.help=A lower light level is required for operation. +errors.notLucid.desc=Not bright enough +errors.notLucid.help=A higher light level is required for operation +errors.notDay.desc=Not daytime +errors.notDay.help=Operation is only possible during the day. +errors.notNight.desc=Not nighttime +errors.notNight.help=Operation is only possible during the night. +errors.noFlower.desc=No flowers +errors.noFlower.help=Hive members are not finding the right flowers. +errors.noQueen.desc=No queen +errors.noQueen.help=Supply this hive with a queen or a princess and a drone. +errors.noDrone.desc=No drone +errors.noDrone.help=Mating requires a drone present. +errors.noSky.desc=Sky obstructed +errors.noSky.help=Clear the area above the machine. +errors.noSpace.desc=No inventory space +errors.noSpace.help=Empty this machine's inventory. +errors.noRecipe.desc=No recipe +errors.noRecipe.help=No matching recipe was found for the supplied resources. +errors.noEnergyNet.desc=No electricity +errors.noEnergyNet.help=Your world is barren of any electricity. (Install IndustrialCraft\u00b2.) +errors.noSpecimen.desc=Nothing to analyze +errors.noSpecimen.help=Supply specimen to analyze. +errors.forcedCooldown.desc=Forced Cooldown +errors.forcedCooldown.help=Engine has overheated and is forced into cooldown. +errors.noHoney.desc=Honey required +errors.noHoney.help=This gadget requires honey drops or honeydew for operation. +errors.notPostpaid.desc=Stamps Needed +errors.notPostpaid.help=Apply more stamps to pay the postal service. +errors.noRecipient.desc=No Recipient +errors.noRecipient.help=You need to address your letter to a recipient to send it. +errors.notAlphaNumeric.desc=Not Alphanumeric +errors.notAlphaNumeric.help=Given string must consist of letters and numbers only. +errors.notUnique.desc=Not Unique +errors.notUnique.help=Given string must be unique in this world. Choose a different one. +errors.noStamps.desc=No Stamps +errors.noStamps.help=A trade station requires stamps to pay postage. This one has run out of them. +errors.wrongStacksize.desc=Too Many Items +errors.wrongStacksize.help=Only single items can be used here. +errors.noCircuitBoard.desc=Board Missing +errors.noCircuitBoard.help=Insert a circuit board to solder the selected tubes onto it. +errors.circuitMismatch.desc=Layout Mismatch +errors.circuitMismatch.help=Amount of tubes does not match size of circuit board. +flowers.cacti=Cacti +flowers.end=End +flowers.jungle=Jungle +flowers.mushroom=Mushroom +flowers.nether=Nether +flowers.vanilla=Flowers +flowers.wheat=Wheat +flowers.gourd=Gourds +fluid.bioethanol=Ethanol +fluid.biomass=Biomass +fluid.milk=Milk +fluid.seedoil=Seed Oil +fluid.juice=Fruit Juice +fluid.honey=Honey +fluid.mead=Short Mead +fluid.glass=Liquid Glass +fluid.ice=Crushed Ice +gui.climate=Climate +gui.empty=Empty +gui.temptol=Temp.Tol +gui.temperature=Temperature +gui.humidity=Humidity +gui.humidtol=Humid.Tol. +gui.unknown=Unknown genome +gui.hybrid=Hybrid +gui.worker=Worker +gui.life=Life +gui.beealyzer=Beealyzer +gui.beealyzer.help=Supply bee and provide honey or honeydew as a pacifier. +gui.beealyzer.overview=Analytics available +gui.beealyzer.produce=Possible Produce +gui.beealyzer.specialty=Possible Specialty +gui.beealyzer.mutations=Possible Mutations +gui.beealyzer.behaviour=Behaviour +gui.beealyzer.natural=Natural Origin +gui.beealyzer.artificial=Artificial Origin +gui.beealyzer.generations=Generations in Captivity +gui.alyzer.authority=Authority +gui.alyzer.classification=Classification +gui.alyzer.nodescription=Encyclopedia Minecraftia could not provide an entry for this specimen. +gui.alyzer.extinct=Extinct +gui.general=General +gui.environment=Environment +gui.produce=Produce +gui.evolution=Evolution +gui.active=Active +gui.inactive=Inactive +gui.species=Species +gui.lifespan=Lifespan +gui.speed=Speed +gui.size=Size +gui.metabolism=Metabolism +gui.pollination=Pollin. +gui.flowers=Flowers +gui.fertility=Fertility +gui.area=Area +gui.effect=Effect +gui.nocturnal=Nocturnal +gui.diurnal=Diurnal +gui.flyer=Flyer +gui.cave=Cave +gui.fireresist=Fireproof +gui.derelict=Derelict +gui.owner=Owner +gui.hellish=Hellish +gui.hot=Hot +gui.warm=Warm +gui.normal=Normal +gui.cold=Cold +gui.icy=Icy +gui.arid=Arid +gui.damp=Damp +gui.energy=Energy +gui.currentOutput=Current Output +gui.stored=Stored +gui.heat=Heat +gui.habitatlocator=Habitat Locator +gui.closetosearch=close to search +gui.didyouknow=Did you know +gui.maxspeed=Maximum +gui.fastest=Fastest +gui.faster=Faster +gui.fast=Fast +gui.normal=Normal +gui.slow=Slow +gui.slower=Slower +gui.slowest=Slowest +gui.longestlife=Longest +gui.longerlife=Longer +gui.longlife=Long +gui.elongatedlife=Elongated +gui.normallife=Normal +gui.shortenedlife=Shortened +gui.shortlife=Short +gui.shorterlife=Shorter +gui.shortestlife=Shortest +gui.speciescount=Species +gui.queens=Queens +gui.princesses=Princ. +gui.drones=Drones +gui.slots=Slots +gui.access=Access +gui.rule.shared=Shared +gui.rule.restricted=Restricted +gui.rule.private=Private +gui.page=Page +gui.maxenergy=Maximum Energy +gui.maxenergyreceive=Maximum Input +gui.noeffect=No effect +gui.mail.from=From +gui.mail.to=To +gui.blank=Blank +gui.mail.nametrader=Name your trade station +gui.mail.pleasesend=Please send +gui.mail.foreveryattached=for every attached +gui.mail.nothingtotrade=Trade station has nothing to trade. +gui.mail.notrader=No trade station of that name available. +gui.addressee.player=Player +gui.addressee.trader=Trader Station +gui.pipe.filter.closed=Closed +gui.pipe.filter.anything=Anything +gui.pipe.filter.item=Items +gui.pipe.filter.bee=Any Bees +gui.pipe.filter.drone=Drones +gui.pipe.filter.princess=Princesses +gui.pipe.filter.queen=Queen +gui.pipe.filter.pure_breed=Pure-Bred Bees +gui.pipe.filter.nocturnal=Nocturnal Bees +gui.pipe.filter.pure_nocturnal=Pure Nocturnal Bees +gui.pipe.filter.flyer=Strong Flyers +gui.pipe.filter.pure_flyer=Pure Flyers +gui.pipe.filter.cave=Cave-Dwellers +gui.pipe.filter.pure_cave=Pure Cave-Dwellers +gui.emptysocket=Empty Socket +gui.smallest=Smallest +gui.smaller=Smaller +gui.small=Small +gui.average=Average +gui.large=Large +gui.larger=Larger +gui.largest=Largest +gui.gigantic=Gigantic +gui.plains=Plains +gui.desert=Desert +gui.beach=Beach +gui.water=Water +gui.nether=Nether +gui.crop=Crop +gui.lowest=Lowest +gui.lower=Lower +gui.low=Low +gui.normal=Normal +gui.triple=Triple +gui.high=High +gui.higher=Higher +gui.highest=Highest +gui.fecundated=Mated +gui.tooltip.tmi=Hold shift for details +gui.worktable.clear=Click to clear Grid +gui.escritoire.probe=Examine Specimens +hints.beebiomes.tag=Choose your biome! +hints.beebiomes.desc=Bees only work in biomes that suit their species. Use your beealyzer and habitat locator to find out in which. +hints.beebreeding.tag=Breed your bees! +hints.beebreeding.desc=Crossbreeding drones and princesses of different species may net you offspring with a new species. +hints.beejubilance.tag=Make your bee happy! +hints.beejubilance.desc=Only jubilant bees will produce their specialty. Make sure to have them in their preferred climate. +hints.enginebronzefuels.tag=Use all the fuels! +hints.enginebronzefuels.desc=You can use a wide variety of fuels for your biogas engine: Biomass, seed oil, honey, milk and even water! +hints.enginebronzeheatloss.tag=Careful with water! +hints.enginebronzeheatloss.desc=Though you can use water in a biogas engine, it is terribly inefficient and will constantly consume lava. +hints.enginebronzeoutput.tag=Choose your fuel! +hints.enginebronzeoutput.desc=Different fuels will net you different energy outputs in a biogas engine. Outputs range from 1 MJ/t to 5 MJ/t. +hints.pipette.tag=Empty tanks with the pipette +hints.pipette.desc=If you are stuck with remaining liquid in a machine's tank, you can click the tank with a pipette to empty it. +hints.enginecopperfuels.tag=Use all the fuels! +hints.enginecopperfuels.desc=Peat-fired engines can use untreated peat, but they can also use bituminous peat to double their energy output. +hints.usesofash.tag=Use your ash! +hints.usesofash.desc=Ash can be used to create fertilizer and is required to refine bituminous peat. +hints.shortmead.tag=Get your energy drink! +hints.shortmead.desc=Your fermenter can not only create biomass, you can also use honeydew and liquid honey to make some short mead. +hints.generatorfuels.tag=Use all the fuels! +hints.generatorfuels.desc=Bio generators accept both biomass and biofuel. They are at their most efficient with biofuel. +hints.moistenerproducts.tag=Want some mossy cobble? +hints.moistenerproducts.desc=Given the correct ingredients, your moistener can also create mossy cobblestone or mossy stone bricks. +hints.enginetinbatteries.tag=Charge those batteries! +hints.enginetinbatteries.desc=You can use batteries to run your electrical engines without needing to wire them up. +hints.energyunit.tag=Say Minecraft Joule! +hints.energyunit.desc=An engine's energy output is measured in MJ/t, which stands for "Minecraft Joule per tick". Each second has 20 ticks. +hints.crating.tag=Crate your Surplus! +hints.crating.desc=Main task of carpenters is the compression of your surplus resources. Many bulk blocks and items can be packaged into crates. +hints.enginebronzewaste.tag=Fuel is conserved. +hints.enginebronzewaste.desc=Contrary to peat-fired engines disabled biogas engines will not waste the biomass currently in the system. +hints.enginecopperwaste.tag=Beware wasting energy! +hints.enginecopperwaste.desc=Disabled peat-fired engines continue to burn peat already removed from the stash without generating energy from it. +hints.energybuffer.tag=Buffering Energy! +hints.energybuffer.desc=Engines are capable of buffering a lesser amount of energy if it cannot be transmitted to the target. +hints.forcedcooldown.tag=Beware Overheating! +hints.forcedcooldown.desc=Engines can overheat if the energy they produce is not consumed. Reaching melting point will force them into cooldown. +hints.cooldownloss.tag=Cooldown means energy loss! +hints.cooldownloss.desc=Engines going into forced cooldown will also lose a significant chunk of their stored energy. +hints.beeflowers.tag=Bees need flowers +hints.beeflowers.desc=Any bee will need some type of flower in the vicinity. Some rather mundane flowers, others very exotic ones. +hints.nopowerrequired.tag=No power required +hints.nopowerrequired.desc=Machines of this type do not require any power to operate. +hints.accesscontrol.tag=Access Control +hints.accesscontrol.desc=A machine's owner can set it to three different types of access: Shared, restricted or private. +hints.accessrules.tag=Access rules +hints.accessrules.desc="Shared" access allows anyone to break the machine or interact with it. "Restricted" still allows interaction for anyone. +hints.accesspipe.tag=Restricted Pipe Access +hints.accesspipe.desc=A machine set to private will disallow any interaction with tubes or pipes. +hints.flowerjungle.tag=What's a jungle flower? +hints.flowerjungle.desc=Jungle flowers are ferns or vines. +hints.flowernether.tag=What's a nether flower? +hints.flowernether.desc=Netherwart are the nether flowers. +hints.apiaristsuit.tag=Bee Suits! +hints.apiaristsuit.desc=A full apiarist's suit will protect you from all negative bee effects. +hints.honeyfood.tag=Grab foodstuff! +hints.honeyfood.desc=Many different kinds of foods can be made from honey and other bee products. +hints.powerrequired.tag=Requires Energy! +hints.powerrequired.desc=This machine requires energy from an engine to function. Attach an engine and start it, to allow production. +hints.powerraintank.tag=Bottling Requires Energy! +hints.powerraintank.desc=Even an unpowered raintank will collect rain. However to bottle the water, energy from an engine is required. +hints.manualpeat.tag=No Bog Needed! +hints.manualpeat.desc=Peat can be farmed in automatic peat bogs, but when you start out, you might want to try harvesting a bit of peat by hand. +hints.peatharvest.tag=Harvest Peat! +hints.peatharvest.desc=Bog earth directly adjacent to water will mature to peat. Use a shovel to harvest it. +hints.enginetinchoke.tag=Regulate Output +hints.enginetinchoke.desc=Electrical engines can be outfitted with circuit boards to choke their power output to 1 MJ/t and also reduce their energy demand. +hints.postage.tag=Pay the Ferryman +hints.postage.desc=Sending letters costs stamps. To a base fee of 1n, every attachment adds another 1n of cost. +item.beverage.meadShort=Short Mead +item.beverage.meadCurative=Curative Mead +item.circuitboard.basic=Basic Circuit Board +item.circuitboard.enhanced=Enhanced Circuit Board +item.circuitboard.refined=Refined Circuit Board +item.circuitboard.intricate=Intricate Circuit Board +item.comb.honey=Honey Comb +item.comb.cocoa=Cocoa Comb +item.comb.simmering=Simmering Comb +item.comb.stringy=Stringy Comb +item.comb.frozen=Frozen Comb +item.comb.dripping=Dripping Comb +item.comb.silky=Silky Comb +item.comb.parched=Parched Comb +item.comb.mysterious=Mysterious Comb +item.comb.irradiated=Irradiated Comb +item.comb.powdery=Powdery Comb +item.comb.reddened=Reddened Comb +item.comb.darkened=Darkened Comb +item.comb.omega=Omega Comb +item.comb.wheaten=Wheaten Comb +item.comb.mossy=Mossy Comb +item.comb.mellow=Mellow Comb +item.crated.adj=Crated +item.crated.unknown=Crate with unknown content +item.dissipationCharge=Dissipation Charge +item.honeyDrop.charged=Charged Drop +item.honeyDrop.honey=Honey Drop +item.honeyDrop.omega=Omega Drop +item.pollen.normal=Pollen +item.pollen.crystalline=Crystalline Pollen +item.propolis.normal=Propolis +item.propolis.sticky=Sticky Propolis +item.propolis.pulsating=Pulsating Propolis +item.propolis.silky=Silky Propolis +item.thermionicTubes.ex-0=Copper Electron Tube +item.thermionicTubes.ex-1=Tin Electron Tube +item.thermionicTubes.ex-2=Bronze Electron Tube +item.thermionicTubes.ex-3=Iron Electron Tube +item.thermionicTubes.ex-4=Golden Electron Tube +item.thermionicTubes.ex-5=Diamantine Electron Tube +item.thermionicTubes.ex-6=Obsidian Electron Tube +item.thermionicTubes.ex-7=Blazing Electron Tube +item.thermionicTubes.ex-8=Rubberised Electron Tube +item.thermionicTubes.ex-9=Emerald Electron Tube +item.thermionicTubes.ex-10=Apatine Electron Tube +item.thermionicTubes.ex-11=Lapis Electron Tube +item.pulsatingDust=Pulsating Dust +item.pulsatingMesh=Pulsating Mesh +item.silkWisp=Silk Wisp +item.wovenSilk=Woven Silk +item.fertilizerBio=Compost +item.fertilizerCompound=Fertilizer +item.apatite=Apatite +item.ingotCopper=Copper Ingot +item.ingotTin=Tin Ingot +item.ingotBronze=Bronze Ingot +item.pipette=Pipette +item.wrench=Wrench +item.gearBronze=Bronze Gear +item.bucketBiomass=Biomass Bucket +item.sturdyMachine=Sturdy Casing +item.vialCatalyst=Catalyst +item.bucketBiofuel=Ethanol Bucket +item.peat=Peat +item.ash=Ash +item.gearCopper=Copper Gear +item.waterCan=Water Can +item.canEmpty=Can +item.biomassCan=Biomass Can +item.biofuelCan=Ethanol Can +item.gearTin=Tin Gear +item.hardenedMachine=Hardened Casing +item.iodineCapsule=Iodine Capsule +item.carton=Carton +item.crate=Crate +item.oakStick=Impregnated Stick +item.woodPulp=Wood Pulp +item.kitPickaxe=Pickaxe Kit +item.bronzePickaxe=Survivalist's Pickaxe +item.brokenBronzePickaxe=Broken Pickaxe +item.kitShovel=Shovel Kit +item.bronzeShovel=Survivalist's Shovel +item.brokenBronzeShovel=Broken Shovel +item.tent=Survivalist's Tent +item.mouldyWheat=Mouldy Wheat +item.decayingWheat=Decaying Wheat +item.mulch=Mulch +item.scoop=Scoop +item.beeswax=Beeswax +item.royalJelly=Royal Jelly +item.honeydew=Honeydew +item.waxCapsule=Wax Capsule +item.honeyedSlice=Honeyed Slice +item.ambrosia=Ambrosia +item.canOil=Oil Can +item.canFuel=Fuel Can +item.canLava=Lava Can +item.canSeedOil=Seed Oil Can +item.canHoney=Honey Can +item.canJuice=Juice Can +item.canIce=Ice Can +item.honeyPot=Honey Pot +item.waxCapsuleWater=Water Capsule +item.waxCapsuleBiomass=Biomass Capsule +item.waxCapsuleBiofuel=Ethanol Capsule +item.bituminousPeat=Bituminous Peat +item.waxCapsuleOil=Oil Capsule +item.waxCapsuleFuel=Fuel Capsule +item.waxCapsuleSeedOil=Seed Oil Capsule +item.waxCapsuleHoney=Honey Capsule +item.waxCapsuleJuice=Juice Capsule +item.waxCapsuleIce=Ice Capsule +item.phosphor=Phosphor +item.refractoryWax=Refractory Wax +item.refractoryEmpty=Refractory Capsule +item.refractoryLava=Lava Capsule +item.refractoryWater=Water Capsule +item.refractoryBiomass=Biomass Capsule +item.refractoryBiofuel=Ethanol Capsule +item.refractoryOil=Oil Capsule +item.refractoryFuel=Fuel Capsule +item.refractorySeedOil=Seed Oil Capsule +item.refractoryHoney=Honey Capsule +item.refractoryJuice=Juice Capsule +item.refractoryIce=Ice Capsule +item.beealyzer=Beealyzer +item.apiaristHelmet=Apiarist's Hat +item.apiaristChest=Apiarist's Shirt +item.apiaristLegs=Apiarist's Pants +item.apiaristBoots=Apiarist's Shoes +item.naturalistHelmet=Spectacles +item.biomeFinder=Habitat Locator +item.infuser=Infuser +item.imprinter=Imprinter +item.solderingIron=Soldering Iron +item.letters=Letter +item.stamps=Stamp +item.scentedPaneling=Scented Paneling +item.impregnatedCasing=Impregnated Casing +item.frameUntreated=Untreated Frame +item.frameImpregnated=Impregnated Frame +item.frameProven=Proven Frame +item.iceShard=Ice Shard +item.waxCast=Wax Cast +item.treealyzer=Treealyzer +item.fruit.cherry=Cherry +item.fruit.walnut=Walnut +item.fruit.chestnut=Chestnut +item.fruit.lemon=Lemon +item.fruit.plum=Plum +item.fruit.papaya=Papaya +item.fruit.dates=Date +itemGroup.forestry=Forestry +itemGroup.arboriculture=Arboriculture +itemGroup.apiculture=Apiculture +itemGroup.lepidopterology=Lepidopterology +layout.engine.tin=Electric Engine +storage.backpack.apiarist=Apiarist's Backpack +storage.backpack.adventurer=Adventurer's Backpack +storage.backpack.builder=Builder's Backpack +storage.backpack.digger=Digger's Backpack +storage.backpack.forester=Forester's Backpack +storage.backpack.hunter=Hunter's Backpack +storage.backpack.miner=Miner's Backpack +storage.backpack.t2adj=Woven +tile.for.engine.0=Electrical Engine +tile.for.engine.1=Peat-fired Engine +tile.for.engine.2=Biogas Engine +tile.for.engine.3=Bio Generator +tile.for.engine.4=Clockwork Engine +tile.for.factory.0=Bottler +tile.for.factory.1=Carpenter +tile.for.factory.2=Centrifuge +tile.for.factory.3=Fermenter +tile.for.factory.4=Moistener +tile.for.factory.5=Squeezer +tile.for.factory.6=Still +tile.for.factory.7=Rainmaker +tile.for.factory2.0=Thermionic Fabricator +tile.for.factory2.1=Raintank +tile.for.factory2.2=Worktable +tile.for.core.0=Analyzer +tile.for.core.1=Escritoire +tile.for.mail.0=Mailbox +tile.for.mail.1=Trade Station +tile.for.mail.2=Stamp Collector +tile.beehives.1=Forest Hive +tile.beehives.2=Meadows Hive +tile.beehives.3=Desert Hive +tile.beehives.4=Jungle Hive +tile.beehives.5=End Hive +tile.beehives.6=Snow Hive +tile.beehives.7=Swamp Hive +tile.resources.0=Apatite Ore +tile.resources.1=Copper Ore +tile.resources.2=Tin Ore +tile.soil.0=Humus +tile.soil.1=Bog Earth +tile.stained.0=White Stained Glass +tile.stained.1=Orange Stained Glass +tile.stained.2=Magenta Stained Glass +tile.stained.3=Light Blue Stained Glass +tile.stained.4=Yellow Stained Glass +tile.stained.5=Lime Stained Glass +tile.stained.6=Pink Stained Glass +tile.stained.7=Gray Stained Glass +tile.stained.8=Light Gray Stained Glass +tile.stained.9=Cyan Stained Glass +tile.stained.10=Purple Stained Glass +tile.stained.11=Blue Stained Glass +tile.stained.12=Brown Stained Glass +tile.stained.13=Green Stained Glass +tile.stained.14=Red Stained Glass +tile.stained.15=Black Stained Glass +trigger.hasMail=Has Mail +trigger.hasWork=Has Work +trigger.lowFuel=Fuel +trigger.lowGermlings=Germlings +trigger.lowResources=Resources +trigger.lowSoil=Soil +trigger.missingDrone=Missing Drone +trigger.missingQueen=Missing Queen or Princess +trigger.noFrames=No Frames +trigger.lowPaper=Paper +trigger.lowLiquid=Liquid +trigger.lowFertilizer=Fertilizer +trigger.lowInput=Input +trigger.lowStamps=Stamps +trigger.mailBuffer=Buffer +usage.engine.tin=In Electrical Engines diff --git a/forestry_resources/lang/forestry/farming/en_US.properties b/forestry_resources/lang/forestry/farming/en_US.properties new file mode 100755 index 000000000..c9fbc72ff --- /dev/null +++ b/forestry_resources/lang/forestry/farming/en_US.properties @@ -0,0 +1,55 @@ +circuit.managedArboreal=Arboretum +circuit.managedPeat=Peat Bog +circuit.managedCereal=Crop Farm +circuit.managedVegetable=Vegetable Farm +circuit.managedInfernal=Infernal Farm +circuit.managedShroom=Shroom Farm +circuit.manualOrchard=Orchard +circuit.manualPeat=Peat Bog +circuit.manualCereal=Crop Farm +circuit.manualVegetable=Vegetable Farm +circuit.manualSucculent=Succulent Farm +circuit.manualPoales=Reed Farm +circuit.manualRubber=Rubber Plantation +circuit.manualGourd=Gourd Farm +circuit.manualCocoa=Cocoa Plantation +circuit.manualShroom=Shroom Farm +errors.noFertilizer.desc=No Fertilizer +errors.noFertilizer.help=Farms require fertilizer for function. Compost is insufficient. +errors.noFarmland.desc=No Farmland +errors.noFarmland.help=Smooth sandstone, bricks or stone bricks create a platform the farm will build on. +errors.noLiquid.desc=No Water +errors.noLiquid.help=Depending on rainfall, temperature and humidity farms need to be supplied with varying amounts of water. +gui.hydration=Hydration Required +gui.hydr.heat=By Heat +gui.hydr.humid=By Humidity +gui.hydr.rainfall=By Rainfall +gui.hydr.overall=Overall +hints.farmland.tag=Lay out your farmland! +hints.farmland.desc=Smooth sandstone, bricks or stone bricks create a platform the farm will build on. +hints.gearbox.tag=Supply power! +hints.gearbox.desc=Use gearboxes to attach engines or power lines to your farm. +hints.valve.tag=Supply water! +hints.valve.desc=Almost all farms require water. Use valve blocks for automation. +hints.fertilizer.tag=Fertilizer needed! +hints.fertilizer.desc=All farms need fertilizer to work. Compost or mulch will not suffice. +hints.hatch.tag=Batten down the hatches! +hints.hatch.desc=Hatches are a pipe or tube's best friend. Use them to automate transport. +hints.circuitboard.tag=Program your farms! +hints.circuitboard.desc=Use a soldering iron to turn your tree farm into any kind of farm you like. +hints.manualfarms.tag=Manual farms! +hints.manualfarms.desc=Apart from the managed farms there are manual farms which will only maintain the farm, but not build it. +hints.farmgui.tag=Soil goes left, seeds go right! +hints.farmgui.desc=Soil goes into the left slots, seeds or saplings into the right slots of the reservoir on the top right part. +layout.farms.managed=Managed Farms +layout.farms.manual=Manual Farms +tile.ffarm.0=Farm Block +tile.ffarm.2=Farm Gearbox +tile.ffarm.3=Farm Hatch +tile.ffarm.4=Farm Valve +tile.ffarm.5=Farm Control +trigger.lowSoil=Soil +trigger.lowLiquid=Water Tank +trigger.lowFertilizer=Fertilizer +usage.farms.managed=Managed Farm +usage.farms.manual=Manual Farm \ No newline at end of file diff --git a/forestry_resources/lang/forestry/lepidopterology/en_US.properties b/forestry_resources/lang/forestry/lepidopterology/en_US.properties new file mode 100755 index 000000000..5aab512d0 --- /dev/null +++ b/forestry_resources/lang/forestry/lepidopterology/en_US.properties @@ -0,0 +1,8 @@ +gui.flutterlyzer.help=Supply butterfly and provide honey or honeydew as a pacifier. +gui.loot.butterfly=Possible Butterfly Loot +gui.loot.caterpillar=Possible Caterpillar Loot +item.butterfly=Butterfly +item.moth=Moth +item.flutterlyzer=Flutterlyzer +storage.backpack.lepidopterist=Lepidopterist's Backpack +tile.for.lepidopterology.0=Lepidopterist's Chest \ No newline at end of file diff --git a/forestry_resources/lang/forestry/mail/en_US.properties b/forestry_resources/lang/forestry/mail/en_US.properties new file mode 100755 index 000000000..47a2a1ad8 --- /dev/null +++ b/forestry_resources/lang/forestry/mail/en_US.properties @@ -0,0 +1,23 @@ +chat.mail.no_mailbox=Recipient has no mailbox. +chat.mail.not_mailable=Letter is not sendable. +chat.mail.not_postpaid=Letter is not sufficiently stamped. +chat.mail.mailbox_full=Recipient's mailbox is full. +chat.mail.already_mailed=Cannot resend letter. +chat.mail.response_not_mailable=Trade station cannot send the response letter. You need to have a mailbox to deliver to. +chat.mail.insufficient_offer=Trade station demands more. +chat.mail.insufficient_trade_good=Trade station has run out of supplies. +chat.mail.insufficient_buffer=Trade station is full. +chat.mail.insufficient_paper=Trade station ran out of paper. +chat.mail.insufficient_stamps=Trade station ran out of stamps. +chat.mail.ok=Trade is available. +chat.mail.wrongstacksize=Can only write one letter at a time. +gui.mail.catalogue.close=Close +gui.mail.catalogue.trade=Trade +gui.mail.filter.all=All +gui.mail.filter.online=Online +gui.mail.filter.offline=Offline +gui.mail.willtrade=%s will trade +gui.mail.address.copy=Use +gui.mail.tradefor=for +gui.mail.notrades=No trades available. +item.catalogue=Catalogue \ No newline at end of file diff --git a/forestry_resources/lang/forestry/pipes/en_US.properties b/forestry_resources/lang/forestry/pipes/en_US.properties new file mode 100755 index 000000000..c7f569f8a --- /dev/null +++ b/forestry_resources/lang/forestry/pipes/en_US.properties @@ -0,0 +1,2 @@ + +item.PipeItemsPropolis=Apiarist's Pipe \ No newline at end of file diff --git a/forestry_resources/mcmod.info b/forestry_resources/mcmod.info new file mode 100755 index 000000000..b27a0f933 --- /dev/null +++ b/forestry_resources/mcmod.info @@ -0,0 +1,18 @@ +[ +{ + "modid": "Forestry", + "name": "Forestry for Minecraft", + "description": "Trees, bees and more.", + "credits": "mistaqur, Binnie", + "logoFile": "/gfx/forestry/logo.png", + "version": "${version}", + "mcversion": "${mcversion}", + "url": "http://forestry.sengir.net/", + "updateUrl": "http://forestry.sengir.net/wiki/index.php?n=Main.Downloads", + "authors": [ "SirSengir" ], + "screenshots": [ "/gfx/forestry/screenshots/screen1.jpg", "/gfx/forestry/screenshots/screen2.jpg" ], + "dependencies": [ + "mod_MinecraftForge" + ] +} +] diff --git a/forestry_techne/Bee.java b/forestry_techne/Bee.java new file mode 100755 index 000000000..4a74d28f7 --- /dev/null +++ b/forestry_techne/Bee.java @@ -0,0 +1,131 @@ +// Date: 30.05.2013 09:02:55 +// Template version 1.1 +// Java generated by Techne +// Keep in mind that you still need to fill in some blanks +// - ZeuX + + + + + + +package net.minecraft.src; + +public class ModelBee extends ModelBase +{ + //fields + ModelRenderer Snout; + ModelRenderer TorsoWing; + ModelRenderer Rump; + ModelRenderer Tail; + ModelRenderer TailEnd; + ModelRenderer Bridge; + ModelRenderer EyeRight; + ModelRenderer EyeLeft; + ModelRenderer WingLeft; + ModelRenderer WingRight; + ModelRenderer crown; + + public ModelBee() + { + textureWidth = 64; + textureHeight = 32; + + Snout = new ModelRenderer(this, 18, 11); + Snout.addBox(0F, 0F, 0F, 1, 2, 1); + Snout.setRotationPoint(0F, 1F, -2F); + Snout.setTextureSize(64, 32); + Snout.mirror = true; + setRotation(Snout, 0F, 0F, 0F); + TorsoWing = new ModelRenderer(this, 28, 14); + TorsoWing.addBox(0F, 0F, 0F, 3, 3, 1); + TorsoWing.setRotationPoint(-1F, 0F, -1F); + TorsoWing.setTextureSize(64, 32); + TorsoWing.mirror = true; + setRotation(TorsoWing, 0F, 0F, 0F); + Rump = new ModelRenderer(this, 10, 14); + Rump.addBox(-1F, -1F, 0F, 3, 3, 3); + Rump.setRotationPoint(0F, 1F, 1F); + Rump.setTextureSize(64, 32); + Rump.mirror = true; + setRotation(Rump, 0F, 0F, 0F); + Tail = new ModelRenderer(this, 4, 14); + Tail.addBox(0F, 0F, 0F, 2, 2, 1); + Tail.setRotationPoint(-0.5F, 0.5333334F, 4F); + Tail.setTextureSize(64, 32); + Tail.mirror = true; + setRotation(Tail, 0F, 0F, 0F); + TailEnd = new ModelRenderer(this, 0, 14); + TailEnd.addBox(0F, 0F, 0F, 1, 1, 1); + TailEnd.setRotationPoint(0F, 1F, 5F); + TailEnd.setTextureSize(64, 32); + TailEnd.mirror = true; + setRotation(TailEnd, 0F, 0F, 0F); + Bridge = new ModelRenderer(this, 22, 14); + Bridge.addBox(0F, 0F, 0F, 2, 2, 1); + Bridge.setRotationPoint(-0.5F, 0.5F, 0F); + Bridge.setTextureSize(64, 32); + Bridge.mirror = true; + setRotation(Bridge, 0F, 0F, 0F); + EyeRight = new ModelRenderer(this, 22, 9); + EyeRight.addBox(0F, 0F, 0F, 1, 1, 1); + EyeRight.setRotationPoint(-1F, 0F, -2F); + EyeRight.setTextureSize(64, 32); + EyeRight.mirror = true; + setRotation(EyeRight, 0F, 0F, 0F); + EyeLeft = new ModelRenderer(this, 18, 9); + EyeLeft.addBox(0F, 0F, 0F, 1, 1, 1); + EyeLeft.setRotationPoint(1F, 0F, -2F); + EyeLeft.setTextureSize(64, 32); + EyeLeft.mirror = true; + setRotation(EyeLeft, 0F, 0F, 0F); + WingLeft = new ModelRenderer(this, 0, 0); + WingLeft.addBox(0F, 0F, 0F, 3, 1, 6); + WingLeft.setRotationPoint(1F, -0.1F, -0.5F); + WingLeft.setTextureSize(64, 32); + WingLeft.mirror = true; + setRotation(WingLeft, 0F, 0F, 0F); + WingRight = new ModelRenderer(this, 0, 7); + WingRight.addBox(-3F, 0F, 0F, 3, 1, 6); + WingRight.setRotationPoint(0F, -0.1F, -0.5F); + WingRight.setTextureSize(64, 32); + WingRight.mirror = true; + setRotation(WingRight, 0F, 0F, 0F); + crown = new ModelRenderer(this, 0, 17); + crown.addBox(0F, 0F, 0F, 2, 1, 2); + crown.setRotationPoint(-0.5F, -1.5F, -1.5F); + crown.setTextureSize(64, 32); + crown.mirror = true; + setRotation(crown, 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); + Snout.render(f5); + TorsoWing.render(f5); + Rump.render(f5); + Tail.render(f5); + TailEnd.render(f5); + Bridge.render(f5); + EyeRight.render(f5); + EyeLeft.render(f5); + WingLeft.render(f5); + WingRight.render(f5); + crown.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) + { + super.setRotationAngles(f, f1, f2, f3, f4, f5); + } + +} diff --git a/forestry_techne/Bee1.tcn b/forestry_techne/Bee1.tcn new file mode 100755 index 000000000..addeebffd Binary files /dev/null and b/forestry_techne/Bee1.tcn differ diff --git a/forestry_techne/Bee2.tcn b/forestry_techne/Bee2.tcn new file mode 100755 index 000000000..efabc99dc Binary files /dev/null and b/forestry_techne/Bee2.tcn differ diff --git a/forestry_techne/BeeQueen.java b/forestry_techne/BeeQueen.java new file mode 100755 index 000000000..5d384cafa --- /dev/null +++ b/forestry_techne/BeeQueen.java @@ -0,0 +1,131 @@ +// Date: 16.06.2013 11:01:08 +// Template version 1.1 +// Java generated by Techne +// Keep in mind that you still need to fill in some blanks +// - ZeuX + + + + + + +package net.minecraft.src; + +public class ModelBeeQueen extends ModelBase +{ + //fields + ModelRenderer Snout; + ModelRenderer TorsoWing; + ModelRenderer Rump; + ModelRenderer Tail; + ModelRenderer TailEnd; + ModelRenderer Bridge; + ModelRenderer EyeRight; + ModelRenderer EyeLeft; + ModelRenderer WingLeft; + ModelRenderer WingRight; + ModelRenderer crown; + + public ModelBeeQueen() + { + textureWidth = 64; + textureHeight = 32; + + Snout = new ModelRenderer(this, 18, 11); + Snout.addBox(0F, 0F, 0F, 1, 2, 1); + Snout.setRotationPoint(0F, 1F, -3F); + Snout.setTextureSize(64, 32); + Snout.mirror = true; + setRotation(Snout, 0F, 0F, 0F); + TorsoWing = new ModelRenderer(this, 32, 14); + TorsoWing.addBox(0F, 0F, 0F, 3, 3, 2); + TorsoWing.setRotationPoint(-1F, 0F, -2F); + TorsoWing.setTextureSize(64, 32); + TorsoWing.mirror = true; + setRotation(TorsoWing, 0F, 0F, 0F); + Rump = new ModelRenderer(this, 12, 14); + Rump.addBox(-1F, -1F, 0F, 3, 3, 4); + Rump.setRotationPoint(0F, 1F, 1F); + Rump.setTextureSize(64, 32); + Rump.mirror = true; + setRotation(Rump, 0F, 0F, 0F); + Tail = new ModelRenderer(this, 4, 14); + Tail.addBox(0F, 0F, 0F, 2, 2, 2); + Tail.setRotationPoint(-0.5F, 0.5333334F, 5F); + Tail.setTextureSize(64, 32); + Tail.mirror = true; + setRotation(Tail, 0F, 0F, 0F); + TailEnd = new ModelRenderer(this, 0, 14); + TailEnd.addBox(0F, 0F, 0F, 1, 1, 1); + TailEnd.setRotationPoint(0F, 1F, 7F); + TailEnd.setTextureSize(64, 32); + TailEnd.mirror = true; + setRotation(TailEnd, 0F, 0F, 0F); + Bridge = new ModelRenderer(this, 26, 14); + Bridge.addBox(0F, 0F, 0F, 2, 2, 1); + Bridge.setRotationPoint(-0.5F, 0.5F, 0F); + Bridge.setTextureSize(64, 32); + Bridge.mirror = true; + setRotation(Bridge, 0F, 0F, 0F); + EyeRight = new ModelRenderer(this, 22, 9); + EyeRight.addBox(0F, 0F, 0F, 1, 1, 1); + EyeRight.setRotationPoint(-1F, 0F, -3F); + EyeRight.setTextureSize(64, 32); + EyeRight.mirror = true; + setRotation(EyeRight, 0F, 0F, 0F); + EyeLeft = new ModelRenderer(this, 18, 9); + EyeLeft.addBox(0F, 0F, 0F, 1, 1, 1); + EyeLeft.setRotationPoint(1F, 0F, -3F); + EyeLeft.setTextureSize(64, 32); + EyeLeft.mirror = true; + setRotation(EyeLeft, 0F, 0F, 0F); + WingLeft = new ModelRenderer(this, 0, 0); + WingLeft.addBox(0F, 0F, 0F, 3, 1, 6); + WingLeft.setRotationPoint(1F, -0.1F, -0.5F); + WingLeft.setTextureSize(64, 32); + WingLeft.mirror = true; + setRotation(WingLeft, 0F, 0F, 0F); + WingRight = new ModelRenderer(this, 0, 7); + WingRight.addBox(-3F, 0F, 0F, 3, 1, 6); + WingRight.setRotationPoint(0F, -0.1F, -0.5F); + WingRight.setTextureSize(64, 32); + WingRight.mirror = true; + setRotation(WingRight, 0F, 0F, 0F); + crown = new ModelRenderer(this, 0, 18); + crown.addBox(0F, 0F, 0F, 2, 1, 2); + crown.setRotationPoint(-0.5F, -1.5F, -2F); + crown.setTextureSize(64, 32); + crown.mirror = true; + setRotation(crown, 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); + Snout.render(f5); + TorsoWing.render(f5); + Rump.render(f5); + Tail.render(f5); + TailEnd.render(f5); + Bridge.render(f5); + EyeRight.render(f5); + EyeLeft.render(f5); + WingLeft.render(f5); + WingRight.render(f5); + crown.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) + { + super.setRotationAngles(f, f1, f2, f3, f4, f5); + } + +} diff --git a/forestry_techne/BeeQueen.png b/forestry_techne/BeeQueen.png new file mode 100755 index 000000000..faeb52bb3 Binary files /dev/null and b/forestry_techne/BeeQueen.png differ diff --git a/forestry_techne/BeeQueen.tcn b/forestry_techne/BeeQueen.tcn new file mode 100755 index 000000000..af1d07781 Binary files /dev/null and b/forestry_techne/BeeQueen.tcn differ diff --git a/forestry_techne/Butterfly1.tcn b/forestry_techne/Butterfly1.tcn new file mode 100755 index 000000000..bf74ab432 Binary files /dev/null and b/forestry_techne/Butterfly1.tcn differ diff --git a/forestry_techne/Butterfly2-2.tcn b/forestry_techne/Butterfly2-2.tcn new file mode 100755 index 000000000..3ac95170d Binary files /dev/null and b/forestry_techne/Butterfly2-2.tcn differ diff --git a/forestry_techne/Butterfly2.png b/forestry_techne/Butterfly2.png new file mode 100755 index 000000000..4494c7c26 Binary files /dev/null and b/forestry_techne/Butterfly2.png differ diff --git a/forestry_techne/Escritoire.java b/forestry_techne/Escritoire.java new file mode 100755 index 000000000..4247d1bf8 --- /dev/null +++ b/forestry_techne/Escritoire.java @@ -0,0 +1,123 @@ +// Date: 26.05.2013 12:47:37 +// Template version 1.1 +// Java generated by Techne +// Keep in mind that you still need to fill in some blanks +// - ZeuX + + + + + + +package net.minecraft.src; + +public class ModelEscritoire extends ModelBase +{ + //fields + ModelRenderer desk; + ModelRenderer standRB; + ModelRenderer standRF; + ModelRenderer standLB; + ModelRenderer standLF; + ModelRenderer drawers; + ModelRenderer standLowLF; + ModelRenderer standLowRB; + ModelRenderer standLowRF; + ModelRenderer standLowLB; + + public ModelEscritoire() + { + textureWidth = 64; + textureHeight = 32; + + desk = new ModelRenderer(this, 0, 0); + desk.addBox(-8F, 3F, -7.8F, 16, 2, 15); + desk.setRotationPoint(0F, 0F, 0F); + desk.setTextureSize(64, 32); + desk.mirror = true; + setRotation(desk, 0.0872665F, 0F, 0F); + standRB = new ModelRenderer(this, 38, 18); + standRB.addBox(5F, 4F, 5F, 2, 6, 2); + standRB.setRotationPoint(0F, 0F, 0F); + standRB.setTextureSize(64, 32); + standRB.mirror = true; + setRotation(standRB, 0F, 0F, 0F); + standRF = new ModelRenderer(this, 38, 18); + standRF.addBox(5F, 4F, -7F, 2, 6, 2); + standRF.setRotationPoint(0F, 0F, 0F); + standRF.setTextureSize(64, 32); + standRF.mirror = true; + setRotation(standRF, 0F, 0F, 0F); + standLB = new ModelRenderer(this, 38, 18); + standLB.addBox(-7F, 4F, 5F, 2, 6, 2); + standLB.setRotationPoint(0F, 0F, 0F); + standLB.setTextureSize(64, 32); + standLB.mirror = true; + setRotation(standLB, 0F, 0F, 0F); + standLF = new ModelRenderer(this, 38, 18); + standLF.addBox(-7F, 4F, -7F, 2, 6, 2); + standLF.setRotationPoint(0F, 0F, 0F); + standLF.setTextureSize(64, 32); + standLF.mirror = true; + setRotation(standLF, 0F, 0F, 0F); + drawers = new ModelRenderer(this, 0, 18); + drawers.addBox(-7.5F, -2F, 4.5F, 15, 5, 3); + drawers.setRotationPoint(0F, 0F, 0F); + drawers.setTextureSize(64, 32); + drawers.mirror = true; + setRotation(drawers, 0F, 0F, 0F); + standLowLF = new ModelRenderer(this, 0, 26); + standLowLF.addBox(-6.5F, 10F, -6.5F, 1, 4, 1); + standLowLF.setRotationPoint(0F, 0F, 0F); + standLowLF.setTextureSize(64, 32); + standLowLF.mirror = true; + setRotation(standLowLF, 0F, 0F, 0F); + standLowRB = new ModelRenderer(this, 0, 26); + standLowRB.addBox(5.5F, 10F, 5.5F, 1, 4, 1); + standLowRB.setRotationPoint(0F, 0F, 0F); + standLowRB.setTextureSize(64, 32); + standLowRB.mirror = true; + setRotation(standLowRB, 0F, 0F, 0F); + standLowRF = new ModelRenderer(this, 0, 26); + standLowRF.addBox(5.5F, 10F, -6.5F, 1, 4, 1); + standLowRF.setRotationPoint(0F, 0F, 0F); + standLowRF.setTextureSize(64, 32); + standLowRF.mirror = true; + setRotation(standLowRF, 0F, 0F, 0F); + standLowLB = new ModelRenderer(this, 0, 26); + standLowLB.addBox(-6.5F, 10F, 5.5F, 1, 4, 1); + standLowLB.setRotationPoint(0F, 0F, 0F); + standLowLB.setTextureSize(64, 32); + standLowLB.mirror = true; + setRotation(standLowLB, 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); + desk.render(f5); + standRB.render(f5); + standRF.render(f5); + standLB.render(f5); + standLF.render(f5); + drawers.render(f5); + standLowLF.render(f5); + standLowRB.render(f5); + standLowRF.render(f5); + standLowLB.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) + { + super.setRotationAngles(f, f1, f2, f3, f4, f5); + } + +} diff --git a/forestry_techne/Escritoire.png b/forestry_techne/Escritoire.png new file mode 100755 index 000000000..4aa56b444 Binary files /dev/null and b/forestry_techne/Escritoire.png differ diff --git a/forestry_techne/escritoire.tcn b/forestry_techne/escritoire.tcn new file mode 100755 index 000000000..405a8b16f Binary files /dev/null and b/forestry_techne/escritoire.tcn differ diff --git a/forestry_techne/escritoire2.tcn b/forestry_techne/escritoire2.tcn new file mode 100755 index 000000000..bf9d5fd06 Binary files /dev/null and b/forestry_techne/escritoire2.tcn differ diff --git a/pipes_common/forestry/pipes/EnumFilterType.java b/pipes_common/forestry/pipes/EnumFilterType.java new file mode 100755 index 000000000..1b6bee5f7 --- /dev/null +++ b/pipes_common/forestry/pipes/EnumFilterType.java @@ -0,0 +1,38 @@ +/******************************************************************************* + * Copyright 2011-2014 by SirSengir + * + * This work is licensed under a Creative Commons Attribution-NonCommercial-NoDerivs 3.0 Unported License. + * + * To view a copy of this license, visit http://creativecommons.org/licenses/by-nc-nd/3.0/. + ******************************************************************************/ +package forestry.pipes; + +import java.util.Locale; + +import net.minecraft.item.ItemStack; +import net.minecraft.util.Icon; +import cpw.mods.fml.relauncher.Side; +import cpw.mods.fml.relauncher.SideOnly; +import forestry.core.config.ForestryItem; +import forestry.core.render.TextureManager; + +public enum EnumFilterType { + + CLOSED, ANYTHING, ITEM, BEE, DRONE, PRINCESS, QUEEN, PURE_BREED, NOCTURNAL, PURE_NOCTURNAL, FLYER, PURE_FLYER, CAVE, PURE_CAVE, NATURAL; + + public static EnumFilterType getType(ItemStack stack) { + if (ForestryItem.beeDroneGE.isItemEqual(stack)) + return DRONE; + if (ForestryItem.beePrincessGE.isItemEqual(stack)) + return PRINCESS; + if (ForestryItem.beeQueenGE.isItemEqual(stack)) + return QUEEN; + + return ITEM; + } + + @SideOnly(Side.CLIENT) + public Icon getIcon() { + return TextureManager.getInstance().getDefault("analyzer/" + this.toString().toLowerCase(Locale.ENGLISH)); + } +} diff --git a/pipes_common/forestry/pipes/GuiHandlerPipes.java b/pipes_common/forestry/pipes/GuiHandlerPipes.java new file mode 100755 index 000000000..9bf221fe2 --- /dev/null +++ b/pipes_common/forestry/pipes/GuiHandlerPipes.java @@ -0,0 +1,65 @@ +/******************************************************************************* + * Copyright 2011-2014 by SirSengir + * + * This work is licensed under a Creative Commons Attribution-NonCommercial-NoDerivs 3.0 Unported License. + * + * To view a copy of this license, visit http://creativecommons.org/licenses/by-nc-nd/3.0/. + ******************************************************************************/ +package forestry.pipes; + +import net.minecraft.entity.player.EntityPlayer; +import net.minecraft.tileentity.TileEntity; +import net.minecraft.world.World; +import buildcraft.transport.Pipe; +import buildcraft.transport.TileGenericPipe; +import cpw.mods.fml.common.network.IGuiHandler; +import forestry.core.network.GuiId; +import forestry.pipes.gui.ContainerPropolisPipe; +import forestry.pipes.gui.GuiPropolisPipe; +import forestry.plugins.PluginApiculture; + +public class GuiHandlerPipes implements IGuiHandler { + + private Pipe getPipe(World world, int x, int y, int z) { + TileEntity tile = world.getBlockTileEntity(x, y, z); + if (tile == null) + return null; + + if (!(tile instanceof TileGenericPipe)) + return null; + + return ((TileGenericPipe) tile).pipe; + } + + @Override + public Object getClientGuiElement(int id, EntityPlayer player, World world, int x, int y, int z) { + + if (id >= GuiId.values().length) + return null; + + switch (GuiId.values()[id]) { + case PropolisPipeGUI: + return new GuiPropolisPipe(player, (PipeItemsPropolis)getPipe(world, x, y, z)); + default: + return null; + + } + } + + @Override + public Object getServerGuiElement(int id, EntityPlayer player, World world, int x, int y, int z) { + + if (id >= GuiId.values().length) + return null; + + switch (GuiId.values()[id]) { + case PropolisPipeGUI: + PluginApiculture.beeInterface.getBreedingTracker(world, player.username).synchToPlayer(player); + return new ContainerPropolisPipe(player.inventory, (PipeItemsPropolis)getPipe(world, x, y, z)); + default: + return null; + + } + } + +} diff --git a/pipes_common/forestry/pipes/PipeIconProvider.java b/pipes_common/forestry/pipes/PipeIconProvider.java new file mode 100755 index 000000000..f1679d0b4 --- /dev/null +++ b/pipes_common/forestry/pipes/PipeIconProvider.java @@ -0,0 +1,40 @@ +/******************************************************************************* + * Copyright 2011-2014 by SirSengir + * + * This work is licensed under a Creative Commons Attribution-NonCommercial-NoDerivs 3.0 Unported License. + * + * To view a copy of this license, visit http://creativecommons.org/licenses/by-nc-nd/3.0/. + ******************************************************************************/ +package forestry.pipes; + +import net.minecraft.client.renderer.texture.IconRegister; +import net.minecraft.util.Icon; +import buildcraft.api.core.IIconProvider; +import cpw.mods.fml.relauncher.Side; +import cpw.mods.fml.relauncher.SideOnly; +import forestry.core.render.TextureManager; + +public class PipeIconProvider implements IIconProvider { + + private static Icon[] icons; + + @Override + @SideOnly(Side.CLIENT) + public Icon getIcon(int iconIndex) { + return icons[iconIndex]; + } + + @Override + @SideOnly(Side.CLIENT) + public void registerIcons(IconRegister iconRegister) { + icons = new Icon[7]; + icons[0] = TextureManager.getInstance().registerTex(iconRegister, "pipes/pipe_prop.empty"); + icons[1] = TextureManager.getInstance().registerTex(iconRegister, "pipes/pipe_prop.black"); + icons[2] = TextureManager.getInstance().registerTex(iconRegister, "pipes/pipe_prop.white"); + icons[3] = TextureManager.getInstance().registerTex(iconRegister, "pipes/pipe_prop.red"); + icons[4] = TextureManager.getInstance().registerTex(iconRegister, "pipes/pipe_prop.blue"); + icons[5] = TextureManager.getInstance().registerTex(iconRegister, "pipes/pipe_prop.green"); + icons[6] = TextureManager.getInstance().registerTex(iconRegister, "pipes/pipe_prop.yellow"); + } + +} diff --git a/pipes_common/forestry/pipes/PipeItemsPropolis.java b/pipes_common/forestry/pipes/PipeItemsPropolis.java new file mode 100755 index 000000000..0506565d4 --- /dev/null +++ b/pipes_common/forestry/pipes/PipeItemsPropolis.java @@ -0,0 +1,160 @@ +/******************************************************************************* + * Copyright 2011-2014 by SirSengir + * + * This work is licensed under a Creative Commons Attribution-NonCommercial-NoDerivs 3.0 Unported License. + * + * To view a copy of this license, visit http://creativecommons.org/licenses/by-nc-nd/3.0/. + ******************************************************************************/ +package forestry.pipes; + +import java.util.ArrayList; +import java.util.LinkedList; + +import net.minecraft.block.Block; +import net.minecraft.entity.player.EntityPlayer; +import net.minecraft.nbt.NBTTagCompound; +import net.minecraftforge.common.ForgeDirection; +import buildcraft.api.core.IIconProvider; +import buildcraft.api.core.Position; +import buildcraft.transport.BlockGenericPipe; +import buildcraft.transport.IPipeTransportItemsHook; +import buildcraft.transport.Pipe; +import buildcraft.transport.PipeTransportItems; +import buildcraft.transport.TransportConstants; +import buildcraft.transport.TravelingItem; +import cpw.mods.fml.relauncher.Side; +import cpw.mods.fml.relauncher.SideOnly; +import forestry.api.apiculture.IBee; +import forestry.api.core.ForestryAPI; +import forestry.api.genetics.IAllele; +import forestry.core.network.GuiId; +import forestry.core.proxy.Proxies; +import forestry.plugins.PluginApiculture; + +public class PipeItemsPropolis extends Pipe implements IPipeTransportItemsHook { + + public final PipeLogicPropolis pipeLogic; + + public PipeItemsPropolis(int itemID) { + super(new PipeTransportItems(), itemID); + pipeLogic = new PipeLogicPropolis(this); + transport.allowBouncing = true; + } + + @Override + public void readFromNBT(NBTTagCompound nbt) { + super.readFromNBT(nbt); + pipeLogic.readFromNBT(nbt); + } + + @Override + public void writeToNBT(NBTTagCompound nbt) { + super.writeToNBT(nbt); + pipeLogic.writeToNBT(nbt); + } + IIconProvider provider; + + @SideOnly(Side.CLIENT) + @Override + public IIconProvider getIconProvider() { + if (provider == null) + provider = new PipeIconProvider(); + + return provider; + } + + @Override + public int getIconIndex(ForgeDirection direction) { + if (direction == ForgeDirection.UNKNOWN) + return 0; + + return direction.ordinal() + 1; + } + + @Override + public boolean blockActivated(EntityPlayer player) { + if (!Proxies.common.isSimulating(getWorld())) + return true; + + if (player.getCurrentEquippedItem() != null && player.getCurrentEquippedItem().itemID < Block.blocksList.length) + if (Block.blocksList[player.getCurrentEquippedItem().itemID] instanceof BlockGenericPipe) + return false; + + player.openGui(ForestryAPI.instance, GuiId.PropolisPipeGUI.ordinal(), player.worldObj, container.xCoord, container.yCoord, container.zCoord); + + return true; + } + + @Override + public LinkedList filterPossibleMovements(LinkedList possibleOrientations, Position pos, TravelingItem item) { + + LinkedList filteredOrientations = new LinkedList(); + LinkedList typedOrientations = new LinkedList(); + LinkedList defaultOrientations = new LinkedList(); + + // We need a bee! + EnumFilterType type = EnumFilterType.getType(item.getItemStack()); + IBee bee = null; + + if (type != EnumFilterType.ITEM) + bee = PluginApiculture.beeInterface.getMember(item.getItemStack()); + + // Filtered outputs + for (ForgeDirection dir : possibleOrientations) { + + // Continue if this direction is closed. + if (pipeLogic.isClosed(dir)) + continue; + + if (pipeLogic.isIndiscriminate(dir)) { + defaultOrientations.add(dir); + continue; + } + + // We need to match the type for this orientation's filter + if (!pipeLogic.matchType(dir, type, bee)) + continue; + + // Passing the type filter is enough for non-bee items. + if (type == EnumFilterType.ITEM) { + filteredOrientations.add(dir); + continue; + } + + ArrayList filters = pipeLogic.getGenomeFilters(dir); + // If we have no genome filters, this is only a typed route. + if (filters.size() <= 0) { + typedOrientations.add(dir); + continue; + } + + // Bees need to match one of the genome filters + for (IAllele[] pattern : filters) { + if (pipeLogic.matchAllele(pattern[0], bee.getIdent()) && pipeLogic.matchAllele(pattern[1], bee.getGenome().getSecondary().getUID())) + filteredOrientations.add(dir); + } + } + + if (filteredOrientations.size() > 0) + return filteredOrientations; + else if (typedOrientations.size() > 0) + return typedOrientations; + else + return defaultOrientations; + + } + + @Override + public void entityEntered(TravelingItem item, ForgeDirection orientation) { + // A bit of speed to perhaps prevent bees from popping out of the pipe. + try { + item.setSpeed(TransportConstants.PIPE_NORMAL_SPEED * 20F); + } catch (Throwable error) { + } + } + + @Override + public void readjustSpeed(TravelingItem item) { + transport.defaultReajustSpeed(item); + } +} diff --git a/pipes_common/forestry/pipes/PipeLogicPropolis.java b/pipes_common/forestry/pipes/PipeLogicPropolis.java new file mode 100755 index 000000000..460a24b6d --- /dev/null +++ b/pipes_common/forestry/pipes/PipeLogicPropolis.java @@ -0,0 +1,206 @@ +/******************************************************************************* + * Copyright 2011-2014 by SirSengir + * + * This work is licensed under a Creative Commons Attribution-NonCommercial-NoDerivs 3.0 Unported License. + * + * To view a copy of this license, visit http://creativecommons.org/licenses/by-nc-nd/3.0/. + ******************************************************************************/ +package forestry.pipes; + +import java.util.ArrayList; + +import net.minecraft.block.Block; +import net.minecraft.entity.player.EntityPlayer; +import net.minecraft.nbt.NBTTagCompound; +import net.minecraftforge.common.ForgeDirection; +import buildcraft.transport.BlockGenericPipe; +import buildcraft.transport.Pipe; +import forestry.api.apiculture.EnumBeeChromosome; +import forestry.api.apiculture.IBee; +import forestry.api.core.ForestryAPI; +import forestry.api.genetics.AlleleManager; +import forestry.api.genetics.IAllele; +import forestry.api.genetics.IAlleleSpecies; +import forestry.core.network.GuiId; +import forestry.core.network.PacketCoordinates; +import forestry.core.network.PacketIds; +import forestry.core.network.PacketNBT; +import forestry.core.network.PacketPayload; +import forestry.core.network.PacketUpdate; +import forestry.core.proxy.Proxies; + +public class PipeLogicPropolis { + + private Pipe pipe; + + private EnumFilterType[] typeFilter = new EnumFilterType[6]; + private IAllele[][][] genomeFilter = new IAllele[6][3][2]; + + public PipeLogicPropolis(Pipe pipe) { + this.pipe = pipe; + for (int i = 0; i < typeFilter.length; i++) + typeFilter[i] = EnumFilterType.CLOSED; + } + + public void readFromNBT(NBTTagCompound nbttagcompound) { + for (int i = 0; i < typeFilter.length; i++) + typeFilter[i] = EnumFilterType.values()[nbttagcompound.getByte("TypeFilter" + i)]; + + for (int i = 0; i < 6; i++) + for (int j = 0; j < 3; j++) { + if (nbttagcompound.hasKey("GenomeFilterS" + i + "-" + j + "-" + 0)) + genomeFilter[i][j][0] = AlleleManager.alleleRegistry.getAllele(nbttagcompound.getString("GenomeFilterS" + i + "-" + j + "-" + 0)); + if (nbttagcompound.hasKey("GenomeFilterS" + i + "-" + j + "-" + 1)) + genomeFilter[i][j][1] = AlleleManager.alleleRegistry.getAllele(nbttagcompound.getString("GenomeFilterS" + i + "-" + j + "-" + 1)); + } + } + + public void writeToNBT(NBTTagCompound nbttagcompound) { + for (int i = 0; i < typeFilter.length; i++) + nbttagcompound.setByte("TypeFilter" + i, (byte) typeFilter[i].ordinal()); + + for (int i = 0; i < 6; i++) + for (int j = 0; j < 3; j++) { + if (genomeFilter[i][j][0] != null) + nbttagcompound.setString("GenomeFilterS" + i + "-" + j + "-" + 0, genomeFilter[i][j][0].getUID()); + if (genomeFilter[i][j][1] != null) + nbttagcompound.setString("GenomeFilterS" + i + "-" + j + "-" + 1, genomeFilter[i][j][1].getUID()); + } + } + + public boolean isClosed(ForgeDirection orientation) { + return typeFilter[orientation.ordinal()] == EnumFilterType.CLOSED; + } + + public boolean isIndiscriminate(ForgeDirection orientation) { + return typeFilter[orientation.ordinal()] == EnumFilterType.ANYTHING; + } + + public boolean matchType(ForgeDirection orientation, EnumFilterType type, IBee bee) { + EnumFilterType filter = typeFilter[orientation.ordinal()]; + if (filter == EnumFilterType.BEE) + return type != EnumFilterType.ITEM && type != EnumFilterType.CLOSED && type != EnumFilterType.CLOSED; + + // Special bee filtering + if (bee != null) { + if (filter == EnumFilterType.PURE_BREED) + return bee.isPureBred(EnumBeeChromosome.SPECIES.ordinal()); + if (filter == EnumFilterType.NOCTURNAL) + return bee.getGenome().getNocturnal(); + if (filter == EnumFilterType.PURE_NOCTURNAL) + return bee.getGenome().getNocturnal() && bee.isPureBred(EnumBeeChromosome.NOCTURNAL.ordinal()); + if (filter == EnumFilterType.FLYER) + return bee.getGenome().getTolerantFlyer(); + if (filter == EnumFilterType.PURE_FLYER) + return bee.getGenome().getTolerantFlyer() && bee.isPureBred(EnumBeeChromosome.TOLERANT_FLYER.ordinal()); + if (filter == EnumFilterType.CAVE) + return bee.getGenome().getCaveDwelling(); + if (filter == EnumFilterType.PURE_CAVE) + return bee.getGenome().getCaveDwelling() && bee.isPureBred(EnumBeeChromosome.CAVE_DWELLING.ordinal()); + if (filter == EnumFilterType.NATURAL) + return bee.isNatural(); + } + + // Compare the remaining + return filter == type; + } + + public boolean matchAllele(IAllele filter, String ident) { + if (filter == null) + return true; + else + return filter.getUID().equals(ident); + } + + public ArrayList getGenomeFilters(ForgeDirection orientation) { + ArrayList filters = new ArrayList(); + + for (int i = 0; i < 3; i++) + if (genomeFilter[orientation.ordinal()][i] != null + && (genomeFilter[orientation.ordinal()][i][0] != null || genomeFilter[orientation.ordinal()][i][1] != null)) + filters.add(genomeFilter[orientation.ordinal()][i]); + + return filters; + } + + public EnumFilterType getTypeFilter(ForgeDirection orientation) { + return typeFilter[orientation.ordinal()]; + } + + public void setTypeFilter(ForgeDirection orientation, EnumFilterType type) { + typeFilter[orientation.ordinal()] = type; + if (!Proxies.common.isSimulating(pipe.getWorld())) + sendTypeFilterChange(orientation, type); + } + + public IAlleleSpecies getSpeciesFilter(ForgeDirection orientation, int pattern, int allele) { + + if (genomeFilter[orientation.ordinal()] == null) + return null; + + if (genomeFilter[orientation.ordinal()].length <= pattern) + return null; + + if (genomeFilter[orientation.ordinal()][pattern] == null) + return null; + + if (genomeFilter[orientation.ordinal()][pattern].length <= allele) + return null; + + return (IAlleleSpecies) genomeFilter[orientation.ordinal()][pattern][allele]; + } + + public void setSpeciesFilter(ForgeDirection orientation, int pattern, int allele, IAllele species) { + genomeFilter[orientation.ordinal()][pattern][allele] = species; + if (!Proxies.common.isSimulating(pipe.getWorld())) + sendGenomeFilterChange(orientation, pattern, allele, species); + } + + // Server side + public void sendFilterSet(EntityPlayer player) { + NBTTagCompound nbttagcompound = new NBTTagCompound(); + this.writeToNBT(nbttagcompound); + Proxies.net.sendToPlayer(new PacketNBT(PacketIds.PROP_SEND_FILTER_SET, nbttagcompound), player); + } + + public void handleTypeFilterChange(PacketPayload payload) { + typeFilter[payload.intPayload[0]] = EnumFilterType.values()[payload.intPayload[1]]; + } + + public void handleGenomeFilterChange(PacketPayload payload) { + if (!payload.stringPayload[0].equals("NULL")) + genomeFilter[payload.intPayload[0]][payload.intPayload[1]][payload.intPayload[2]] = AlleleManager.alleleRegistry + .getAllele(payload.stringPayload[0]); + else + genomeFilter[payload.intPayload[0]][payload.intPayload[1]][payload.intPayload[2]] = null; + } + + // Client side + public void requestFilterSet() { + Proxies.net.sendToServer(new PacketCoordinates(PacketIds.PROP_REQUEST_FILTER_SET, pipe.container.xCoord, pipe.container.yCoord, pipe.container.zCoord)); + } + + public void sendTypeFilterChange(ForgeDirection orientation, EnumFilterType filter) { + PacketPayload payload = new PacketPayload(2, 0, 0); + payload.intPayload[0] = orientation.ordinal(); + payload.intPayload[1] = filter.ordinal(); + Proxies.net.sendToServer(new PacketUpdate(PacketIds.PROP_SEND_FILTER_CHANGE_TYPE, pipe.container.xCoord, pipe.container.yCoord, pipe.container.zCoord, payload)); + } + + public void sendGenomeFilterChange(ForgeDirection orientation, int pattern, int allele, IAllele species) { + PacketPayload payload = new PacketPayload(3, 0, 1); + payload.intPayload[0] = orientation.ordinal(); + payload.intPayload[1] = pattern; + payload.intPayload[2] = allele; + if (species != null) + payload.stringPayload[0] = species.getUID(); + else + payload.stringPayload[0] = "NULL"; + + Proxies.net.sendToServer(new PacketUpdate(PacketIds.PROP_SEND_FILTER_CHANGE_GENOME, pipe.container.xCoord, pipe.container.yCoord, pipe.container.zCoord, payload)); + } + + public void handleFilterSet(PacketNBT packet) { + this.readFromNBT(packet.getTagCompound()); + } +} diff --git a/pipes_common/forestry/pipes/gui/ContainerPropolisPipe.java b/pipes_common/forestry/pipes/gui/ContainerPropolisPipe.java new file mode 100755 index 000000000..7a7a94467 --- /dev/null +++ b/pipes_common/forestry/pipes/gui/ContainerPropolisPipe.java @@ -0,0 +1,44 @@ +/** + * Copyright (c) SpaceToad, 2011 + * http://www.mod-buildcraft.com + * + * BuildCraft is distributed under the terms of the Minecraft Mod Public + * License 1.0, or MMPL. Please check the contents of the license located in + * http://www.mod-buildcraft.com/MMPL-1.0.txt + */ + +package forestry.pipes.gui; + +import net.minecraft.entity.player.EntityPlayer; +import net.minecraft.inventory.IInventory; +import net.minecraft.inventory.Slot; +import buildcraft.transport.Pipe; +import forestry.core.gui.ContainerForestry; +import forestry.core.utils.InventoryAdapter; +import forestry.pipes.PipeItemsPropolis; +import forestry.pipes.PipeLogicPropolis; + +public class ContainerPropolisPipe extends ContainerForestry { + + IInventory playerIInventory; + public PipeLogicPropolis pipeLogic; + + public ContainerPropolisPipe(IInventory playerInventory, PipeItemsPropolis pipe) { + super(new InventoryAdapter(0, "Empty")); + this.playerIInventory = playerInventory; + this.pipeLogic = (PipeLogicPropolis) pipe.pipeLogic; + + for (int l = 0; l < 3; l++) + for (int k1 = 0; k1 < 9; k1++) + addSlot(new Slot(playerInventory, k1 + l * 9 + 9, 8 + k1 * 18, 140 + l * 18)); + + for (int i1 = 0; i1 < 9; i1++) + addSlot(new Slot(playerInventory, i1, 8 + i1 * 18, 198)); + } + + @Override + public boolean canInteractWith(EntityPlayer entityplayer) { + return true; + } + +} diff --git a/pipes_common/forestry/pipes/gui/GuiPropolisPipe.java b/pipes_common/forestry/pipes/gui/GuiPropolisPipe.java new file mode 100755 index 000000000..c79ca7b69 --- /dev/null +++ b/pipes_common/forestry/pipes/gui/GuiPropolisPipe.java @@ -0,0 +1,237 @@ +/******************************************************************************* + * Copyright 2011-2014 by SirSengir + * + * This work is licensed under a Creative Commons Attribution-NonCommercial-NoDerivs 3.0 Unported License. + * + * To view a copy of this license, visit http://creativecommons.org/licenses/by-nc-nd/3.0/. + ******************************************************************************/ +package forestry.pipes.gui; + +import java.util.Iterator; +import java.util.Locale; +import java.util.Map.Entry; + +import net.minecraft.entity.player.EntityPlayer; +import net.minecraft.util.Icon; +import net.minecraftforge.common.ForgeDirection; + +import org.lwjgl.opengl.GL11; + +import buildcraft.transport.Pipe; +import forestry.api.apiculture.IAlleleBeeSpecies; +import forestry.api.apiculture.IApiaristTracker; +import forestry.api.genetics.AlleleManager; +import forestry.api.genetics.IAllele; +import forestry.api.genetics.IAlleleSpecies; +import forestry.apiculture.items.ItemBeeGE; +import forestry.core.config.Config; +import forestry.core.config.Defaults; +import forestry.core.config.ForestryItem; +import forestry.core.genetics.ItemGE; +import forestry.core.gui.widgets.Widget; +import forestry.core.gui.GuiForestry; +import forestry.core.proxy.Proxies; +import forestry.core.render.SpriteSheet; +import forestry.core.utils.StringUtil; +import forestry.pipes.EnumFilterType; +import forestry.pipes.PipeItemsPropolis; +import forestry.pipes.PipeLogicPropolis; +import forestry.plugins.PluginApiculture; + +/** + * GuiScreen for propolis pipes. + * + * @author SirSengir + */ +public class GuiPropolisPipe extends GuiForestry { + + class TypeFilterSlot extends Widget { + + ForgeDirection orientation; + PipeLogicPropolis logic; + + public TypeFilterSlot(int x, int y, ForgeDirection orientation, PipeLogicPropolis logic) { + super(widgetManager, x, y); + this.orientation = orientation; + this.logic = logic; + } + + public EnumFilterType getType() { + return logic.getTypeFilter(orientation); + } + + @Override + public void draw(int startX, int startY) { + EnumFilterType type = logic.getTypeFilter(orientation); + Icon icon = null; + if (type != null) + icon = type.getIcon(); + if(icon == null) + return; + + GL11.glColor4f(1.0f, 1.0f, 1.0f, 1.0F); + Proxies.common.bindTexture(SpriteSheet.ITEMS); + drawTexturedModelRectFromIcon(startX + xPos, startY + yPos, icon, 16, 16); + + } + + @Override + protected String getLegacyTooltip(EntityPlayer player) { + EnumFilterType type = logic.getTypeFilter(orientation); + return StringUtil.localize("gui.pipe.filter." + type.toString().toLowerCase(Locale.ENGLISH)); + } + + @Override + public void handleMouseClick(int mouseX, int mouseY, int mouseButton) { + EnumFilterType change; + if (mouseButton == 1) + change = EnumFilterType.CLOSED; + else if (getType().ordinal() < EnumFilterType.values().length - 1) + change = EnumFilterType.values()[getType().ordinal() + 1]; + else + change = EnumFilterType.CLOSED; + pipeLogic.setTypeFilter(orientation, change); + + } + + } + + class SpeciesFilterSlot extends Widget { + + IApiaristTracker tracker; + ForgeDirection orientation; + PipeLogicPropolis logic; + int pattern; + int allele; + + public SpeciesFilterSlot(IApiaristTracker tracker, int x, int y, ForgeDirection orientation, int pattern, int allele, PipeLogicPropolis logic) { + super(widgetManager, x, y); + this.tracker = tracker; + this.orientation = orientation; + this.pattern = pattern; + this.allele = allele; + this.logic = logic; + } + + public IAlleleSpecies getSpecies() { + return logic.getSpeciesFilter(orientation, pattern, allele); + } + + public boolean isDefined() { + IAlleleSpecies species = logic.getSpeciesFilter(orientation, pattern, allele); + return species != null; + } + + @Override + public void draw(int startX, int startY) { + if (!isDefined()) + return; + + IAlleleSpecies species = logic.getSpeciesFilter(orientation, pattern, allele); + GL11.glDisable(GL11.GL_LIGHTING); + + for (int i = 0; i < 3; ++i) { + + Icon icon = ((ItemBeeGE) ForestryItem.beeDroneGE.item()).getIconFromSpecies((IAlleleBeeSpecies) species, i); + int color = ((ItemGE) ForestryItem.beeDroneGE.item()).getColourFromSpecies(species, i); + + float colorR = (color >> 16 & 255) / 255.0F; + float colorG = (color >> 8 & 255) / 255.0F; + float colorB = (color & 255) / 255.0F; + + GL11.glColor4f(colorR, colorG, colorB, 1.0F); + // drawTexturedModalRect(startX + xPos, startY + yPos, iconIndex % 16 * 16, iconIndex / 16 * 16, 16, 16); + manager.gui.drawTexturedModelRectFromIcon(startX + xPos, startY + yPos, icon, 16, 16); + + } + GL11.glEnable(GL11.GL_LIGHTING); + + } + + @Override + protected String getLegacyTooltip(EntityPlayer player) { + IAlleleSpecies species = logic.getSpeciesFilter(orientation, pattern, allele); + if (species != null) + return species.getName(); + else + return null; + } + + @Override + public void handleMouseClick(int mouseX, int mouseY, int mouseButton) { + IAlleleSpecies change = null; + if (mouseButton == 1) + change = null; + else if (getSpecies() == null) { + + Iterator it = AlleleManager.alleleRegistry.getRegisteredAlleles().entrySet().iterator(); + while (it.hasNext()) { + Entry entry = (Entry) it.next(); + if (!(entry.getValue() instanceof IAlleleBeeSpecies)) + continue; + + change = (IAlleleBeeSpecies) entry.getValue(); + break; + } + + } else { + + Iterator it = AlleleManager.alleleRegistry.getRegisteredAlleles().entrySet().iterator(); + while (it.hasNext()) { + Entry entry = (Entry) it.next(); + if (!(entry.getValue() instanceof IAlleleBeeSpecies)) + continue; + + IAlleleBeeSpecies species = (IAlleleBeeSpecies) entry.getValue(); + if (!species.getUID().equals(getSpecies().getUID())) + continue; + + while (it.hasNext()) { + Entry entry2 = (Entry) it.next(); + if (!(entry2.getValue() instanceof IAlleleBeeSpecies)) + continue; + + IAlleleBeeSpecies next = (IAlleleBeeSpecies) entry2.getValue(); + if (!Config.isDebug && next.isSecret() && !tracker.isDiscovered(next)) + continue; + + change = next; + break; + } + + break; + } + } + pipeLogic.setSpeciesFilter(orientation, pattern, allele, change); + } + } + + PipeLogicPropolis pipeLogic; + + public GuiPropolisPipe(EntityPlayer player, PipeItemsPropolis pipe) { + super(Defaults.TEXTURE_PATH_GUI + "/analyzer.png", new ContainerPropolisPipe(player.inventory, pipe)); + + pipeLogic = pipe.pipeLogic; + // Request filter set update if on client + if (!Proxies.common.isSimulating(pipe.getWorld())) + pipeLogic.requestFilterSet(); + + xSize = 175; + ySize = 225; + + for (int i = 0; i < 6; i++) + widgetManager.add(new TypeFilterSlot(8, 18 + i * 18, ForgeDirection.values()[i], pipeLogic)); + + IApiaristTracker tracker = PluginApiculture.beeInterface.getBreedingTracker(player.worldObj, player.username); + for (int i = 0; i < 6; i++) + for (int j = 0; j < 3; j++) + for (int k = 0; k < 2; k++) + widgetManager.add(new SpeciesFilterSlot(tracker, 44 + j * 45 + k * 18, 18 + i * 18, ForgeDirection.values()[i], j, k, pipeLogic)); + } + + @Override + protected void drawGuiContainerForegroundLayer(int mouseX, int mouseY) { + super.drawGuiContainerForegroundLayer(mouseX, mouseY); + fontRenderer.drawString("Apiarist's Pipe", 56, 6, 0x303030); + } +} diff --git a/pipes_common/forestry/pipes/network/PacketHandlerPipes.java b/pipes_common/forestry/pipes/network/PacketHandlerPipes.java new file mode 100755 index 000000000..dd86d8e7b --- /dev/null +++ b/pipes_common/forestry/pipes/network/PacketHandlerPipes.java @@ -0,0 +1,122 @@ +/******************************************************************************* + * Copyright 2011-2014 by SirSengir + * + * This work is licensed under a Creative Commons Attribution-NonCommercial-NoDerivs 3.0 Unported License. + * + * To view a copy of this license, visit http://creativecommons.org/licenses/by-nc-nd/3.0/. + ******************************************************************************/ +package forestry.pipes.network; + +import java.io.DataInputStream; + +import net.minecraft.entity.player.EntityPlayer; +import net.minecraft.inventory.Container; +import net.minecraft.network.INetworkManager; +import net.minecraft.tileentity.TileEntity; +import net.minecraft.world.World; +import buildcraft.transport.Pipe; +import buildcraft.transport.TileGenericPipe; +import cpw.mods.fml.common.network.Player; +import forestry.core.interfaces.IPacketHandler; +import forestry.core.network.PacketCoordinates; +import forestry.core.network.PacketIds; +import forestry.core.network.PacketNBT; +import forestry.core.network.PacketUpdate; +import forestry.core.proxy.Proxies; +import forestry.pipes.PipeItemsPropolis; +import forestry.pipes.PipeLogicPropolis; +import forestry.pipes.gui.ContainerPropolisPipe; + +public class PacketHandlerPipes implements IPacketHandler { + + private Pipe getPipe(World world, int x, int y, int z) { + TileEntity tile = world.getBlockTileEntity(x, y, z); + if (tile == null) + return null; + + if (!(tile instanceof TileGenericPipe)) + return null; + + return ((TileGenericPipe) tile).pipe; + } + + @Override + public void onPacketData(INetworkManager network, int packetID, DataInputStream data, Player player) { + + try { + + PacketUpdate packetU; + + switch (packetID) { + + // CLIENT + case PacketIds.PROP_SEND_FILTER_SET: + PacketNBT packetN = new PacketNBT(); + packetN.readData(data); + onFilterSet(packetN); + break; + + // SERVER + case PacketIds.PROP_REQUEST_FILTER_SET: + PacketCoordinates packetC = new PacketCoordinates(); + packetC.readData(data); + onRequestFilterSet((EntityPlayer) player, packetC); + break; + case PacketIds.PROP_SEND_FILTER_CHANGE_TYPE: + packetU = new PacketUpdate(); + packetU.readData(data); + onTypeFilterChange((EntityPlayer) player, packetU); + break; + case PacketIds.PROP_SEND_FILTER_CHANGE_GENOME: + packetU = new PacketUpdate(); + packetU.readData(data); + onGenomeFilterChange((EntityPlayer) player, packetU); + break; + + } + } catch (Exception ex) { + ex.printStackTrace(); + } + } + + private void onFilterSet(PacketNBT packet) { + Container container = Proxies.common.getClientInstance().thePlayer.openContainer; + + if (container instanceof ContainerPropolisPipe) { + PipeLogicPropolis pipeLogic = ((ContainerPropolisPipe) container).pipeLogic; + pipeLogic.handleFilterSet(packet); + } + } + + private void onTypeFilterChange(EntityPlayer player, PacketUpdate packet) { + + Pipe pipe = getPipe(player.worldObj, packet.posX, packet.posY, packet.posZ); + if (pipe == null) + return; + + if (pipe instanceof PipeItemsPropolis) + ((PipeItemsPropolis) pipe).pipeLogic.handleTypeFilterChange(packet.payload); + + } + + private void onGenomeFilterChange(EntityPlayer player, PacketUpdate packet) { + + Pipe pipe = getPipe(player.worldObj, packet.posX, packet.posY, packet.posZ); + if (pipe == null) + return; + + if (pipe instanceof PipeItemsPropolis) + ((PipeItemsPropolis) pipe).pipeLogic.handleGenomeFilterChange(packet.payload); + } + + private void onRequestFilterSet(EntityPlayer player, PacketCoordinates packet) { + + Pipe pipe = getPipe(player.worldObj, packet.posX, packet.posY, packet.posZ); + if (pipe == null) + return; + + if (pipe instanceof PipeItemsPropolis) + ((PipeItemsPropolis) pipe).pipeLogic.sendFilterSet(player); + } + +} diff --git a/pipes_common/forestry/pipes/proxy/ClientProxyPipes.java b/pipes_common/forestry/pipes/proxy/ClientProxyPipes.java new file mode 100755 index 000000000..ef8557afc --- /dev/null +++ b/pipes_common/forestry/pipes/proxy/ClientProxyPipes.java @@ -0,0 +1,34 @@ +/******************************************************************************* + * Copyright 2011-2014 by SirSengir + * + * This work is licensed under a Creative Commons Attribution-NonCommercial-NoDerivs 3.0 Unported License. + * + * To view a copy of this license, visit http://creativecommons.org/licenses/by-nc-nd/3.0/. + ******************************************************************************/ +package forestry.pipes.proxy; + +import net.minecraftforge.client.IItemRenderer; +import net.minecraftforge.client.MinecraftForgeClient; +import buildcraft.core.utils.Localization; +import buildcraft.transport.TransportProxyClient; +import forestry.plugins.PluginPropolisPipe; + +public class ClientProxyPipes extends ProxyPipes { + + @Override + public void registerCustomItemRenderer(int itemID, IItemRenderer basemod) { + MinecraftForgeClient.registerItemRenderer(itemID, basemod); + } + + @Override + public void initPropolisPipe() { + super.initPropolisPipe(); + registerCustomItemRenderer(PluginPropolisPipe.pipeItemsPropolis.itemID, TransportProxyClient.pipeItemRenderer); + } + + @Override + public void addLocalizations() { + Localization.addLocalization("/lang/forestry/pipes/", "en_US"); + } + +} diff --git a/pipes_common/forestry/pipes/proxy/ProxyPipes.java b/pipes_common/forestry/pipes/proxy/ProxyPipes.java new file mode 100755 index 000000000..c68f7a7ab --- /dev/null +++ b/pipes_common/forestry/pipes/proxy/ProxyPipes.java @@ -0,0 +1,45 @@ +/******************************************************************************* + * Copyright 2011-2014 by SirSengir + * + * This work is licensed under a Creative Commons Attribution-NonCommercial-NoDerivs 3.0 Unported License. + * + * To view a copy of this license, visit http://creativecommons.org/licenses/by-nc-nd/3.0/. + ******************************************************************************/ +package forestry.pipes.proxy; + +import net.minecraft.item.Item; +import net.minecraft.item.ItemStack; +import net.minecraftforge.client.IItemRenderer; +import buildcraft.BuildCraftTransport; +import buildcraft.transport.BlockGenericPipe; +import buildcraft.transport.Pipe; +import cpw.mods.fml.common.registry.GameRegistry; +import forestry.pipes.PipeItemsPropolis; +import forestry.plugins.PluginPropolisPipe; + +public class ProxyPipes { + + public void registerCustomItemRenderer(int itemID, IItemRenderer basemod) { + } + + public void initPropolisPipe() { + PluginPropolisPipe.pipeItemsPropolis = createPipe(PluginPropolisPipe.propolisPipeItemId, PipeItemsPropolis.class, "Apiarist's Pipe"); + } + + public Item createPipe(int id, Class clas, String description) { + + Item pipe = BlockGenericPipe.registerPipe(id, clas); + pipe.setUnlocalizedName(clas.getSimpleName()); + + return pipe; + } + + public void registerCraftingPropolis(ItemStack resource) { + GameRegistry.addRecipe(new ItemStack(PluginPropolisPipe.pipeItemsPropolis), + new Object[] { "#X#", Character.valueOf('#'), resource, Character.valueOf('X'), BuildCraftTransport.pipeItemsDiamond }); + + } + + public void addLocalizations() { + } +} diff --git a/pipes_common/forestry/plugins/PluginPropolisPipe.java b/pipes_common/forestry/plugins/PluginPropolisPipe.java new file mode 100755 index 000000000..ed3c759f9 --- /dev/null +++ b/pipes_common/forestry/plugins/PluginPropolisPipe.java @@ -0,0 +1,102 @@ +/******************************************************************************* + * Copyright 2011-2014 by SirSengir + * + * This work is licensed under a Creative Commons Attribution-NonCommercial-NoDerivs 3.0 Unported License. + * + * To view a copy of this license, visit http://creativecommons.org/licenses/by-nc-nd/3.0/. + ******************************************************************************/ +package forestry.plugins; + +import net.minecraft.item.Item; +import net.minecraft.item.ItemStack; +import cpw.mods.fml.common.FMLCommonHandler; +import cpw.mods.fml.common.network.IGuiHandler; +import forestry.api.core.PluginInfo; +import forestry.core.config.Configuration; +import forestry.core.config.Defaults; +import forestry.core.config.ForestryItem; +import forestry.core.interfaces.IPacketHandler; +import forestry.core.proxy.Proxies; +import forestry.pipes.GuiHandlerPipes; +import forestry.pipes.network.PacketHandlerPipes; +import forestry.pipes.proxy.ProxyPipes; + +@PluginInfo(pluginID = "Pipes", name = "Pipes", author = "SirSengir", url = Defaults.URL, description = "Adds the apiarist's pipe for beekeeping if apiculture is enabled and BuildCraft 3 is present.") +public class PluginPropolisPipe extends NativePlugin { + + public static ProxyPipes proxy; + + static String CONFIG_CATEGORY = "pipes"; + public static Configuration config; + public static int propolisPipeItemId; + + public static String textureBees = Defaults.TEXTURE_PATH_GUI + "/analyzer_icons.png"; + /** + * Pipe used to sort bees from Forestry. + */ + public static Item pipeItemsPropolis; + + @Override + public boolean isAvailable() { + return Proxies.common.isModLoaded("BuildCraft|Transport"); + } + + @Override + public void preInit() { + + config = new Configuration(); + + propolisPipeItemId = Integer.parseInt(PluginPropolisPipe.config.get("propolisPipe", CONFIG_CATEGORY, 14000).Value); + + config.save(); + + } + + @Override + public void doInit() { + } + + @Override + public void postInit() { + String proxyClass = "forestry.pipes.proxy.ProxyPipes"; + if (FMLCommonHandler.instance().getSide().isClient()) + proxyClass = "forestry.pipes.proxy.ClientProxyPipes"; + + proxy = (ProxyPipes) Proxies.common.instantiateIfModLoaded("BuildCraft|Transport", proxyClass); + + if (proxy == null) + return; + + proxy.initPropolisPipe(); + proxy.registerCraftingPropolis(ForestryItem.propolis.getItemStack()); + proxy.addLocalizations(); + + } + + @Override + public IGuiHandler getGuiHandler() { + return new GuiHandlerPipes(); + } + + @Override + public IPacketHandler getPacketHandler() { + return new PacketHandlerPipes(); + } + + @Override + protected void registerItems() { + } + + @Override + protected void registerBackpackItems() { + } + + @Override + protected void registerCrates() { + } + + @Override + protected void registerRecipes() { + } + +}