Compare commits

...

No commits in common. "BOP-1.16.4-13.x.x" and "BOP-for-1.6" have entirely different histories.

3933 changed files with 86855 additions and 62386 deletions

View File

@ -1,27 +0,0 @@
---
name: 1.16.3 Standalone Bug
about: For bugs that occur with Biomes O' Plenty for 1.16.3. We do not support older versions!
title: ''
labels: bug-minor
assignees: ''
---
## Bug Report
[ Lines between [ ] (square brackets) should be removed before posting. ]</br>
### What's the issue you encountered?
[ Describe the issue in detail and what you were doing beforehand. ]</br>
### How can the issue be reproduced?
[ Include a detailed step by step process for recreating your issue with only Biomes O' Plenty installed. ]</br>
### Logs
[ Please include any relevant logs here. This can be done by dragging and dropping your log files into the issue. ]</br>
### Mod Version
[ Please put the version of the mod you were using here. ]</br>

View File

@ -1,23 +0,0 @@
---
name: 1.16.3 Standalone Crash
about: For crashes that occur with Biomes O' Plenty for 1.16.3. We do not support older versions!
title: ''
labels: crash
assignees: ''
---
## Bug Report
[ Lines between [ ] (square brackets) should be removed before posting. ]</br>
### How can the crash be reproduced?
[ Include a detailed step by step process for recreating your crash with only Biomes O' Plenty installed. ]</br>
### Crash Report and Logs
[ Please include your crash report and logs here. This can be done by dragging and dropping your log files and crash report files into the issue. ]</br>
### Mod Version
[ Please put the version of the mod you were using here. ]</br>

View File

@ -1,20 +0,0 @@
---
name: 1.16.3 Feature Request
about: Feature requests for Biomes O' Plenty for 1.16.3. We do not support older versions!
title: ''
labels: feature
assignees: ''
---
## Feature Request
[ Lines between [ ] (square brackets) should be removed before posting. ]</br>
### What feature are you suggesting?
[ Provide an overview of the feature being suggested. ]</br>
### Why should it be added?
[ Describe the benefits of implementing this feature. ]</br>

View File

@ -1,5 +0,0 @@
blank_issues_enabled: false
contact_links:
- name: Glitchfiend Discord
url: https://discord.gg/GyyzU6T
about: Please ask general questions here instead of opening issues for them.

61
.gitignore vendored
View File

@ -1,28 +1,39 @@
/build/
/bin/
/out/
/Mixin/
/repo/
/run/
/logs/
.idea/*
/.gradle/
/.settings/
/.classpath
/.project
*.bat
*.sh
# OS generated files
*.DS_Store
LICENSE.txt
# IntelliJ project files
*.iml
*.ipr
*.iws
temp/*
runtime/*
reobf/*
logs/*
lib/*
jars/*
forge/*
eclipse/*
docs/*
conf/*
bin/*
*.launch
mappings/.gradle/
#mappings/mcp/
mappings/build/
mappings/*.csv
mappings/.project
mappings/last_updated.json
src/minecraft/cpw/*
src/minecraft/net/minecraft/*
src/minecraft/net/minecraftforge/classloading/*
src/minecraft/net/minecraftforge/common/*
src/minecraft/net/minecraftforge/client/*
src/minecraft/net/minecraftforge/event/*
src/minecraft/net/minecraftforge/liquids/*
src/minecraft/net/minecraftforge/oredict/*
src/minecraft/net/minecraftforge/transformers/*
src/minecraft/paulscode/*
src/minecraft/ibxm/*
src/minecraft/Start.java
src/minecraft/mcpmod.info
src/minecraft/mcp.png
src/minecraft/forge_logo.png
src/minecraft/forge_at.cfg
src/minecraft/fmlversion.properties
src/minecraft/fml_marker.cfg
src/minecraft/fml_at.cfg
build_number.properties

60
Jenkinsfile vendored
View File

@ -1,60 +0,0 @@
@Library('forge-shared-library')_
pipeline {
options {
disableConcurrentBuilds()
}
agent {
docker {
image 'gradle:jdk8'
args '-v forgegc:/home/gradle/.gradle/'
}
}
environment {
GRADLE_ARGS = '--no-daemon --console=plain' // No daemon for now as FG3 kinda derps. //'-Dorg.gradle.daemon.idletimeout=5000'
JENKINS_HEAD = 'https://wiki.jenkins-ci.org/download/attachments/2916393/headshot.png'
}
stages {
stage('fetch') {
steps {
checkout scm
}
}
stage('setup') {
steps {
withGradle {
sh './gradlew ${GRADLE_ARGS} --refresh-dependencies'
}
script {
env.MYVERSION = sh(returnStdout: true, script: './gradlew :properties -q | grep "^version:" | awk \'{print $2}\'').trim()
}
}
}
stage('changelog') {
when {
not {
changeRequest()
}
}
steps {
writeChangelog(currentBuild, "build/BiomesOPlenty-${env.MYVERSION}-changelog.txt")
}
}
stage('publish') {
when {
not {
changeRequest()
}
}
environment {
CURSE_API_KEY = credentials('curse-api-key')
}
steps {
withGradle {
sh './gradlew ${GRADLE_ARGS} :uploadArchives curseforge -PcurseApiKey=${CURSE_API_KEY}'
}
}
}
}
}

View File

@ -1,325 +0,0 @@
Creative Commons Attribution-NonCommercial-NoDerivatives 4.0
International Public License
By exercising the Licensed Rights (defined below), You accept and agree
to be bound by the terms and conditions of this Creative Commons
Attribution-NonCommercial-NoDerivatives 4.0 International Public
License ("Public License"). To the extent this Public License may be
interpreted as a contract, You are granted the Licensed Rights in
consideration of Your acceptance of these terms and conditions, and the
Licensor grants You such rights in consideration of benefits the
Licensor receives from making the Licensed Material available under
these terms and conditions.
Section 1 -- Definitions.
a. Adapted Material means material subject to Copyright and Similar
Rights that is derived from or based upon the Licensed Material
and in which the Licensed Material is translated, altered,
arranged, transformed, or otherwise modified in a manner requiring
permission under the Copyright and Similar Rights held by the
Licensor. For purposes of this Public License, where the Licensed
Material is a musical work, performance, or sound recording,
Adapted Material is always produced where the Licensed Material is
synched in timed relation with a moving image.
b. Copyright and Similar Rights means copyright and/or similar rights
closely related to copyright including, without limitation,
performance, broadcast, sound recording, and Sui Generis Database
Rights, without regard to how the rights are labeled or
categorized. For purposes of this Public License, the rights
specified in Section 2(b)(1)-(2) are not Copyright and Similar
Rights.
c. Effective Technological Measures means those measures that, in the
absence of proper authority, may not be circumvented under laws
fulfilling obligations under Article 11 of the WIPO Copyright
Treaty adopted on December 20, 1996, and/or similar international
agreements.
d. Exceptions and Limitations means fair use, fair dealing, and/or
any other exception or limitation to Copyright and Similar Rights
that applies to Your use of the Licensed Material.
e. Licensed Material means the artistic or literary work, database,
or other material to which the Licensor applied this Public
License.
f. Licensed Rights means the rights granted to You subject to the
terms and conditions of this Public License, which are limited to
all Copyright and Similar Rights that apply to Your use of the
Licensed Material and that the Licensor has authority to license.
g. Licensor means the individual(s) or entity(ies) granting rights
under this Public License.
h. NonCommercial means not primarily intended for or directed towards
commercial advantage or monetary compensation. For purposes of
this Public License, the exchange of the Licensed Material for
other material subject to Copyright and Similar Rights by digital
file-sharing or similar means is NonCommercial provided there is
no payment of monetary compensation in connection with the
exchange.
i. Share means to provide material to the public by any means or
process that requires permission under the Licensed Rights, such
as reproduction, public display, public performance, distribution,
dissemination, communication, or importation, and to make material
available to the public including in ways that members of the
public may access the material from a place and at a time
individually chosen by them.
j. Sui Generis Database Rights means rights other than copyright
resulting from Directive 96/9/EC of the European Parliament and of
the Council of 11 March 1996 on the legal protection of databases,
as amended and/or succeeded, as well as other essentially
equivalent rights anywhere in the world.
k. You means the individual or entity exercising the Licensed Rights
under this Public License. Your has a corresponding meaning.
Section 2 -- Scope.
a. License grant.
1. Subject to the terms and conditions of this Public License,
the Licensor hereby grants You a worldwide, royalty-free,
non-sublicensable, non-exclusive, irrevocable license to
exercise the Licensed Rights in the Licensed Material to:
a. reproduce and Share the Licensed Material, in whole or
in part, for NonCommercial purposes only; and
b. produce and reproduce, but not Share, Adapted Material
for NonCommercial purposes only.
2. Exceptions and Limitations. For the avoidance of doubt, where
Exceptions and Limitations apply to Your use, this Public
License does not apply, and You do not need to comply with
its terms and conditions.
3. Term. The term of this Public License is specified in Section
6(a).
4. Media and formats; technical modifications allowed. The
Licensor authorizes You to exercise the Licensed Rights in
all media and formats whether now known or hereafter created,
and to make technical modifications necessary to do so. The
Licensor waives and/or agrees not to assert any right or
authority to forbid You from making technical modifications
necessary to exercise the Licensed Rights, including
technical modifications necessary to circumvent Effective
Technological Measures. For purposes of this Public License,
simply making modifications authorized by this Section 2(a)
(4) never produces Adapted Material.
5. Downstream recipients.
a. Offer from the Licensor -- Licensed Material. Every
recipient of the Licensed Material automatically
receives an offer from the Licensor to exercise the
Licensed Rights under the terms and conditions of this
Public License.
b. No downstream restrictions. You may not offer or impose
any additional or different terms or conditions on, or
apply any Effective Technological Measures to, the
Licensed Material if doing so restricts exercise of the
Licensed Rights by any recipient of the Licensed
Material.
6. No endorsement. Nothing in this Public License constitutes or
may be construed as permission to assert or imply that You
are, or that Your use of the Licensed Material is, connected
with, or sponsored, endorsed, or granted official status by,
the Licensor or others designated to receive attribution as
provided in Section 3(a)(1)(A)(i).
b. Other rights.
1. Moral rights, such as the right of integrity, are not
licensed under this Public License, nor are publicity,
privacy, and/or other similar personality rights; however, to
the extent possible, the Licensor waives and/or agrees not to
assert any such rights held by the Licensor to the limited
extent necessary to allow You to exercise the Licensed
Rights, but not otherwise.
2. Patent and trademark rights are not licensed under this
Public License.
3. To the extent possible, the Licensor waives any right to
collect royalties from You for the exercise of the Licensed
Rights, whether directly or through a collecting society
under any voluntary or waivable statutory or compulsory
licensing scheme. In all other cases the Licensor expressly
reserves any right to collect such royalties, including when
the Licensed Material is used other than for NonCommercial
purposes.
Section 3 -- License Conditions.
Your exercise of the Licensed Rights is expressly made subject to the
following conditions.
a. Attribution.
1. If You Share the Licensed Material, You must:
a. retain the following if it is supplied by the Licensor
with the Licensed Material:
i. identification of the creator(s) of the Licensed
Material and any others designated to receive
attribution, in any reasonable manner requested by
the Licensor (including by pseudonym if
designated);
ii. a copyright notice;
iii. a notice that refers to this Public License;
iv. a notice that refers to the disclaimer of
warranties;
v. a URI or hyperlink to the Licensed Material to the
extent reasonably practicable;
b. indicate if You modified the Licensed Material and
retain an indication of any previous modifications; and
c. indicate the Licensed Material is licensed under this
Public License, and include the text of, or the URI or
hyperlink to, this Public License.
For the avoidance of doubt, You do not have permission under
this Public License to Share Adapted Material.
2. You may satisfy the conditions in Section 3(a)(1) in any
reasonable manner based on the medium, means, and context in
which You Share the Licensed Material. For example, it may be
reasonable to satisfy the conditions by providing a URI or
hyperlink to a resource that includes the required
information.
3. If requested by the Licensor, You must remove any of the
information required by Section 3(a)(1)(A) to the extent
reasonably practicable.
Section 4 -- Sui Generis Database Rights.
Where the Licensed Rights include Sui Generis Database Rights that
apply to Your use of the Licensed Material:
a. for the avoidance of doubt, Section 2(a)(1) grants You the right
to extract, reuse, reproduce, and Share all or a substantial
portion of the contents of the database for NonCommercial purposes
only and provided You do not Share Adapted Material;
b. if You include all or a substantial portion of the database
contents in a database in which You have Sui Generis Database
Rights, then the database in which You have Sui Generis Database
Rights (but not its individual contents) is Adapted Material; and
c. You must comply with the conditions in Section 3(a) if You Share
all or a substantial portion of the contents of the database.
For the avoidance of doubt, this Section 4 supplements and does not
replace Your obligations under this Public License where the Licensed
Rights include other Copyright and Similar Rights.
Section 5 -- Disclaimer of Warranties and Limitation of Liability.
a. UNLESS OTHERWISE SEPARATELY UNDERTAKEN BY THE LICENSOR, TO THE
EXTENT POSSIBLE, THE LICENSOR OFFERS THE LICENSED MATERIAL AS-IS
AND AS-AVAILABLE, AND MAKES NO REPRESENTATIONS OR WARRANTIES OF
ANY KIND CONCERNING THE LICENSED MATERIAL, WHETHER EXPRESS,
IMPLIED, STATUTORY, OR OTHER. THIS INCLUDES, WITHOUT LIMITATION,
WARRANTIES OF TITLE, MERCHANTABILITY, FITNESS FOR A PARTICULAR
PURPOSE, NON-INFRINGEMENT, ABSENCE OF LATENT OR OTHER DEFECTS,
ACCURACY, OR THE PRESENCE OR ABSENCE OF ERRORS, WHETHER OR NOT
KNOWN OR DISCOVERABLE. WHERE DISCLAIMERS OF WARRANTIES ARE NOT
ALLOWED IN FULL OR IN PART, THIS DISCLAIMER MAY NOT APPLY TO YOU.
b. TO THE EXTENT POSSIBLE, IN NO EVENT WILL THE LICENSOR BE LIABLE
TO YOU ON ANY LEGAL THEORY (INCLUDING, WITHOUT LIMITATION,
NEGLIGENCE) OR OTHERWISE FOR ANY DIRECT, SPECIAL, INDIRECT,
INCIDENTAL, CONSEQUENTIAL, PUNITIVE, EXEMPLARY, OR OTHER LOSSES,
COSTS, EXPENSES, OR DAMAGES ARISING OUT OF THIS PUBLIC LICENSE OR
USE OF THE LICENSED MATERIAL, EVEN IF THE LICENSOR HAS BEEN
ADVISED OF THE POSSIBILITY OF SUCH LOSSES, COSTS, EXPENSES, OR
DAMAGES. WHERE A LIMITATION OF LIABILITY IS NOT ALLOWED IN FULL OR
IN PART, THIS LIMITATION MAY NOT APPLY TO YOU.
c. The disclaimer of warranties and limitation of liability provided
above shall be interpreted in a manner that, to the extent
possible, most closely approximates an absolute disclaimer and
waiver of all liability.
Section 6 -- Term and Termination.
a. This Public License applies for the term of the Copyright and
Similar Rights licensed here. However, if You fail to comply with
this Public License, then Your rights under this Public License
terminate automatically.
b. Where Your right to use the Licensed Material has terminated under
Section 6(a), it reinstates:
1. automatically as of the date the violation is cured, provided
it is cured within 30 days of Your discovery of the
violation; or
2. upon express reinstatement by the Licensor.
For the avoidance of doubt, this Section 6(b) does not affect any
right the Licensor may have to seek remedies for Your violations
of this Public License.
c. For the avoidance of doubt, the Licensor may also offer the
Licensed Material under separate terms or conditions or stop
distributing the Licensed Material at any time; however, doing so
will not terminate this Public License.
d. Sections 1, 5, 6, 7, and 8 survive termination of this Public
License.
Section 7 -- Other Terms and Conditions.
a. The Licensor shall not be bound by any additional or different
terms or conditions communicated by You unless expressly agreed.
b. Any arrangements, understandings, or agreements regarding the
Licensed Material not stated herein are separate from and
independent of the terms and conditions of this Public License.
Section 8 -- Interpretation.
a. For the avoidance of doubt, this Public License does not, and
shall not be interpreted to, reduce, limit, restrict, or impose
conditions on any use of the Licensed Material that could lawfully
be made without permission under this Public License.
b. To the extent possible, if any provision of this Public License is
deemed unenforceable, it shall be automatically reformed to the
minimum extent necessary to make it enforceable. If the provision
cannot be reformed, it shall be severed from this Public License
without affecting the enforceability of the remaining terms and
conditions.
c. No term or condition of this Public License will be waived and no
failure to comply consented to unless expressly agreed to by the
Licensor.
d. Nothing in this Public License constitutes or may be interpreted
as a limitation upon, or waiver of, any privileges and immunities
that apply to the Licensor or You, including from the legal
processes of any jurisdiction or authority.

480
README.md
View File

@ -1,17 +1,479 @@
<p align="center"><img src="https://i.imgur.com/HQ2opH6.png"></p>
[<img src="http://i.creativecommons.org/l/by-nc-nd/3.0/88x31.png">](http://creativecommons.org/licenses/by-nc-nd/3.0/deed.en_US)
<p align="center"><img src="https://i.imgur.com/CYxKg5M.png"></p>
Biomes O' Plenty is licensed under a [Creative Commons Attribution-NonCommercial-NoDerivs 3.0 Unported License](http://creativecommons.org/licenses/by-nc-nd/3.0/deed.en_US).
<p align="center">https://discord.gg/GyyzU6T</p>
## Authors
**Biomes O' Plenty** is a **Minecraft mod** that adds **over 50 new biomes** to the Overworld, Nether, and End. From Lavender Fields to Redwood Forests and many more, all of our biomes are decorated with a variety of **new trees, flowers, and plants!**
- **Adubbz** - "Madman" - General, Technical, Mod Compatibility
-----------------
- **Amnet** - "Foreign Affairs" - General, Technical, Mod Compatibility
**Note:** To use the mod on a **server**, you must set the **level-type** setting in your server's config file to **biomesoplenty**
- **Forstride** - "World Painter" - Founder, Art, Biome Design, General
-----------------
- **ted80** - "Biome Fanatic" - Biome Execution, General
[<img src="http://i.creativecommons.org/l/by-nc-nd/3.0/88x31.png">](http://creativecommons.org/licenses/by-nc-nd/4.0/deed.en_US)
## Credits ##
- **gamax92** - Initial Forge Conversion
- **enchilado** - Mud Tool and Armour Textures
- **Tim Rurkowski** - Music author
Biomes O' Plenty is licensed under a [Creative Commons Attribution-NonCommercial-NoDerivs 4.0 Unported License](http://creativecommons.org/licenses/by-nc-nd/4.0/deed.en_US).
- **Soaryn** - Help making the Altar Frames
- **MineModder2000** - 256 high worlds
## Changelog
(Future changelogs can be found in the releases section)
Version 1.1.0 '24-09-13'
- Made steam particles animated
- Added the Phantom
- Removed the crafting recipe for ghastly souls (*I wonder where they went*)
- Changed the biomes in which billages can generate in by default
- Added Wither Wart
- Tweaked the liquid poison textures
- Updated several localizations (Props to VeryBigBro and Vexatos)
- Fixed the Mountain biome's height
- Added gravestone gen to the nether
- Changed how willow trees generate
- Added persimmons and persimmon trees
- Changed the hunger/saturation values for food
- Added smooth sky colour transitions (this was a Forge addition, but it's worth mentioning)
- Nerfed jungle spiders
- Changed the mod logo
- Added various coloured coral
- Tweaked kelp
- Added a few ocean biomes
- Oceanic Abyss
- Coral Reef
- Kelp Forest
- Added Forge Multipart microblocks integration
- Fixed rainfall values for snowy biomes
- Added the Ochre Acres biome
- Fixed bucket container items
- Increaed growth time for apple trees
- Added wading boots
- Added flippers
- Tweaked the Oasis biome
- Added custom village materials for various biomes
- Fixed block picking on stairs (Our OCD friend Leenhaart :P)
- Added Tropics Mountain Subbiome
- Added Hibiscus
- Added Lily of the Valley
- Added Burning Blossom
- Tweaked various plant/flower textures
- Renamed Aloe to Bromeliad
- Added Lavender
- Added the Lavender Fields biome
- Added a way to grow tiny cacti and cattails with bonemeal
- Deathblooms and thorns now hurt if shears aren't used
- Added Goldenrods
- Added Bluebells
- Switched to using isGenMineableReplaceable (which in turn fixed Underground Biomes compatibility with gems)
- Added Shrubs
- Added Wheat Grass
- Added Damp Grass
- Tweaked Moss generation
- Tweaked Moss texture
- Disabled rain in the Badlands
- Made moss no longer spread
- Updated to 1.6.4
- Added Miner's Delight
- Tweaked the way Berry Bushes render
- Updated the MFR API
- Updated the Forestry API
- Added config options for the ocean biomes, wither wart and burning blossom
- Added Icy Iris
- Added Flat Mushroom
- Added cocoa trees to the Tropical Rainforest
- Added jungle wood to trees in the Brushland and Scrubland
- Tweaked marsh generation
- Added mud to Marshes
- Renamed reeds to River Cane
- Added proper reeds (You'll know them when you see them)
Version 0.6.2 '20-08-13'
- Fixed bigtrees compatibility
- Fixed another bug with altars
Version 0.6.1 '16-08-13'
- Fixed food for the fifty-billionth time
- Added fr_CA localisation
- Added fr_FR localisation
- Added pl_PL localisation
- Added a config option for the Spring Water Regeneration Effect
- Tweaked some achievements
- Made puddles dry up faster
- Changed the height of the Grassland
- Promised Land Tweaks
- Fixed Spring Water Regeneration Effect
- Fixed stair hardness
- Added the Silkglades biome
- Added a config option to generate pumpkins without faces
- Added a config option to disable lethal decoration
- Tweaked Biome Dictionary definitions
- Tweaked Origin Valley sky colour
- Added sub biomes for the enhanced vanilla biomes
- Tweaked the barley texture
- Fixed quicksand deepness
- Added the Overgrown Greens biome
- Prevented the Nether from being overriden in default worlds unless Add to Default is set to true
- Fixed a crash with saplings
- Added a config option to disable vanilla's exposed stone feature
- Tweaked the Shrubland height
- Tweaked the Tundra height
- Fixed terrain generator "stripes"
- Fixed a crash with disabling structures
- Fixed some bugs with sacrificing
- Fixed some bugs with pine tree growth requirements and slabs
Version 0.6.0 '03-08-13'
- Ripped out old integration for BC pumps
- Fixed a server crash bug with sacrifical altars
- Fixed a bug with the German localisation
- Added config options for certain recipes
- Tweaked the Bayou and Lush Swamp heights
- Overhauled the Field biome
- Added spires to the wasteland
- Added a Savanna Plateau sub-biome
- Made mountainous biomes less ugly
- Fixed noms again
- Fixed a crash between RC and GT
- Added a zh_CN localisation
- Split the config file into sub files
Version 0.5.9.2 '30-07-13'
- Added the Chromaflora
- Changed willow trees in the Promised Land to swampy ivy trees
- Re-added clouds to the Promised Land
- Fixed the eating bug in multiplayer, now zip your traps about it!
- Russian translation tweaks (by VeryBigBro)
- Updated Forestry Integration and API
- Corrected loftwood recipes
- Updated ore dictionary registration for logs
- Tweaked fir log/plank textures
Version 0.5.9 '23-07-13'
- Fixed eating food
- Fixed some biome heights, decreased the amount of trees in the Snowy Confierous Forest
- Tweaked some flower textures, changed some achievement icons
- Fixed height for mangroves
- Added support for falling leaves from Better Grass & Leaves
- Fixed a crash bug with non-living entities entering poison ivy
- Updated the better leaf textures
- Fixed a crash with saplings
- Added Long Grass
- Added config option for disabling oceans
- Fixed an issue with the shroom powder texture
- Tweaked the Garden biome
- Tweaked the Shield biome
Version 0.5.8 '21-07-13'
- Removed the crappy Amethyst Tinkers Construct tools
- Redid the grave
- Berries now have a new texture
- Changed localized name of Berries to Berry
- Adjusted how common Scythes are damaged
- Added wild carrots
- Added salads
- Changed the texture for fast willow leaves
- Tweaked the Garden biome
- Added beach variation config options
- Added Russian translations (courtesy of Sodiet)
- Fixed the sky colours config option
- Plants no longer generate in invalid positions (causing them to them pop off)
- Reeds are now cut down properly
- Fixed poison dart particles
- Tweaked the creative tab icon
- Puddles now dry up faster
- Added support for full 256 terrain generation
- Tweaked sub-biomes
- Improved some sapling textures
- Tweaked the Alps sub biome
- Fixed the mod logo
- Fixed fluid localizations
- Fixed bucket container items
- Poison ivy no longer poisons players wearing leather pants and boots
- Tweaked some biomes to allow them to generate above 128
Version 0.5.7 '09-07-13'
- Full update to 1.6.2
- Adjusted the crafting recipes for Scythes
- Added sub-biomes
- Canyon Ravine
- Meadow Forest
- Thick Ominous Woods
- Pasture Meadow
- Pasture Thin
- Shrubland Forest
- Timber Thin
- Added amethyst buckets specifically for picking up Spring Water
- Removed the Overgrown Beach
- Tweaked the Badlands
Version 0.5.6 '05-07-13'
- Added Treecapacitator compatibility
- Made the Ancient Staff and Dart Blower render in 3D like other tools
- Addeed the Altar Frame
- Added the Sacrificial Focus
- Added the Celestial Lens
- Added the Soul Manipulator
- Added Scythes
- Fixed alignment on mud/amethyst tool textures
- Added Globs to the API
- Fixed Glob spawning
- Fixed decoration on the Overgrown Beach
- Coniferous Forest colour changes
- Fixed a few logs being unable to be burned into charcoal
- Added option to disable the Nether changes
- Tweaked picking up apples from apple trees.
- Tweaked placing saplings.
- Added new stairs as a valid fuel
- Switched to a new localizations system (Not that anyone will use it)
- Fixed Thaumcraft Golem working on Apple Trees
- Added Minefactory Reloaded compatibility
- Changed the default Moss ID
- Added a warning when using the default world type without the config option enabled
- New version checking system
- Added Biome Finder achievements
- Added Tinkers construct integration for Amethyst tools
- Fixed an exploit with shears and berry bushes
- Added support for Better Grass and Leaves
- Tweaked the Fungi Forest trees
- Tweaked pyramid generation
- Made the BOP world type able to have biomes from other mods
- Added puddles that generate in the rain
- Fixed grass not dropping seeds
- Added graves
- Made horses spawn in several biomes
- Removed the Nourishment effect
- Removed BWG4 integration (Ted wanted to move it into BWG4 itself)
- You can no longer spawn in the hot springs or orchard
- Tweaked hot springs generation
- Tweaked apple tree generation
- Spring water can no longer be picked up by hand
- Algae is now biome coloured
- Tweaked the Badlands
- Tweaked the Mystic Grove
Version 0.5.5 '04-06-13'
- Fixed warnings on startup about Thaumcraft compatibility
- Fixed tundra boulder generation
- Added bamboo thatching > bamboo recipe
- Tweaked the Liquid Poison texture
- Custom dyes now work on sheep and dog collars
- Fixed a bug with connected textures
- Updated some temperatures and humidities for Forestry
- Added some new gems
- Changed the Ancient Staff recipe to use the new gems
- Fixed temperature/humidity values for the Hot Springs and Mountain biomes
- Added config options for which Nether biomes generate
- Added a config option for the custom loot
- Fixed a bug with bamboo not decaying
Version 0.5.4 '01-06-13'
- Added use animation to berry bushes
- Tweaked apple leaf textures
- Removed nether tags from overworld biomes
- Added several Nether Biomes
- Undergarden
- Corrupted Sands
- Phantasmagoric Inferno
- Boneyard
- Tweaked dandelion particles
- Apples and berries from leaves and bushes no longer spawn directly on the player
- Fixed a bug with trees in the Jade Cliffs
- Added ivy
- Nerfed apple tree growth
- Tweaked algae generation
- Tweaked algae texture
- Adjusted the Boreal Forest
- Added Bone Segments
- Added kelp
- Made amethyst tools and armour repairable
- Overhauled the Bog biome
- Renamed the Swampwoods to the Sludegpit and made it like the old Bog
- Adjusted the Deadlands and how Smoldering Grass generates
- Added the Timber biome
- Added Spring Water
- Added Liquid Poison
- Added the Nourishment potion effect (from Spring Wtaer)
- Added the Paralysis potion effect (from Poison Darts)
- Gave the deathbloom a particle effect
- Made the deathbloom apply the wither effect on contact
- Added pine trees
- Tweaked the Canyon
- Tweaked hard dirt texture
- Tweaked aloe texture
- Tweaked fir leaf texture
- Added pine, hellbark and jacaranda wood, leaves, planks, stairs and slabs
- Added the Hot Springs biome
- Added Jacaranda trees
- Disabled oil generation in the Promised Land
- Adjusted quicksand generation
- Allowed tiny cacti and thorns to live in any light level
- Reworked the Promised Lands portal
- Improved the Mangrove biome
- Added steam particles
- Tweaked grass bounding boxes
- Added beach variations
- Players now enter the overworld upon falling out of the Promised Lands
- The Ancient Staff now depletes on use
- Gave the Promised Lands a movement ratio of 16
- The Ancient Staff can now be used in the Promised Lands
Version 0.5.3 '17-05-13'
- Added reeds
- Added 2 new mushrooms (Portobello and Blue Milk Cap)
- Adjusted and fixed mod compatibility with Thermal Expansion
- Adjusted hitboxes for some flowers
- Added poison ivy
- Changed default distance between villages
- Tweaked the Fungi Forest
- Fixed High Grass generation in the Marsh
- Removed Barley from blacksmith chests
- Added white dandelions (they can be blown into the air too!)
- Improved Redwood Forest Biome and thin Redwood tree generation
- Replaced the old Ice Sheet Biome with a Polar biome
- Added random offset for foliage
- Renamed Yucca to Aloe
- Changed the moss texture
- Added the dart blower
- Fixed a few crafting recipes
- Added a new Promised Land generator
- Added Promised Land Sub-Biomes
- Adjusted which plants grow from bonemeal
- Made the Promised Lands use holy stone
- Adjusted Amethyst Ore texture
- Added hippy flower bands
- Added cloud blocks
- Redwood trees now require a 3x3 of redwood saplings
- Tweaked spider spawn weights in the Ominous Woods
- Added big tree variants of the red and orange trees to the Seasonal Forest
- Made the sky colour of the Promised Lands configurable
- Added Celestial Crystal
- Fixed a crash bug with mudballs
- Tweaked apple leaves
- Adjusted palm tree generation
- Added alternative blue, brown and green, black and white dyes
- Added glowshrooms
- Made Icy Hills hillier
- Gave barley a random offset
- Added sunflowers
- Added lilyflowers
- Adjusted some achievement descriptions
- Switched to using BWG4 Acacia Trees
- Tweaked the Savanna
- BOP woods now trigger the "Get Wood" achievement
- Added berry bushes
- Added sunflower seeds
- Overhauled the Grove Biome
- Overhauled the Field Biome
- Added the "Glob"
Version 0.5.2 '05-05-13'
- Added an API for other mod developers
- Added support for Biomes O Plenty woods in Thermal Expansion sawmills
- Significantly compressed the amount of Block IDs used, however breaks existing worlds
- Updated to the latest Forge
- Changed various things to use IShearable
- Changed default biome ids to be compatible with Mo Creatures
- Made a proper fix for achievements and made them enabled by default (The config option is still there though for those that want it)
- Added Better World Generation 4 support
- Made shears instantly destroy Biomes O Plenty leaves
- Adjusted high grass hitbox to cover both blocks
- Fixed an issue causing sound files to be created on the desktop
- Biomes O Plenty saplings now work in the Forestry fermenter
- Biomes O Plenty flowers can now be used with bees
- Gave the different types Autumn and Cherry Leaves their own names
- Added Biome Dictionary support
- Added seeds on destroyed Biomes O Plenty grasses
- Carrots and potatoes now have a chance (1%) to be dropped from sprouts
- Added a random drop of apples when destroying apple leaves
- Added flowers to plants created on bonemeal use
- Tweaked the recipe for bamboo thatching
- Bamboo now acts as sticks
- Hopefully fixed saplings once and for all
- Added hardcoded foliage colours
- Added configurable spawn distance between villages in the BOP world type
- Added more biomes for villages to spawn in
- Tweaked cattail generation
- Renamed the texture files to reflect the in-game names
- You can now have different textures for the heart of every log
- Added Thaumcraft compatibility
- Updated the regular BOP music disc file (courtesy of Forstride), may require deleting the old bopdisc.ogg to take effect
- Allowed Forestry beehives to spawn on Biomes O Plenty certain blocks
- Fixed registering biomes for world types - BOP biomes now accessible in Large Biomes World Type
- Fixed leaf decay
- Fixed config option for adding biomes to vanilla world types
- Fixed Red Rock
- Fixed BOP Items
- Fixed placing of Mangrove and Holy Saplings
- Finished the Thaumcraft aspects
- Changed the styling of Bamboo Forests to that of Forstrides liking
- Added Yucca flower to desert biomes
- Added High Cattails
- Seperated High Grass into two blocks
- Fire now burns infinitely on ashes
- Fixed willow colouring
- Adjust the Canyon Biome slightly
- Adjusted the Lush Desert biome slightly
Version 0.5.1 '17-04-2013'
- Fixed server crash with mudballs
- Fixed Forestry beehives spawning, as well as giving biomes appropriate temperatures
- Removed wrong recipe for mossy cobblestone
- Added bamboo saplings
- Bonemeal now creates the appropriate giant flowers when used on red and yellow flowers
- Changed default biome ids
- Fixed sapling bugs
Version 0.5.0 '09-04-2013'
- Desert sprouts and Dune Grass now require shears to be harvested
- Added alpha beaches to origin valley biome
- You can now throw Mudballs to deal 1/2 heart of damage
- Entities get the slowness potion effect when hit by mudballs
- Mud balls can now be fired from dispensers
- Resources now only install client-side
- Fixed bonemeal on Origin Saplings
- Bonemeal now only reacts to mangrove saplings when they are on sand
- Fixed bonemeal and holy grass dependancies on Holy and Magic saplings
- Changed the leaves blocks to use the IShearable interface
- Made the enderporter only work in the overworld
- Fixed the textures for logs to display according to their orientation
- Adding Leaves, Saplings, Stairs and Slabs to Ore Dictionary
- Fixed crash on right clicking on slabs with nothing in your hand
- Fixed trees not generating in the Mystic grove
- Fixed placing Moss, TreeMoss and Willow
- Fixed a bug with Promised Lands not using the ID from the config file
Version 0.4.9 '03-04-2013'
- Tools actually have the properties of the tools they are meant to be (they used to all think they are swords)
- Ore dictionary support for wood
- Added a temporary fix for the Ach Flower issue in the form of a config option for achievements
- Fancier message upon creation of The Promised Lands
- No more duplicate chat messages on creating the Promised Lands
- You can no longer create an infinite endstone supply from spamming Promised Lands portals
- Holy Tall grass no longer drops itself without using shears
- Fixed things wrongly having wooden footstep sounds
- Saplings now use the new bonemeal system added by Minecraft 1.5
- Bonemeal now creates Holy Tall Grass when used on Holy Grass
- Fixed slabs not stacking
- Fixed leaf decay
- Fixed tool effectiveness on various blocks
- Gave smoldering grass and ash their expected behaviours; burn on contact (smoldering grass) and slowness (ash)
- Holy and magic saplings will only grow on Holy Grass
- Holy Grass burns up into Soulsand in the Nether
- Fixed axe recipes
- Removed unnecessary recipes for hoes
Version 0.4.8 '31-03-2013'
- Fixed smoldering grass texture
- Fixed flower achievement?
- Fixed Giant red flower texture
Version 0.4.7 '30-03-2013'
- Updated to Minecraft 1.5.1

View File

@ -1,188 +1,126 @@
buildscript {
repositories {
mavenLocal()
maven { url = 'https://files.minecraftforge.net/maven' }
jcenter()
mavenCentral()
}
dependencies {
classpath group: 'net.minecraftforge.gradle', name: 'ForgeGradle', version: '3.+', changing: true
}
}
plugins {
id "com.matthewprenger.cursegradle" version "1.4.0"
}
apply plugin: 'net.minecraftforge.gradle'
apply plugin: 'eclipse'
apply plugin: 'idea'
apply plugin: 'maven'
repositories { mavenLocal() }
group = "com.github.glitchfiend.biomesoplenty"
archivesBaseName = "BiomesOPlenty"
def getGitHash = {
def stdout = new ByteArrayOutputStream()
exec {
commandLine 'git', 'rev-parse', '--short', 'HEAD'
standardOutput = stdout
}
return stdout.toString().trim()
}
version = "${minecraft_version}-${mod_version}.${System.getenv().BUILD_NUMBER}"
minecraft {
mappings channel: 'official', version: minecraft_version
accessTransformer = file('src/main/resources/META-INF/accesstransformer.cfg')
runs {
client = {
workingDirectory = project.file("run").canonicalPath
source sourceSets.main
}
server = {
workingDirectory = project.file("run").canonicalPath
source sourceSets.main
}
}
}
processResources {
from (sourceSets.main.resources.srcDirs) {
include 'META-INF/mods.toml'
expand 'version': project.version
}
}
jar {
classifier = 'universal'
}
dependencies {
minecraft 'net.minecraftforge:forge:' + minecraft_version + '-' + forge_version
}
task sourcesJar(type: Jar) {
from sourceSets.main.allJava
from (sourceSets.main.output) {
include 'LICENSE.txt'
}
classifier = 'sources'
}
task deobfJar(type: Jar) {
from sourceSets.main.output
classifier = 'deobf'
}
task apiJar(type: Jar) {
from(sourceSets.main.allJava) {
include 'biomesoplenty/api/**'
}
from (sourceSets.main.output) {
include 'LICENSE.txt'
include 'biomesoplenty/api/**'
}
classifier = 'api'
}
def changelog_file = rootProject.file("build/BiomesOPlenty-${version}-changelog.txt")
curseforge {
if (project.hasProperty('curseApiKey')) {
apiKey = project.getProperty('curseApiKey')
project {
id = '220318'
if (changelog_file.exists()) {
changelog = changelog_file
}
releaseType = 'beta'
mainArtifact(jar) {
displayName = "Biomes O' Plenty ${version}"
}
addArtifact sourcesJar
addArtifact deobfJar
addArtifact apiJar
}
}
}
artifacts {
if (changelog_file.exists()) {
archives changelog_file
}
archives jar
archives sourcesJar
archives deobfJar
archives apiJar
}
uploadArchives {
repositories {
mavenDeployer {
if (project.hasProperty('forgeMavenPassword')) {
repository(url: "https://files.minecraftforge.net/maven/manage/upload") {
authentication(userName: project.getProperty('forgeMavenUsername'), password: project.getProperty('forgeMavenPassword'))
}
}
else {
// local repo folder. Might wanna juset use gradle install if you wanans end it to maven-local
repository(url: 'file://localhost/' + project.file('repo').getAbsolutePath())
}
pom {
groupId = project.group
version = project.version
artifactId = project.archivesBaseName
project {
name project.archivesBaseName
packaging 'jar'
description 'Biomes O Plenty'
url 'https://github.com/Glitchfiend/BiomesOPlenty'
scm {
url 'https://github.com/Glitchfiend/BiomesOPlenty'
connection 'scm:git:git://github.com/Glitchfiend/BiomesOPlenty.git'
developerConnection 'scm:git:git@github.com:Glitchfiend/BiomesOPlenty.git'
}
issueManagement {
system 'github'
url 'https://github.com/Glitchfiend/BiomesOPlenty/issues'
}
licenses {
license {
name 'Creative Commons Attribution-NonCommercial-NoDerivs 4.0 International Public License'
url 'http://creativecommons.org/licenses/by-nc-nd/4.0/'
distribution 'repo'
}
}
developers {
developer {
id 'Adubbz'
name 'Adubbz'
roles { role 'developer' }
}
developer {
id 'Forstride'
name 'Forstride'
roles { role 'developer' }
}
}
}
}
}
}
}
buildscript {
repositories {
mavenCentral()
maven {
name = "ForgeFS"
url = "http://files.minecraftforge.net/maven"
}
}
dependencies {
classpath 'net.minecraftforge.gradle:ForgeGradle:1.0-SNAPSHOT'
}
}
apply plugin: "forge"
// define the properties file
ext.configFile = file "build.properties"
configFile.withReader {
// read config. it shall from now on be referenced as simply config or as project.config
def prop = new Properties()
prop.load(it)
project.ext.config = new ConfigSlurper().parse prop
}
repositories {
ivy {
name 'Forge FS legacy'
artifactPattern "http://files.minecraftforge.net/[module]/[module]-dev-[revision].[ext]"
}
}
dependencies {
compile name: 'WorldCore', version: "${config.minecraft_version}-${config.worldcore_version}", ext: 'jar'
compile name: 'ForgeMultipart', version: "${config.minecraft_version}-${config.fmp_version}", ext: 'jar'
}
group = "biomesoplenty"
version = config.mod_version
archivesBaseName = "BiomesOPlenty"
minecraft {
version = config.minecraft_version + "-" + config.forge_version // grab latest forge
assetDir = "run/assets"
replaceIn "BiomesOPlenty.java"
replace "1.42.666.42.1", '9.11.1.952'
}
// add some stuff to the version
version = "${config.minecraft_version}-${config.mod_version}.${System.getenv().BUILD_NUMBER}"
processResources {
// replace stuff in the files we want.
from(sourceSets.main.resources.srcDirs) {
include '**/*.info'
include '**/*.properties'
// replaces
expand ([
'mod_version': project.config.mod_version,
'minecraft_version': project.config.minecraft_version,
'build_number': project.config.build_number,
'worldcore_version': project.config.worldcore_version
])
}
// copy everything else, thats we didnt do before
from(sourceSets.main.resources.srcDirs) {
exclude '**/*.info'
exclude '**/*.properties'
}
}
// change the name of my obfuscated jar
jar {
manifest {
attributes 'FMLCorePlugin': 'biomesoplenty.asm.BOPFMLLoadingPlugin'
attributes 'FMLCorePluginContainsFMLMod': 'true'
}
appendix = 'universal'
}
import net.minecraftforge.gradle.tasks.dev.ChangelogTask
import net.minecraftforge.gradle.common.Constants
import net.minecraftforge.gradle.delayed.*
task createChangelog(type: ChangelogTask) {
def jobName = "${System.getenv().JOB_NAME}"
def buildNumber = "${System.getenv().BUILD_NUMBER}"
setServerRoot(new DelayedString(project, 'http://ci.jenkins.minecraftforge.net/'))
setJobName(new DelayedString(project, jobName.toString()));
setAuthName(new DelayedString(project, 'console_script'));
setAuthPassword(new DelayedString(project, 'dc6d48ca20a474beeac280a9a16a926e'));
setTargetBuild({buildNumber.toString()});
setOutput(new DelayedFile(project, 'build/libs/' + jobName + '-changelog-' + "${project.version}" + '.txt'));
}
tasks.build.dependsOn('createChangelog')
// add a source jar
task sourceJar(type: Jar) {
from sourceSets.main.allSource
appendix = 'src'
}
task apiJar(type: Jar) {
from(sourceSets.main.java)
{
include "biomesoplenty/api/*"
}
appendix = 'api'
}
// because the normal output has been made to be obfuscated
task deobfJar(type: Jar) {
from sourceSets.main.output
appendix = 'deobf'
}
artifacts {
archives sourceJar
archives deobfJar
archives apiJar
}

5
build.properties Normal file
View File

@ -0,0 +1,5 @@
minecraft_version=1.6.4
forge_version=9.11.1.964
mod_version=1.2.1
worldcore_version=1.1.0.17
fmp_version=1.0.0.182

9
capes.txt Normal file
View File

@ -0,0 +1,9 @@
Adubbz:https://raw.github.com/Glitchfiend/BiomesOPlenty/master/capes/dev_cape.png
futureamnet:https://raw.github.com/Glitchfiend/BiomesOPlenty/master/capes/dev_cape.png
TDWP_FTW:https://raw.github.com/Glitchfiend/BiomesOPlenty/master/capes/dev_cape.png
ted80:https://raw.github.com/Glitchfiend/BiomesOPlenty/master/capes/dev_cape.png
Vrrtep_aTun:https://raw.github.com/Glitchfiend/BiomesOPlenty/master/capes/donator_cape.png
Vexatos:https://raw.github.com/Glitchfiend/BiomesOPlenty/master/capes/helper_cape.png
Heptaforce:https://raw.github.com/Glitchfiend/BiomesOPlenty/master/capes/helper_cape.png

BIN
capes/dev_cape.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 547 B

BIN
capes/donator_cape.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 494 B

BIN
capes/helper_cape.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 655 B

View File

@ -1,12 +0,0 @@
# Sets default memory used for gradle commands. Can be overridden by user or command line properties.
# This is required to provide enough memory for the Minecraft decompilation process.
org.gradle.jvmargs=-Xmx3G
org.gradle.daemon=false
mod_version=13.1.0
minecraft_version=1.16.5
minecraft_version_toml=16
forge_version=36.1.0
forge_version_toml=36
forge_group=net.minecraftforge

BIN
gradle/wrapper/gradle-wrapper.jar vendored Normal file → Executable file

Binary file not shown.

3
gradle/wrapper/gradle-wrapper.properties vendored Normal file → Executable file
View File

@ -1,5 +1,6 @@
#Wed Oct 09 10:24:07 CDT 2013
distributionBase=GRADLE_USER_HOME
distributionPath=wrapper/dists
zipStoreBase=GRADLE_USER_HOME
zipStorePath=wrapper/dists
distributionUrl=https\://services.gradle.org/distributions/gradle-4.9-bin.zip
distributionUrl=http\://services.gradle.org/distributions/gradle-1.8-bin.zip

108
gradlew vendored
View File

@ -6,6 +6,47 @@
##
##############################################################################
# Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script.
DEFAULT_JVM_OPTS=""
APP_NAME="Gradle"
APP_BASE_NAME=`basename "$0"`
# Use the maximum available, or set MAX_FD != -1 to use that value.
MAX_FD="maximum"
warn ( ) {
echo "$*"
}
die ( ) {
echo
echo "$*"
echo
exit 1
}
# OS specific support (must be 'true' or 'false').
cygwin=false
msys=false
darwin=false
case "`uname`" in
CYGWIN* )
cygwin=true
;;
Darwin* )
darwin=true
;;
MINGW* )
msys=true
;;
esac
# For Cygwin, ensure paths are in UNIX format before anything is touched.
if $cygwin ; then
[ -n "$JAVA_HOME" ] && JAVA_HOME=`cygpath --unix "$JAVA_HOME"`
fi
# Attempt to set APP_HOME
# Resolve links: $0 may be a link
PRG="$0"
@ -20,49 +61,9 @@ while [ -h "$PRG" ] ; do
fi
done
SAVED="`pwd`"
cd "`dirname \"$PRG\"`/" >/dev/null
cd "`dirname \"$PRG\"`/" >&-
APP_HOME="`pwd -P`"
cd "$SAVED" >/dev/null
APP_NAME="Gradle"
APP_BASE_NAME=`basename "$0"`
# Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script.
DEFAULT_JVM_OPTS='"-Xmx64m" "-Xms64m"'
# Use the maximum available, or set MAX_FD != -1 to use that value.
MAX_FD="maximum"
warn () {
echo "$*"
}
die () {
echo
echo "$*"
echo
exit 1
}
# OS specific support (must be 'true' or 'false').
cygwin=false
msys=false
darwin=false
nonstop=false
case "`uname`" in
CYGWIN* )
cygwin=true
;;
Darwin* )
darwin=true
;;
MINGW* )
msys=true
;;
NONSTOP* )
nonstop=true
;;
esac
cd "$SAVED" >&-
CLASSPATH=$APP_HOME/gradle/wrapper/gradle-wrapper.jar
@ -89,7 +90,7 @@ location of your Java installation."
fi
# Increase the maximum file descriptors if we can.
if [ "$cygwin" = "false" -a "$darwin" = "false" -a "$nonstop" = "false" ] ; then
if [ "$cygwin" = "false" -a "$darwin" = "false" ] ; then
MAX_FD_LIMIT=`ulimit -H -n`
if [ $? -eq 0 ] ; then
if [ "$MAX_FD" = "maximum" -o "$MAX_FD" = "max" ] ; then
@ -113,7 +114,6 @@ fi
if $cygwin ; then
APP_HOME=`cygpath --path --mixed "$APP_HOME"`
CLASSPATH=`cygpath --path --mixed "$CLASSPATH"`
JAVACMD=`cygpath --unix "$JAVACMD"`
# We build the pattern for arguments to be converted via cygpath
ROOTDIRSRAW=`find -L / -maxdepth 1 -mindepth 1 -type d 2>/dev/null`
@ -154,19 +154,11 @@ if $cygwin ; then
esac
fi
# Escape application args
save () {
for i do printf %s\\n "$i" | sed "s/'/'\\\\''/g;1s/^/'/;\$s/\$/' \\\\/" ; done
echo " "
# Split up the JVM_OPTS And GRADLE_OPTS values into an array, following the shell quoting and substitution rules
function splitJvmOpts() {
JVM_OPTS=("$@")
}
APP_ARGS=$(save "$@")
eval splitJvmOpts $DEFAULT_JVM_OPTS $JAVA_OPTS $GRADLE_OPTS
JVM_OPTS[${#JVM_OPTS[*]}]="-Dorg.gradle.appname=$APP_BASE_NAME"
# Collect all arguments for the java command, following the shell quoting and substitution rules
eval set -- $DEFAULT_JVM_OPTS $JAVA_OPTS $GRADLE_OPTS "\"-Dorg.gradle.appname=$APP_BASE_NAME\"" -classpath "\"$CLASSPATH\"" org.gradle.wrapper.GradleWrapperMain "$APP_ARGS"
# by default we should be in the correct project dir, but when run from Finder on Mac, the cwd is wrong
if [ "$(uname)" = "Darwin" ] && [ "$HOME" = "$PWD" ]; then
cd "$(dirname "$0")"
fi
exec "$JAVACMD" "$@"
exec "$JAVACMD" "${JVM_OPTS[@]}" -classpath "$CLASSPATH" org.gradle.wrapper.GradleWrapperMain "$@"

90
gradlew.bat vendored
View File

@ -1,90 +0,0 @@
@if "%DEBUG%" == "" @echo off
@rem ##########################################################################
@rem
@rem Gradle startup script for Windows
@rem
@rem ##########################################################################
@rem Set local scope for the variables with windows NT shell
if "%OS%"=="Windows_NT" setlocal
@rem Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script.
set DEFAULT_JVM_OPTS=
set DIRNAME=%~dp0
if "%DIRNAME%" == "" set DIRNAME=.
set APP_BASE_NAME=%~n0
set APP_HOME=%DIRNAME%
@rem Find java.exe
if defined JAVA_HOME goto findJavaFromJavaHome
set JAVA_EXE=java.exe
%JAVA_EXE% -version >NUL 2>&1
if "%ERRORLEVEL%" == "0" goto init
echo.
echo ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH.
echo.
echo Please set the JAVA_HOME variable in your environment to match the
echo location of your Java installation.
goto fail
:findJavaFromJavaHome
set JAVA_HOME=%JAVA_HOME:"=%
set JAVA_EXE=%JAVA_HOME%/bin/java.exe
if exist "%JAVA_EXE%" goto init
echo.
echo ERROR: JAVA_HOME is set to an invalid directory: %JAVA_HOME%
echo.
echo Please set the JAVA_HOME variable in your environment to match the
echo location of your Java installation.
goto fail
:init
@rem Get command-line arguments, handling Windowz variants
if not "%OS%" == "Windows_NT" goto win9xME_args
if "%@eval[2+2]" == "4" goto 4NT_args
:win9xME_args
@rem Slurp the command line arguments.
set CMD_LINE_ARGS=
set _SKIP=2
:win9xME_args_slurp
if "x%~1" == "x" goto execute
set CMD_LINE_ARGS=%*
goto execute
:4NT_args
@rem Get arguments from the 4NT Shell from JP Software
set CMD_LINE_ARGS=%$
:execute
@rem Setup the command line
set CLASSPATH=%APP_HOME%\gradle\wrapper\gradle-wrapper.jar
@rem Execute Gradle
"%JAVA_EXE%" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% "-Dorg.gradle.appname=%APP_BASE_NAME%" -classpath "%CLASSPATH%" org.gradle.wrapper.GradleWrapperMain %CMD_LINE_ARGS%
:end
@rem End local scope for the variables with windows NT shell
if "%ERRORLEVEL%"=="0" goto mainEnd
:fail
rem Set variable GRADLE_EXIT_CONSOLE if you need the _script_ return code instead of
rem the _cmd.exe /c_ return code!
if not "" == "%GRADLE_EXIT_CONSOLE%" exit 1
exit /b 1
:mainEnd
if "%OS%"=="Windows_NT" endlocal
:omega

View File

@ -0,0 +1,12 @@
package forestry.api.apiculture;
import java.util.ArrayList;
import net.minecraft.item.ItemStack;
public class FlowerManager {
/**
* ItemStacks representing simple flower blocks. Meta-sensitive, processed by the basic {@link IFlowerProvider}.
*/
public static ArrayList<ItemStack> plainFlowers = new ArrayList<ItemStack>();
}

View File

@ -0,0 +1,34 @@
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;
}
}

View File

@ -0,0 +1,47 @@
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)
*/
public static ArrayList<Integer> aridBiomeIds = new ArrayList<Integer>();
/**
* Populated by Forestry with vanilla biomes. Add additional damp biomes here. (ex. jungle)
*/
public static ArrayList<Integer> dampBiomeIds = new ArrayList<Integer>();
/**
* Populated by Forestry with vanilla biomes. Add additional normal biomes here.
*/
public static ArrayList<Integer> normalBiomeIds = new ArrayList<Integer>();
public final String name;
private EnumHumidity(String name) {
this.name = name;
}
public String getName() {
return this.name;
}
public static ArrayList<Integer> getBiomeIds(EnumHumidity humidity) {
switch (humidity) {
case ARID:
return aridBiomeIds;
case DAMP:
return dampBiomeIds;
case NORMAL:
default:
return normalBiomeIds;
}
}
}

View File

@ -0,0 +1,79 @@
package forestry.api.core;
import java.util.ArrayList;
import net.minecraft.util.Icon;
import cpw.mods.fml.relauncher.Side;
import cpw.mods.fml.relauncher.SideOnly;
/**
* 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)
*/
public static ArrayList<Integer> icyBiomeIds = new ArrayList<Integer>();
/**
* Populated by Forestry with vanilla biomes. Add additional cold biomes here. (ex. taiga)
*/
public static ArrayList<Integer> coldBiomeIds = new ArrayList<Integer>();
/**
* Populated by Forestry with vanilla biomes. Add additional normal biomes here. (ex. forest, plains)
*/
public static ArrayList<Integer> normalBiomeIds = new ArrayList<Integer>();
/**
* Populated by Forestry with vanilla biomes. Add additional warm biomes here. (ex. jungle)
*/
public static ArrayList<Integer> warmBiomeIds = new ArrayList<Integer>();
/**
* Populated by Forestry with vanilla biomes. Add additional hot biomes here. (ex. desert)
*/
public static ArrayList<Integer> hotBiomeIds = new ArrayList<Integer>();
/**
* Populated by Forestry with vanilla biomes. Add additional hellish biomes here. (ex. nether)
*/
public static ArrayList<Integer> hellishBiomeIds = new ArrayList<Integer>();
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 Icon getIcon() {
return ForestryAPI.textureManager.getDefault(iconIndex);
}
public static ArrayList<Integer> 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;
}
}
}

View File

@ -0,0 +1,40 @@
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.
*/
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;
}

View File

@ -0,0 +1,15 @@
package forestry.api.core;
import java.util.ArrayList;
/**
* Used mostly by hives to determine whether they can spawn at a certain position. Rather limited and hackish.
*/
public class GlobalManager {
public static ArrayList<Integer> dirtBlockIds = new ArrayList<Integer>();
public static ArrayList<Integer> sandBlockIds = new ArrayList<Integer>();
public static ArrayList<Integer> leafBlockIds = new ArrayList<Integer>();
public static ArrayList<Integer> snowBlockIds = new ArrayList<Integer>();
}

View File

@ -0,0 +1,20 @@
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);
}

View File

@ -0,0 +1,36 @@
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);
}

View File

@ -0,0 +1,19 @@
package forestry.api.core;
import net.minecraft.client.renderer.texture.IconRegister;
import net.minecraft.util.Icon;
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)
Icon getIcon(short texUID);
@SideOnly(Side.CLIENT)
void registerIcons(IconRegister register);
}

View File

@ -0,0 +1,9 @@
package forestry.api.core;
import net.minecraft.nbt.NBTTagCompound;
public interface INBTTagable {
void readFromNBT(NBTTagCompound nbttagcompound);
void writeToNBT(NBTTagCompound nbttagcompound);
}

View File

@ -0,0 +1,32 @@
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();
}

View File

@ -0,0 +1,15 @@
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();
}

View File

@ -0,0 +1,15 @@
package forestry.api.core;
import net.minecraft.util.Icon;
import cpw.mods.fml.relauncher.Side;
import cpw.mods.fml.relauncher.SideOnly;
@SideOnly(Side.CLIENT)
public interface ITextureManager {
void registerIconProvider(IIconProvider provider);
Icon getIcon(short texUID);
Icon getDefault(String ident);
}

View File

@ -0,0 +1,58 @@
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();
}

View File

@ -0,0 +1,8 @@
package forestry.api.core;
/**
* Marks a tool as a scoop.
*/
public interface IToolScoop {
}

View File

@ -0,0 +1,36 @@
package forestry.api.core;
import net.minecraft.item.Item;
import net.minecraft.item.ItemStack;
import cpw.mods.fml.common.FMLLog;
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 obj = Class.forName(itemClass).getField(ident).get(null);
if (obj instanceof Item)
item = new ItemStack((Item) obj);
else if (obj instanceof ItemStack)
item = (ItemStack) obj;
} catch (Exception ex) {
FMLLog.warning("Could not retrieve Forestry item identified by: " + ident);
}
return item;
}
}

View File

@ -0,0 +1,49 @@
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 "";
}

View File

@ -0,0 +1,14 @@
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;
}

View File

@ -0,0 +1,30 @@
package forestry.api.fuels;
import net.minecraft.item.ItemStack;
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;
}
}

View File

@ -0,0 +1,26 @@
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;
}
}

View File

@ -0,0 +1,24 @@
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;
}
}

View File

@ -0,0 +1,32 @@
package forestry.api.fuels;
import java.util.HashMap;
import net.minecraft.item.ItemStack;
import net.minecraftforge.fluids.Fluid;
import net.minecraftforge.fluids.FluidStack;
public class FuelManager {
/**
* Add new fuels for the fermenter here (i.e. fertilizer). Will accept Items, ItemStacks and Strings (Ore Dictionary)
*/
public static HashMap<Object, FermenterFuel> fermenterFuel;
/**
* Add new resources for the moistener here (i.e. wheat)
*/
public static HashMap<Object, MoistenerFuel> moistenerResource;
/**
* Add new substrates for the rainmaker here
*/
public static HashMap<Object, RainSubstrate> rainSubstrate;
/**
* Add new fuels for EngineBronze (= biogas engine) here
*/
public static HashMap<Object, EngineBronzeFuel> bronzeEngineFuel;
/**
* Add new fuels for EngineCopper (= peat-fired engine) here
*/
public static HashMap<Object, EngineCopperFuel> copperEngineFuel;
// Generator fuel list in GeneratorFuel.class
}

View File

@ -0,0 +1,31 @@
package forestry.api.fuels;
import java.util.HashMap;
import net.minecraftforge.fluids.Fluid;
import net.minecraftforge.fluids.FluidStack;
public class GeneratorFuel {
public static HashMap<Integer, GeneratorFuel> fuels = new HashMap<Integer, GeneratorFuel>();
/**
* 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;
}
}

View File

@ -0,0 +1,29 @@
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;
}
}

View File

@ -0,0 +1,35 @@
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;
}
}

View File

@ -0,0 +1,34 @@
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);
}

View File

@ -0,0 +1,65 @@
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);
}

View File

@ -0,0 +1,74 @@
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<ItemStack, Integer> specifying the possible products and the chances of them resulting from centrifugation.
*/
public void addRecipe(int timePerItem, ItemStack resource, HashMap<ItemStack, Integer> 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);
}

View File

@ -0,0 +1,12 @@
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<Object[], Object[]> getRecipes();
}

View File

@ -0,0 +1,12 @@
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);
}

View File

@ -0,0 +1,48 @@
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.
*/
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.
*/
public void addRecipe(ItemStack resource, int fermentationValue, float modifier, FluidStack output);
}

View File

@ -0,0 +1,11 @@
package forestry.api.recipes;
import net.minecraft.item.ItemStack;
public interface IGenericCrate {
void setContained(ItemStack crate, ItemStack contained);
ItemStack getContained(ItemStack crate);
}

View File

@ -0,0 +1,28 @@
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);
}

View File

@ -0,0 +1,45 @@
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);
}

View File

@ -0,0 +1,29 @@
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);
}

View File

@ -0,0 +1,16 @@
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);
}

View File

@ -0,0 +1,44 @@
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<ICraftingProvider> 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;
}

View File

@ -0,0 +1,18 @@
package forestry.api.storage;
import net.minecraft.entity.player.EntityPlayer;
import net.minecraft.inventory.IInventory;
import net.minecraftforge.event.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;
}
}

View File

@ -0,0 +1,22 @@
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<ItemStack>[] backpackItems;
public static IBackpackInterface backpackInterface;
/**
* Only use this if you know what you are doing. Prefer backpackInterface.
*/
public static HashMap<String, IBackpackDefinition> definitions = new HashMap<String, IBackpackDefinition>();
}

View File

@ -0,0 +1,18 @@
package forestry.api.storage;
import net.minecraft.entity.player.EntityPlayer;
import net.minecraft.inventory.IInventory;
import net.minecraftforge.event.Cancelable;
/**
* Use @ForgeSubscribe 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);
}
}

View File

@ -0,0 +1,21 @@
package forestry.api.storage;
import net.minecraft.entity.player.EntityPlayer;
import net.minecraft.inventory.IInventory;
import net.minecraft.item.ItemStack;
import net.minecraftforge.event.Cancelable;
/**
* Use @ForgeSubscribe 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;
}
}

View File

@ -0,0 +1,5 @@
package forestry.api.storage;
public enum EnumBackpackType {
T1, T2
}

View File

@ -0,0 +1,54 @@
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<ItemStack> 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);
}

View File

@ -0,0 +1,19 @@
package forestry.api.storage;
import net.minecraft.item.Item;
public interface IBackpackInterface {
/**
* Adds a backpack with the given id, definition and type, returning the item.
*
* @param itemID
* Item id to use.
* @param definition
* Definition of backpack behaviour.
* @param type
* Type of backpack. (T1 or T2 (= Woven)
* @return Created backpack item.
*/
Item addBackpack(int itemID, IBackpackDefinition definition, EnumBackpackType type);
}

View File

@ -0,0 +1,498 @@
package powercrystals.minefactoryreloaded.api;
import powercrystals.minefactoryreloaded.api.rednet.IRedNetLogicCircuit;
import java.lang.reflect.Method;
import net.minecraft.item.ItemStack;
/**
* @author PowerCrystals
*
* Class used to register plants and other farming-related things with MFR. Will do nothing if MFR does not exist, but your mod should be set to load
* after MFR or things may not work properly.
*
* To avoid breaking the API, additional FactoryRegistry##s will appear on major MFR versions that contain API additions. On a Minecraft version change,
* these will be rolled back into this class.
*
*/
public class FactoryRegistry
{
/**
* Registers a plantable object with the Planter.
*
* @param plantable The thing to plant.
*/
public static void registerPlantable(IFactoryPlantable plantable)
{
try
{
Class<?> registry = Class.forName("powercrystals.minefactoryreloaded.MFRRegistry");
if(registry != null)
{
Method reg = registry.getMethod("registerPlantable", IFactoryPlantable.class);
reg.invoke(registry, plantable);
}
}
catch(Exception e)
{
e.printStackTrace();
}
}
/**
* Registers a harvestable block with the Harvester.
*
* @param harvestable The thing to harvest.
*/
public static void registerHarvestable(IFactoryHarvestable harvestable)
{
try
{
Class<?> registry = Class.forName("powercrystals.minefactoryreloaded.MFRRegistry");
if(registry != null)
{
Method reg = registry.getMethod("registerHarvestable", IFactoryHarvestable.class);
reg.invoke(registry, harvestable);
}
}
catch(Exception e)
{
e.printStackTrace();
}
}
/**
* Registers a fertilizable block with the Fertilizer.
*
* @param fertilizable The thing to fertilize.
*/
public static void registerFertilizable(IFactoryFertilizable fertilizable)
{
try
{
Class<?> registry = Class.forName("powercrystals.minefactoryreloaded.MFRRegistry");
if(registry != null)
{
Method reg = registry.getMethod("registerFertilizable", IFactoryFertilizable.class);
reg.invoke(registry, fertilizable);
}
}
catch(Exception e)
{
e.printStackTrace();
}
}
/**
* Registers a fertilizer item Fertilizer.
*
* @param fertilizable The thing to fertilize with.
*/
public static void registerFertilizer(IFactoryFertilizer fertilizer)
{
try
{
Class<?> registry = Class.forName("powercrystals.minefactoryreloaded.MFRRegistry");
if(registry != null)
{
Method reg = registry.getMethod("registerFertilizer", IFactoryFertilizer.class);
reg.invoke(registry, fertilizer);
}
}
catch(Exception e)
{
e.printStackTrace();
}
}
/**
* Registers a ranchable entity with the Rancher.
*
* @param ranchable The entity to ranch.
*/
public static void registerRanchable(IFactoryRanchable ranchable)
{
try
{
Class<?> registry = Class.forName("powercrystals.minefactoryreloaded.MFRRegistry");
if(registry != null)
{
Method reg = registry.getMethod("registerRanchable", IFactoryRanchable.class);
reg.invoke(registry, ranchable);
}
}
catch(Exception e)
{
e.printStackTrace();
}
}
/**
* Registers a grindable entity with the Grinder using the new grinder interface. This method will be renamed to the standard "registerGrindable"
* on MC 1.6.
*
* @param grindable The entity to grind.
*/
public static void registerGrindable(IFactoryGrindable grindable)
{
try
{
Class<?> registry = Class.forName("powercrystals.minefactoryreloaded.MFRRegistry");
if(registry != null)
{
Method reg = registry.getMethod("registerGrindable", IFactoryGrindable.class);
reg.invoke(registry, grindable);
}
}
catch(Exception e)
{
e.printStackTrace();
}
}
/**
* Registers a grindable entity with the Grinder using the new grinder interface. This method will be renamed to the standard "registerGrindable"
* on MC 1.6.
*
* @param grindable The entity to grind.
*/
public static void registerGrinderBlacklist(Class<?> ...ungrindables)
{
try
{
Class<?> registry = Class.forName("powercrystals.minefactoryreloaded.MFRRegistry");
if(registry != null)
{
Method reg = registry.getMethod("registerGrinderBlacklist", Class[].class);
reg.invoke(registry, (Object[])ungrindables);
}
}
catch(Exception e)
{
e.printStackTrace();
}
}
/**
* Registers a possible output with the sludge boiler.
*
* @param weight Likelihood that this item will be produced. Lower means rarer.
* @param drop The thing being produced by the sludge boiler.
*/
public static void registerSludgeDrop(int weight, ItemStack drop)
{
try
{
Class<?> registry = Class.forName("powercrystals.minefactoryreloaded.MFRRegistry");
if(registry != null)
{
Method reg = registry.getMethod("registerSludgeDrop", int.class, ItemStack.class);
reg.invoke(registry, weight, drop);
}
}
catch(Exception e)
{
e.printStackTrace();
}
}
/**
* Registers specific food to use in the Breeder (instead of wheat) for a given mob.
*
* @param entityToBreed Entity this food will be used with.
* @param food The item to use when breeding this entity.
*/
public static void registerBreederFood(Class<?> entityToBreed, ItemStack food)
{
try
{
Class<?> registry = Class.forName("powercrystals.minefactoryreloaded.MFRRegistry");
if(registry != null)
{
Method reg = registry.getMethod("registerBreederFood", Class.class, ItemStack.class);
reg.invoke(registry, entityToBreed, food);
}
}
catch(Exception e)
{
e.printStackTrace();
}
}
/**
* Bans an entity class from being collected by Safari Nets
*
* @param blacklistedEntity Class to blacklist
*/
public static void registerSafariNetBlacklist(Class<?> blacklistedEntity)
{
try
{
Class<?> registry = Class.forName("powercrystals.minefactoryreloaded.MFRRegistry");
if(registry != null)
{
Method reg = registry.getMethod("registerSafariNetBlacklist", Class.class);
reg.invoke(registry, blacklistedEntity);
}
}
catch(Exception e)
{
e.printStackTrace();
}
}
/**
* Registers a Safari Net handler to properly serialize a type of mob.
*
* @param handler The Safari Net handler.
*/
public static void registerSafariNetHandler(ISafariNetHandler handler)
{
try
{
Class<?> registry = Class.forName("powercrystals.minefactoryreloaded.MFRRegistry");
if(registry != null)
{
Method reg = registry.getMethod("registerSafariNetHandler", ISafariNetHandler.class);
reg.invoke(registry, handler);
}
}
catch(Exception e)
{
e.printStackTrace();
}
}
/**
* Registers a mob egg handler, which allows the Safari Net to properly change colors.
*
* @param handler The mob egg handler
*/
public static void registerMobEggHandler(IMobEggHandler handler)
{
try
{
Class<?> registry = Class.forName("powercrystals.minefactoryreloaded.MFRRegistry");
if(registry != null)
{
Method reg = registry.getMethod("registerMobEggHandler", IMobEggHandler.class);
reg.invoke(registry, handler);
}
}
catch(Exception e)
{
e.printStackTrace();
}
}
/**
* Allows Rubber Trees to spawn in the specified biome.
*
* @param biome The biome name.
*/
public static void registerRubberTreeBiome(String biome)
{
try
{
Class<?> registry = Class.forName("powercrystals.minefactoryreloaded.MFRRegistry");
if(registry != null)
{
Method reg = registry.getMethod("registerRubberTreeBiome", String.class);
reg.invoke(registry, biome);
}
}
catch(Exception e)
{
e.printStackTrace();
}
}
/**
* Registers an entity as a possible output from villager random safari nets. Note that the "id" field must be initialized
* (i.e. with Entity.addEntityID()) for it to work correctly.
*
* @param savedMob A serialized mob that will be unloaded by the safari net
* @param weight The weight of this mob in the random selection
*/
public static void registerVillagerTradeMob(IRandomMobProvider mobProvider)
{
try
{
Class<?> registry = Class.forName("powercrystals.minefactoryreloaded.MFRRegistry");
if(registry != null)
{
Method reg = registry.getMethod("registerVillagerTradeMob", IRandomMobProvider.class);
reg.invoke(registry, mobProvider);
}
}
catch(Exception e)
{
e.printStackTrace();
}
}
/**
* Registers a handler for drinking liquids with the straw.
*
* @param liquidId The block ID the handler handles.
* @param liquidDrinkHandler The drink handler instance.
*/
public static void registerLiquidDrinkHandler(int liquidId, ILiquidDrinkHandler liquidDrinkHandler)
{
try
{
Class<?> registry = Class.forName("powercrystals.minefactoryreloaded.MFRRegistry");
if(registry != null)
{
Method reg = registry.getMethod("registerLiquidDrinkHandler", int.class, ILiquidDrinkHandler.class);
reg.invoke(registry, liquidId, liquidDrinkHandler);
}
}
catch(Exception e)
{
e.printStackTrace();
}
}
/**
* Registers a possible output with the laser drill.
*
* @param weight Likelihood that this item will be produced. Lower means rarer.
* @param drop The thing being produced by the laser drill.
*/
public static void registerLaserOre(int weight, ItemStack drop)
{
try
{
Class<?> registry = Class.forName("powercrystals.minefactoryreloaded.MFRRegistry");
if(registry != null)
{
Method reg = registry.getMethod("registerLaserOre", int.class, ItemStack.class);
reg.invoke(registry, weight, drop);
}
}
catch(Exception e)
{
e.printStackTrace();
}
}
/**
* Registers a preferred ore with the laser drill. Focuses with the specified color will make the specified ore more likely.
* Used by MFR itself for vanilla: Black (Coal), Light Blue (Diamond), Lime (Emerald), Yellow (Gold), Brown (Iron), Blue (Lapis),
* Red (Redstone), and White (nether quartz).
*
* This will replace setLaserPreferredOre on MC 1.6.
*
* @param color The color that the preferred ore is being set for. White is 0.
* @param ore The ore that will be preferred by the drill when a focus with the specified color is present.
*/
public static void addLaserPreferredOre(int color, ItemStack ore)
{
try
{
Class<?> registry = Class.forName("powercrystals.minefactoryreloaded.MFRRegistry");
if(registry != null)
{
Method reg = registry.getMethod("addLaserPreferredOre", int.class, ItemStack.class);
reg.invoke(registry, color, ore);
}
}
catch(Exception e)
{
e.printStackTrace();
}
}
/**
* Registers a block ID as a fruit tree log. When the Fruit Picker sees this block on the ground, it will
* begin a search in tree mode for any fruit nearby.
*
* @param fruitLogBlockId The block ID to mark as a fruit tree log.
*/
public static void registerFruitLogBlockId(Integer fruitLogBlockId)
{
try
{
Class<?> registry = Class.forName("powercrystals.minefactoryreloaded.MFRRegistry");
if(registry != null)
{
Method reg = registry.getMethod("registerFruitLogBlockId", Integer.class);
reg.invoke(registry, fruitLogBlockId);
}
}
catch(Exception e)
{
e.printStackTrace();
}
}
/**
* Registers a fruit for the Fruit Picker.
*
* @param fruit The fruit to be picked.
*/
public static void registerFruit(IFactoryFruit fruit)
{
try
{
Class<?> registry = Class.forName("powercrystals.minefactoryreloaded.MFRRegistry");
if(registry != null)
{
Method reg = registry.getMethod("registerFruit", IFactoryFruit.class);
reg.invoke(registry, fruit);
}
}
catch(Exception e)
{
e.printStackTrace();
}
}
/**
* Registers an entity string as an invalid entry for the autospawner.
* See also: {@link net.minecraft.entity.EntityList}'s classToStringMapping and stringToClassMapping.
*
* @param entityString The entity string to blacklist.
*/
public static void registerAutoSpawnerBlacklist(String entityString)
{
try
{
Class<?> registry = Class.forName("powercrystals.minefactoryreloaded.MFRRegistry");
if(registry != null)
{
Method reg = registry.getMethod("registerAutoSpawnerBlacklist", String.class);
reg.invoke(registry, entityString);
}
}
catch(Exception e)
{
e.printStackTrace();
}
}
/**
* Registers logic circuit to be usable in the Programmable RedNet Controller.
*
* @param circuit The circuit to be registered.
*/
public static void registerRedNetLogicCircuit(IRedNetLogicCircuit circuit)
{
try
{
Class<?> registry = Class.forName("powercrystals.minefactoryreloaded.MFRRegistry");
if(registry != null)
{
Method reg = registry.getMethod("registerRedNetLogicCircuit", IRedNetLogicCircuit.class);
reg.invoke(registry, circuit);
}
}
catch(Exception e)
{
e.printStackTrace();
}
}
}

View File

@ -0,0 +1,23 @@
package powercrystals.minefactoryreloaded.api;
/**
* @author PowerCrystals
*
* Determines what kind of action a given fertilizer can perform. Your IFactoryFertilizable instances should check this before
* performing any action to maintain future compatibility.
*/
public enum FertilizerType
{
/**
* The fertilizer will fertilize grass.
*/
Grass,
/**
* The fertilizer will grow a plant.
*/
GrowPlant,
/**
* The fertilizer will grow magical crops.
*/
GrowMagicalCrop,
}

View File

@ -0,0 +1,34 @@
package powercrystals.minefactoryreloaded.api;
/**
* @author PowerCrystals
*
* Determines what algorithm the Harvester uses when it encounters this IFactoryHarvestable in the world.
*/
public enum HarvestType
{
/**
* Just break the single block - no special action needed. Carrots, flowers, etc.
*/
Normal,
/**
* Search for identical blocks above.
*/
Column,
/**
* Search for identical blocks above but leave this bottom one for the future. Cactus and sugarcane.
*/
LeaveBottom,
/**
* This block is the base of a tree and the harvester should enter tree-cutting mode.
*/
Tree,
/**
* This block is the base of the tree and the harvester should enter tree-cutting mode, but the tree grows upside-down.
*/
TreeFlipped,
/**
* This block is part of a tree as above, but leaves are cut before tree logs so that leaves do not decay more than necessary.
*/
TreeLeaf
}

View File

@ -0,0 +1,26 @@
package powercrystals.minefactoryreloaded.api;
import net.minecraft.item.ItemStack;
public interface IDeepStorageUnit
{
/**
* @return A populated ItemStack with stackSize for the full amount of materials in the DSU. May have a stackSize > getMaxStackSize().
*/
ItemStack getStoredItemType();
/**
* Sets the total amount of the item currently being stored, or zero if it wants to remove all items.
*/
void setStoredItemCount(int amount);
/**
* Sets the type of the stored item and initializes the number of stored items to amount. Will overwrite any existing stored items.
*/
void setStoredItemType(ItemStack type, int amount);
/**
* @return The maximum number of items the DSU can hold.
*/
int getMaxStoredCount();
}

View File

@ -0,0 +1,40 @@
package powercrystals.minefactoryreloaded.api;
import java.util.Random;
import net.minecraft.world.World;
/**
* @author PowerCrystals
*
* Defines a fertilizable block, and the process to fertilize it. You can assume that you will never have to check that block ID matches the one returned by
* getFertilizableBlockId().
*/
public interface IFactoryFertilizable
{
/**
* @return The block ID this instance is managing.
*/
public int getFertilizableBlockId();
/**
* @param world The world this block belongs to.
* @param x The X coordinate of this block.
* @param y The Y coordinate of this block.
* @param z The Z coordinate of this block.
* @param fertilizerType The kind of fertilizer being used.
* @return True if the block at (x,y,z) can be fertilized with the given type of fertilizer.
*/
public boolean canFertilizeBlock(World world, int x, int y, int z, FertilizerType fertilizerType);
/**
* @param world The world this block belongs to.
* @param rand A Random instance to use when fertilizing, if necessary.
* @param x The X coordinate of this block.
* @param y The Y coordinate of this block.
* @param z The Z coordinate of this block.
* @param fertilizerType The kind of fertilizer being used.
* @return True if fertilization was successful. If false, the Fertilizer will not consume a fertilizer item and will not drain power.
*/
public boolean fertilize(World world, Random rand, int x, int y, int z, FertilizerType fertilizerType);
}

View File

@ -0,0 +1,33 @@
package powercrystals.minefactoryreloaded.api;
import net.minecraft.item.ItemStack;
/**
* @author PowerCrystals
*
* Defines a fertilizer item for use in the Fertilizer.
*/
public interface IFactoryFertilizer
{
/**
* @return The ID of this fertilizer item.
*/
int getFertilizerId();
/**
* @return The metadata of this fertilizer item.
*/
int getFertilizerMeta();
/**
* @return The type of fertilizer this is.
*/
FertilizerType getFertilizerType();
/**
* Called when a fertilization is successful. If you set the ItemStack size to 0, it will be deleted by the fertilizer.
*
* @param fertilizer The ItemStack used to fertilize.
*/
void consume(ItemStack fertilizer);
}

View File

@ -0,0 +1,69 @@
package powercrystals.minefactoryreloaded.api;
import java.util.List;
import java.util.Random;
import net.minecraft.item.ItemStack;
import net.minecraft.world.World;
/**
* Defines a fruit entry for the Fruit Picker.
*
* @author powercrystals
*
*/
public interface IFactoryFruit
{
/**
* @return The block ID this fruit has in the world.
*/
public int getSourceBlockId();
/**
* Used to determine if this fruit can be picked (is it ripe yet, etc)
* @param world The world where the fruit is being picked
* @param x The x-coordinate of the fruit
* @param y The y-coordinate of the fruit
* @param z The z-coordinate of the fruit
* @return True if the fruit can be picked
*/
public boolean canBePicked(World world, int x, int y, int z);
/**
* Called by the Fruit Picker to determine what block to replace the picked block with. Only ID and meta/damage will be used.
* At the time this method is called, the fruit still exists. Do not pass an item ID as the return value.
* @param world The world where the fruit is being picked
* @param x The x-coordinate of the fruit
* @param y The y-coordinate of the fruit
* @param z The z-coordinate of the fruit
* @return The block to replace the fruit block with, or null for air.
*/
public ItemStack getReplacementBlock(World world, int x, int y, int z);
/**
* Called by the Fruit Picker before the fruit is picked.
* @param world The world where the fruit is being picked
* @param x The x-coordinate of the fruit
* @param y The y-coordinate of the fruit
* @param z The z-coordinate of the fruit
*/
public void prePick(World world, int x, int y, int z);
/**
* Called by the Fruit Picker to determine what drops to generate. At the time this method is called, the fruit still exists.
* @param world The world where the fruit is being picked
* @param x The x-coordinate of the fruit
* @param y The y-coordinate of the fruit
* @param z The z-coordinate of the fruit
*/
public List<ItemStack> getDrops(World world, Random rand, int x, int y, int z);
/**
* Called by the Fruit Picker after the fruit is picked.
* @param world The world where the fruit is being picked
* @param x The x-coordinate of the fruit
* @param y The y-coordinate of the fruit
* @param z The z-coordinate of the fruit
*/
public void postPick(World world, int x, int y, int z);
}

View File

@ -0,0 +1,36 @@
package powercrystals.minefactoryreloaded.api;
import java.util.List;
import java.util.Random;
import net.minecraft.entity.EntityLivingBase;
import net.minecraft.world.World;
/**
* @author PowerCrystals
*
* Defines a grindable entity for the Grinder.
*/
@SuppressWarnings("deprecation")
public interface IFactoryGrindable
{
/**
* @return The class that this grindable instance is handling. This must be a subtype of EntityLivingBase or the entity will never
* be noticed by the Grinder.
*/
public Class<?> getGrindableEntity();
/**
* @param world The world this entity is in.
* @param entity The entity instance being ground.
* @param random A Random instance.
* @return The drops generated when this entity is killed.
*/
public List<MobDrop> grind(World world, EntityLivingBase entity, Random random);
/**
* @param entity The entity instance being ground.
* @return Whether this entity has been fully processed or not.
*/
public boolean processEntity(EntityLivingBase entity);
}

View File

@ -0,0 +1,71 @@
package powercrystals.minefactoryreloaded.api;
import java.util.List;
import java.util.Map;
import java.util.Random;
import net.minecraft.item.ItemStack;
import net.minecraft.world.World;
/**
* @author PowerCrystals
*
* Defines a harvestable block for the Harvester.
*/
public interface IFactoryHarvestable
{
/**
* @return The block ID this harvestable instance is managing.
*/
public int getPlantId();
/**
* @return The type of harvest the Harvester should perform on this block.
*/
public HarvestType getHarvestType();
/**
* @return Whether or not the Harvester should break the block when harvesting. If false, no changes will be performed by the Harvester itself.
*/
public boolean breakBlock();
/**
* @param world The world this block is in.
* @param harvesterSettings The harvester's current settings. Do not modify these.
* @param x The X coordinate of the block being harvested.
* @param y The Y coordinate of the block being harvested.
* @param z The Z coordinate of the block being harvested.
* @return True if this block can be harvested.
*/
public boolean canBeHarvested(World world, Map<String, Boolean> harvesterSettings, int x, int y, int z);
/**
* @param world The world this block is in.
* @param rand A Random instance to use when generating drops.
* @param harvesterSettings The harvester's current settings. Do not modify these.
* @param x The X coordinate of the block being harvested.
* @param y The Y coordinate of the block being harvested.
* @param z The Z coordinate of the block being harvested.
* @return The drops generated by breaking this block. For a default implementation, calling Block.getBlockDropped() is usually sufficient.
*/
public List<ItemStack> getDrops(World world, Random rand, Map<String, Boolean> harvesterSettings, int x, int y, int z);
/**
* Called before the block is going to be harvested. Usually empty.
* @param world The world this block is in.
* @param x The X coordinate of the block being harvested.
* @param y The Y coordinate of the block being harvested.
* @param z The Z coordinate of the block being harvested.
*/
public void preHarvest(World world, int x, int y, int z);
/**
* Called after the block is going to be harvested. Used to re-till soil, for example.
* @param world The world this block is in.
* @param x The X coordinate of the block being harvested.
* @param y The Y coordinate of the block being harvested.
* @param z The Z coordinate of the block being harvested.
*/
public void postHarvest(World world, int x, int y, int z);
}

View File

@ -0,0 +1,67 @@
package powercrystals.minefactoryreloaded.api;
import net.minecraft.item.ItemStack;
import net.minecraft.world.World;
/**
* @author PowerCrystals
*
* Defines a plantable object for use in the Planter.
*/
public interface IFactoryPlantable
{
/**
* @return The block or item ID this plantable is managing.
*/
public int getSeedId();
/**
* @param world The world instance this block or item will be placed into.
* @param x The destination X coordinate.
* @param y The destination Y coordinate.
* @param z The destination Z coordinate.
* @param stack The stack being planted.
* @return The block ID that will be placed into the world.
*/
public int getPlantedBlockId(World world, int x, int y, int z, ItemStack stack);
/**
* @param world The world instance this block or item will be placed into.
* @param x The destination X coordinate.
* @param y The destination Y coordinate.
* @param z The destination Z coordinate.
* @param stack The stack being planted.
* @return The block metadata that will be placed into the world.
*/
public int getPlantedBlockMetadata(World world, int x, int y, int z, ItemStack stack);
/**
* @param world The world instance this block or item will be placed into.
* @param x The destination X coordinate.
* @param y The destination Y coordinate.
* @param z The destination Z coordinate.
* @param stack The stack being planted.
* @return True if this plantable can be placed at the provided coordinates.
*/
public boolean canBePlantedHere(World world, int x, int y, int z, ItemStack stack);
/**
* Called before planting is performed. Used to till soil, for example.
* @param world The world instance this block or item will be placed into.
* @param x The destination X coordinate.
* @param y The destination Y coordinate.
* @param z The destination Z coordinate.
* @param stack The stack being planted.
*/
public void prePlant(World world, int x, int y, int z, ItemStack stack);
/**
* Called after planting is performed. Usually empty.
* @param world The world instance this block or item will be placed into.
* @param x The destination X coordinate.
* @param y The destination Y coordinate.
* @param z The destination Z coordinate.
* @param stack The stack being planted.
*/
public void postPlant(World world, int x, int y, int z, ItemStack stack);
}

View File

@ -0,0 +1,28 @@
package powercrystals.minefactoryreloaded.api;
import java.util.List;
import net.minecraft.entity.EntityLivingBase;
import net.minecraft.inventory.IInventory;
import net.minecraft.world.World;
/**
* @author PowerCrystals
*
* Defines a ranchable entity for use in the Rancher.
*/
public interface IFactoryRanchable
{
/**
* @return The entity being ranched. Must be a subtype of EntityLivingBase.
*/
public Class<?> getRanchableEntity();
/**
* @param world The world this entity is in.
* @param entity The entity instance being ranched.
* @param rancher The rancher instance doing the ranching. Used to access the Rancher's inventory when milking cows, for example.
* @return A list of drops.
*/
public List<RanchedItem> ranch(World world, EntityLivingBase entity, IInventory rancher);
}

View File

@ -0,0 +1,8 @@
package powercrystals.minefactoryreloaded.api;
import net.minecraft.entity.player.EntityPlayer;
public interface ILiquidDrinkHandler
{
public void onDrink(EntityPlayer player);
}

View File

@ -0,0 +1,18 @@
package powercrystals.minefactoryreloaded.api;
import net.minecraft.entity.EntityEggInfo;
import net.minecraft.item.ItemStack;
/**
* @author PowerCrystals
*
* Defines a class that MFR will use to local egg info for a given mob. This is used to color the Safari Net based on the captured mob.
*/
public interface IMobEggHandler
{
/**
* @param safariNet The Safari Net that is looking for egg info.
* @return An EntityEggInfo, or null if this instance cannot handle this mob.
*/
public EntityEggInfo getEgg(ItemStack safariNet);
}

View File

@ -0,0 +1,12 @@
package powercrystals.minefactoryreloaded.api;
import net.minecraft.entity.Entity;
import net.minecraft.entity.player.EntityPlayer;
import net.minecraft.world.World;
public interface INeedleAmmo
{
public boolean onHitEntity(EntityPlayer owner, Entity hit, double distance);
public void onHitBlock(EntityPlayer owner, World world, int x, int y, int z, int side, double distance);
public float getSpread();
}

View File

@ -0,0 +1,11 @@
package powercrystals.minefactoryreloaded.api;
import java.util.List;
import net.minecraft.world.World;
public interface IRandomMobProvider
{
public List<RandomMob> getRandomMobs(World world);
}

View File

@ -0,0 +1,28 @@
package powercrystals.minefactoryreloaded.api;
import java.util.List;
import net.minecraft.entity.player.EntityPlayer;
import net.minecraft.item.ItemStack;
/**
* @author PowerCrystals
*
* Defines an object that can display information about a captured mob in a Safari net.
*/
public interface ISafariNetHandler
{
/**
* @return The class of mob that this handler applies to.
*/
public Class<?> validFor();
/**
* @param safariNetStack The Safari Net that is requesting information.
* @param player The player holding the Safari Net.
* @param infoList The current list of information strings. Add yours to this.
* @param advancedTooltips True if the advanced tooltips option is on.
*/
@SuppressWarnings("rawtypes")
public void addInformation(ItemStack safariNetStack, EntityPlayer player, List infoList, boolean advancedTooltips);
}

View File

@ -0,0 +1,31 @@
package powercrystals.minefactoryreloaded.api;
import net.minecraft.entity.EntityLivingBase;
import net.minecraft.item.ItemStack;
import net.minecraft.world.World;
/**
* @author PowerCrystals
*
* Defines a syringe for use in the Vet machine.
*/
public interface ISyringe
{
/**
* Called when the vet is deciding if it should use this syringe.
* @param world The world instance.
* @param entity The entity being injected.
* @param syringe The syringe ItemStack.
* @return True if the entity can be injected by this syringe.
*/
public boolean canInject(World world, EntityLivingBase entity, ItemStack syringe);
/**
* Called to perform an injection.
* @param world The world instance.
* @param entity The entity being injected.
* @param syringe The syringe ItemStack.
* @return True if injection was successful.
*/
public boolean inject(World world, EntityLivingBase entity, ItemStack syringe);
}

View File

@ -0,0 +1,9 @@
package powercrystals.minefactoryreloaded.api;
/**
* @author PowerCrystals
* Defines a tool that can rotate MFR machines. Implement on an Item class. Requires no additional work on your part.
*/
public interface IToolHammer
{
}

View File

@ -0,0 +1,16 @@
package powercrystals.minefactoryreloaded.api;
import net.minecraft.item.ItemStack;
/**
* @author PowerCrystals
*
* This interface is like IToolHammer, but is for items that change state on a per-stack basis. Implement this
* instead of IToolHammer - not both!
*
* This interface will replace IToolHammer in MC 1.6.
*/
public interface IToolHammerAdvanced
{
public boolean isActive(ItemStack stack);
}

View File

@ -0,0 +1,21 @@
package powercrystals.minefactoryreloaded.api;
import net.minecraft.item.ItemStack;
import net.minecraft.util.WeightedRandomItem;
public class MobDrop extends WeightedRandomItem
{
private ItemStack _stack;
public MobDrop(int weight, ItemStack stack)
{
super(weight);
_stack = stack;
}
public ItemStack getStack()
{
if(_stack == null) return null;
return _stack.copy();
}
}

View File

@ -0,0 +1,68 @@
package powercrystals.minefactoryreloaded.api;
import net.minecraft.block.Block;
import net.minecraft.item.Item;
import net.minecraft.item.ItemStack;
import net.minecraftforge.fluids.FluidStack;
/**
* @author skyboy026
*
* Defines an ItemStack or a FluidStack that is the result of an entity being ranched
*/
public final class RanchedItem {
private final ItemStack item;
private final FluidStack fluid;
public RanchedItem(Block item, int amount, int meta)
{
this(new ItemStack(item, amount, meta));
}
public RanchedItem(Block item, int amount)
{
this(new ItemStack(item, amount));
}
public RanchedItem(Block item)
{
this(new ItemStack(item));
}
public RanchedItem(Item item, int amount, int meta)
{
this(new ItemStack(item, amount, meta));
}
public RanchedItem(Item item, int amount)
{
this(new ItemStack(item, amount));
}
public RanchedItem(Item item)
{
this(new ItemStack(item));
}
public RanchedItem(ItemStack item)
{
this.item = item;
fluid = null;
}
public RanchedItem(FluidStack fluid)
{
this.fluid = fluid;
item = null;
}
public boolean hasFluid()
{
return item == null & fluid != null;
}
public Object getResult()
{
return item == null ? fluid : item;
}
}

View File

@ -0,0 +1,21 @@
package powercrystals.minefactoryreloaded.api;
import net.minecraft.entity.Entity;
import net.minecraft.util.WeightedRandomItem;
public class RandomMob extends WeightedRandomItem
{
private Entity _mob;
public RandomMob(Entity savedMob, int weight)
{
super(weight);
_mob = savedMob;
}
public Entity getMob()
{
if(_mob == null) return null;
return _mob;
}
}

View File

@ -0,0 +1,86 @@
package powercrystals.minefactoryreloaded.api.rednet;
import net.minecraft.world.World;
import net.minecraftforge.common.ForgeDirection;
/**
* Defines a Block that can connect to RedNet cables. This must be implemented on your Block class.
* Note that when you implement this, the RedNet network makes several assumptions about your code -
* primarily, it will not clamp values to 0 <= x <= 15. This means you must be able to accept any
* possible integer without crashing, even negatives. It will also assume that calling the onInput(s)Changed()
* methods are sufficient, and will not issue block updates. Finally, it will never call the vanilla redstone
* output methods in All mode, and will only query the methods contained in this interface in that case. In Single
* mode, it will call onInputChanged, and will check for strong power (or weak if in Plate mode) through the vanilla
* method calls.
*
* RedNet cables have their subnets indicated to the user by colored bands on the cable.
* The color of a given subnet is the same as the wool with metadata equal to the subnet number.
* For reference:
* 0:White, 1:Orange, 2:Magenta, 3:LightBlue, 4:Yellow, 5:Lime, 6:Pink, 7:Gray,
* 8:LightGray, 9:Cyan, 10:Purple, 11:Blue, 12:Brown, 13:Green, 14:Red, 15:Black
*/
public interface IConnectableRedNet
{
/**
* Returns the connection type of this Block. "All" types will cause getOutputValues() and onInputsChanged() to be used,
* whereas "Single" types will onInputChanged() to be called for input changes and the normal redstone power output methods
* to be called for output. If this value must be changed while the block is alive, it must perform a block update on any
* adjacent RedNet wires.
* @param world The world this block is in.
* @param x This block's X coordinate.
* @param y This block's Y coordinate.
* @param z This block's Z coordinate.
* @param side The side that connection information is required for.
* @return The connection type.
*/
public RedNetConnectionType getConnectionType(World world, int x, int y, int z, ForgeDirection side);
/**
* Returns the output values of this RedNet node. This array must be 16 elements long. Only called if your block is connected in "All" mode.
* @param world The world this block is in.
* @param x This block's X coordinate.
* @param y This block's Y coordinate.
* @param z This block's Z coordinate.
* @param side The side the output values are required for.
* @return The output values.
*/
public int[] getOutputValues(World world, int x, int y, int z, ForgeDirection side);
/**
* Returns the output value of this RedNet node for a given subnet. Only called if your block is connected in "All" mode.
* @param world The world this block is in.
* @param x This block's X coordinate.
* @param y This block's Y coordinate.
* @param z This block's Z coordinate.
* @param side The side the output value is required for.
* @param subnet The subnet to get the output value for (0-15).
* @return The output value.
*/
public int getOutputValue(World world, int x, int y, int z, ForgeDirection side, int subnet);
/**
* Called when the input values to this block change. Only called if your block is connected in "All" mode.
* Do not issue a network value update from inside this method call; it will be ignored. Issue your updates
* on the next tick.
* @param world The world this block is in.
* @param x This block's X coordinate.
* @param y This block's Y coordinate.
* @param z This block's Z coordinate.
* @param side The side the input values are being changed on.
* @param inputValues The new set of input values. This array will be 16 elements long.
*/
public void onInputsChanged(World world, int x, int y, int z, ForgeDirection side, int[] inputValues);
/**
* Called when the input value to this block changes. Only called if your block is connected in "Single" mode.
* Do not issue a network value update from inside this method call; it will be ignored. Issue your updates
* on the next tick.
* @param world The world this block is in.
* @param x This block's X coordinate.
* @param y This block's Y coordinate.
* @param z This block's Z coordinate.
* @param side The side the input values are being changed on.
* @param inputValue The new input value
*/
public void onInputChanged(World world, int x, int y, int z, ForgeDirection side, int inputValue);
}

View File

@ -0,0 +1,19 @@
package powercrystals.minefactoryreloaded.api.rednet;
import net.minecraft.nbt.NBTTagCompound;
public interface IRedNetLogicCircuit
{
public int getInputCount();
public int getOutputCount();
public int[] recalculateOutputValues(long worldTime, int[] inputValues);
public String getUnlocalizedName();
public String getInputPinLabel(int pin);
public String getOutputPinLabel(int pin);
public void readFromNBT(NBTTagCompound tag);
public void writeToNBT(NBTTagCompound tag);
}

View File

@ -0,0 +1,31 @@
package powercrystals.minefactoryreloaded.api.rednet;
import net.minecraft.world.World;
/**
*
* You should not implement this yourself. Instead, use this to look for cables to notify from your IConnectableRedNet as this does not
* require a block update. This will be implemented on the cable's Block class.
*
*/
public interface IRedNetNetworkContainer
{
/**
* Tells the network to recalculate all subnets.
* @param world The world this cable is in.
* @param x The x-coordinate of this cable.
* @param x The y-coordinate of this cable.
* @param x The z-coordinate of this cable.
*/
public void updateNetwork(World world, int x, int y, int z);
/**
* Tells the network to recalculate a specific subnet.
* @param world The world this cable is in.
* @param x The x-coordinate of this cable.
* @param x The y-coordinate of this cable.
* @param x The z-coordinate of this cable.
* @param subnet The subnet to recalculate.
*/
public void updateNetwork(World world, int x, int y, int z, int subnet);
}

View File

@ -0,0 +1,6 @@
package powercrystals.minefactoryreloaded.api.rednet;
public interface IRedNetNoConnection
{
}

View File

@ -0,0 +1,64 @@
package powercrystals.minefactoryreloaded.api.rednet;
import java.util.HashMap;
import java.util.Map;
/**
* Defines how RedNet cable connects to a block
*
* None: RedNet will never connect to this block (if this is all you want: use IRedNetNoConnection)
*
* CableSingle: Connections will use the cable renderer with a single band, best used for whole blocks
* PlateSingle: Connections will use the plate renderer with a single band, used for conveyers and rails
*
* CableAll: Connections permit access to all 16 bands
* PlateAll: Connections permit access to all 16 bands
*
* Forced connection modes are best used for decoration blocks: RedNet will not connect normally, but will if the user forces it
*
* ForcedCableSingle: Connections permit access to a single band only when the cable is in forced connection mode
* ForcedPlateSingle: Connections permit access to a single band only when the cable is in forced connection mode
*
* ForcedCableAll: Connections permit access to all 16 bands only when the cable is in forced connection mode
* ForcedPlateAll: Connections permit access to all 16 bands only when the cable is in forced connection mode
*/
public enum RedNetConnectionType
{
None, // 0
CableSingle, // 11
PlateSingle, // 13
CableAll, // 19
PlateAll, // 21
ForcedCableSingle, // 43
ForcedPlateSingle, // 45
ForcedCableAll, // 51
ForcedPlateAll; // 53
public final boolean isConnected = this.ordinal() != 0;
public final boolean isSingleSubnet = this.name().endsWith("Single");
public final boolean isAllSubnets = this.name().endsWith("All");
public final boolean isConnectionForced = this.name().startsWith("Forced");
public final boolean isPlate = this.name().contains("Plate");
public final boolean isCable = this.name().contains("Cable");
public final short flags = toFlags(isConnected, isCable, isPlate, isSingleSubnet, isAllSubnets, isConnectionForced);
public static final RedNetConnectionType fromFlags(short flags)
{
return connections.get(flags);
}
private static final short toFlags(boolean ...flags)
{
short ret = 0;
for (int i = flags.length; i --> 0;)
ret |= (flags[i] ? 1 : 0) << i;
return ret;
}
private static final Map<Short, RedNetConnectionType> connections = new HashMap<Short, RedNetConnectionType>();
static {
for (RedNetConnectionType type : RedNetConnectionType.values())
connections.put(type.flags, type);
}
}

View File

@ -0,0 +1,13 @@
package thaumcraft.api;
/**
* @author Azanor
* Items, armor and tools with this interface can receive the Repair enchantment.
* Repairs 1 point of durability every 10 seconds (2 for repair II)
*/
public interface IRepairable {
}

View File

@ -0,0 +1,17 @@
package thaumcraft.api;
import net.minecraft.entity.player.EntityPlayer;
import net.minecraft.item.ItemStack;
/**
* @author Azanor
* Items, armor and tools with this interface can receive the Repair enchantment.
* Repairs 1 point of durability every 10 seconds (2 for repair II)
*/
public interface IRepairableExtended extends IRepairable {
public boolean doRepair(ItemStack stack, EntityPlayer player, int enchantlevel);
}

View File

@ -0,0 +1,15 @@
package thaumcraft.api;
/**
* @author Azanor
* ItemArmor with this interface will grant a discount to the vis cost of actions the wearer performs with casting wands.
* The amount returned is the percentage by which the cost is discounted. There is a built-int max discount of 50%, but
* individual items really shouldn't have a discount more than 5%
*/
public interface IVisDiscounter {
int getVisDiscount();
}

View File

@ -0,0 +1,70 @@
package thaumcraft.api;
import net.minecraft.block.Block;
import net.minecraft.item.Item;
import net.minecraft.item.ItemStack;
import cpw.mods.fml.common.FMLLog;
/**
* @author Azanor
*
* This is used to gain access to the items in my mod.
* I only give some examples and it will probably still
* require a bit of work for you to get hold of everything you need.
*
*/
public class ItemApi {
public static ItemStack getItem(String itemString, int meta) {
ItemStack item = null;
try {
String itemClass = "thaumcraft.common.config.ConfigItems";
Object obj = Class.forName(itemClass).getField(itemString).get(null);
if (obj instanceof Item) {
item = new ItemStack((Item) obj,1,meta);
} else if (obj instanceof ItemStack) {
item = (ItemStack) obj;
}
} catch (Exception ex) {
FMLLog.warning("[Thaumcraft] Could not retrieve item identified by: " + itemString);
}
return item;
}
public static ItemStack getBlock(String itemString, int meta) {
ItemStack item = null;
try {
String itemClass = "thaumcraft.common.config.ConfigBlocks";
Object obj = Class.forName(itemClass).getField(itemString).get(null);
if (obj instanceof Block) {
item = new ItemStack((Block) obj,1,meta);
} else if (obj instanceof ItemStack) {
item = (ItemStack) obj;
}
} catch (Exception ex) {
FMLLog.warning("[Thaumcraft] Could not retrieve block identified by: " + itemString);
}
return item;
}
/**
*
* Some examples
*
* Casting Wands:
* itemWandCasting
*
* Resources:
* itemEssence, itemWispEssence, itemResource, itemShard, itemNugget,
* itemNuggetChicken, itemNuggetBeef, itemNuggetPork, itemTripleMeatTreat
*
* Research:
* itemResearchNotes, itemInkwell, itemThaumonomicon
*
*/
}

View File

@ -0,0 +1,381 @@
package thaumcraft.api;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import net.minecraft.entity.player.EntityPlayer;
import net.minecraft.item.EnumArmorMaterial;
import net.minecraft.item.EnumToolMaterial;
import net.minecraft.item.ItemStack;
import net.minecraft.nbt.NBTBase;
import net.minecraftforge.common.EnumHelper;
import net.minecraftforge.oredict.OreDictionary;
import thaumcraft.api.aspects.Aspect;
import thaumcraft.api.aspects.AspectList;
import thaumcraft.api.crafting.CrucibleRecipe;
import thaumcraft.api.crafting.InfusionRecipe;
import thaumcraft.api.crafting.ShapedArcaneRecipe;
import thaumcraft.api.crafting.ShapelessArcaneRecipe;
import thaumcraft.api.research.IScanEventHandler;
import thaumcraft.api.research.ResearchCategories;
import thaumcraft.api.research.ResearchCategoryList;
import thaumcraft.api.research.ResearchItem;
import thaumcraft.api.research.ResearchPage;
/**
* @author Azanor
*
*
* IMPORTANT: If you are adding your own aspects to items it is a good idea to do it AFTER Thaumcraft adds its aspects, otherwise odd things may happen.
*
*/
public class ThaumcraftApi {
//Materials
public static EnumToolMaterial toolMatThaumium = EnumHelper.addToolMaterial("THAUMIUM", 3, 400, 7F, 2, 22);
public static EnumToolMaterial toolMatElemental = EnumHelper.addToolMaterial("THAUMIUM_ELEMENTAL", 3, 1500, 10F, 3, 18);
public static EnumArmorMaterial armorMatThaumium = EnumHelper.addArmorMaterial("THAUMIUM", 25, new int[] { 2, 6, 5, 2 }, 25);
public static EnumArmorMaterial armorMatSpecial = EnumHelper.addArmorMaterial("SPECIAL", 25, new int[] { 1, 3, 2, 1 }, 25);
//Enchantment references
public static int enchantFrugal;
public static int enchantPotency;
public static int enchantWandFortune;
public static int enchantHaste;
public static int enchantRepair;
//Miscellaneous
/**
* Portable Hole Block-id Blacklist.
* Simply add the block-id's of blocks you don't want the portable hole to go through.
*/
public static ArrayList<Integer> portableHoleBlackList = new ArrayList<Integer>();
//RESEARCH/////////////////////////////////////////
// public static Document researchDoc = null;
// public static ArrayList<String> apiResearchFiles = new ArrayList<String>();
public static ArrayList<IScanEventHandler> scanEventhandlers = new ArrayList<IScanEventHandler>();
public static ArrayList<EntityTags> scanEntities = new ArrayList<EntityTags>();
public static class EntityTags {
public EntityTags(String entityName, NBTBase[] nbts, AspectList aspects) {
this.entityName = entityName;
this.nbts = nbts;
this.aspects = aspects;
}
public String entityName;
public NBTBase[] nbts;
public AspectList aspects;
}
/**
* not really working atm, so ignore it for now
* @param scanEventHandler
*/
public static void registerScanEventhandler(IScanEventHandler scanEventHandler) {
scanEventhandlers.add(scanEventHandler);
}
/**
* This is used to add aspects to entities which you can then scan using a thaumometer.
* Also used to calculate vis drops from mobs.
* @param entityName
* @param aspects
* @param nbt you can specify certain nbt keys and their values
* to differentiate between mobs. <br>For example the normal and wither skeleton:
* <br>ThaumcraftApi.registerEntityTag("Skeleton", (new AspectList()).add(Aspect.DEATH, 5));
* <br>ThaumcraftApi.registerEntityTag("Skeleton", (new AspectList()).add(Aspect.DEATH, 8), new NBTTagByte("SkeletonType",(byte) 1));
*/
public static void registerEntityTag(String entityName, AspectList aspects, NBTBase... nbt ) {
scanEntities.add(new EntityTags(entityName,nbt,aspects));
}
//RECIPES/////////////////////////////////////////
private static ArrayList craftingRecipes = new ArrayList();
private static HashMap<List,ItemStack> smeltingBonus = new HashMap<List,ItemStack>();
private static ArrayList<List> smeltingBonusExlusion = new ArrayList<List>();
/**
* This method is used to determine what bonus items are generated when the infernal furnace smelts items
* @param in The result (not input) of the smelting operation. e.g. new ItemStack(ingotGold)
* @param out The bonus item that can be produced from the smelting operation e.g. new ItemStack(nuggetGold,0,0).
* Stacksize should be 0 unless you want to guarantee that at least 1 item is always produced.
*/
public static void addSmeltingBonus(ItemStack in, ItemStack out) {
smeltingBonus.put(
Arrays.asList(in.itemID,in.getItemDamage()),
new ItemStack(out.itemID,0,out.getItemDamage()));
}
/**
* Returns the bonus item produced from a smelting operation in the infernal furnace
* @param in The result of the smelting operation. e.g. new ItemStack(ingotGold)
* @return the The bonus item that can be produced
*/
public static ItemStack getSmeltingBonus(ItemStack in) {
return smeltingBonus.get(Arrays.asList(in.itemID,in.getItemDamage()));
}
/**
* Excludes specific items from producing bonus items when they are smelted in the infernal furnace, even
* if their smelt result would normally produce a bonus item.
* @param in The item to be smelted that should never produce a bonus item (e.g. the various macerated dusts form IC2)
* Even though they produce gold, iron, etc. ingots, they should NOT produce bonus nuggets as well.
*/
public static void addSmeltingBonusExclusion(ItemStack in) {
smeltingBonusExlusion.add(Arrays.asList(in.itemID,in.getItemDamage()));
}
/**
* Sees if an item is allowed to produce bonus items when smelted in the infernal furnace
* @param in The item you wish to check
* @return true or false
*/
public static boolean isSmeltingBonusExluded(ItemStack in) {
return smeltingBonusExlusion.contains(Arrays.asList(in.itemID,in.getItemDamage()));
}
public static List getCraftingRecipes() {
return craftingRecipes;
}
/**
* @param research the research key required for this recipe to work. Leave blank if it will work without research
* @param result the recipe output
* @param aspects the vis cost per aspect.
* @param recipe The recipe. Format is exactly the same as vanilla recipes. Input itemstacks are NBT sensitive.
*/
public static ShapedArcaneRecipe addArcaneCraftingRecipe(String research, ItemStack result, AspectList aspects, Object ... recipe)
{
ShapedArcaneRecipe r= new ShapedArcaneRecipe(research, result, aspects, recipe);
craftingRecipes.add(r);
return r;
}
/**
* @param research the research key required for this recipe to work. Leave blank if it will work without research
* @param result the recipe output
* @param aspects the vis cost per aspect
* @param recipe The recipe. Format is exactly the same as vanilla shapeless recipes. Input itemstacks are NBT sensitive.
*/
public static ShapelessArcaneRecipe addShapelessArcaneCraftingRecipe(String research, ItemStack result, AspectList aspects, Object ... recipe)
{
ShapelessArcaneRecipe r = new ShapelessArcaneRecipe(research, result, aspects, recipe);
craftingRecipes.add(r);
return r;
}
/**
* @param research the research key required for this recipe to work. Leave blank if it will work without research
* @param result the recipe output. It can either be an itemstack or an nbt compound tag that will be added to the central item
* @param instability a number that represents the N in 1000 chance for the infusion altar to spawn an
* instability effect each second while the crafting is in progress
* @param aspects the essentia cost per aspect.
* @param aspects input the central item to be infused
* @param recipe An array of items required to craft this. Input itemstacks are NBT sensitive.
* Infusion crafting components are automatically "fuzzy" and the oredict will be checked for possible matches.
*
*/
public static InfusionRecipe addInfusionCraftingRecipe(String research, Object result, int instability, AspectList aspects, ItemStack input,ItemStack[] recipe)
{
if (!(result instanceof ItemStack || result instanceof NBTBase)) return null;
InfusionRecipe r= new InfusionRecipe(research, result, instability, aspects, input, recipe);
craftingRecipes.add(r);
return r;
}
/**
* @param stack the recipe result
* @return the recipe
*/
public static InfusionRecipe getInfusionRecipe(ItemStack res) {
for (Object r:getCraftingRecipes()) {
if (r instanceof InfusionRecipe) {
if (((InfusionRecipe)r).recipeOutput instanceof ItemStack) {
if (((ItemStack) ((InfusionRecipe)r).recipeOutput).isItemEqual(res))
return (InfusionRecipe)r;
}
}
}
return null;
}
/**
* @param key the research key required for this recipe to work.
* @param result the output result
* @param cost the vis cost
* @param tags the aspects required to craft this
*/
public static CrucibleRecipe addCrucibleRecipe(String key, ItemStack result, Object catalyst, AspectList tags) {
CrucibleRecipe rc = new CrucibleRecipe(key, result, catalyst, tags);
getCraftingRecipes().add(rc);
return rc;
}
/**
* @param stack the recipe result
* @return the recipe
*/
public static CrucibleRecipe getCrucibleRecipe(ItemStack stack) {
for (Object r:getCraftingRecipes()) {
if (r instanceof CrucibleRecipe) {
if (((CrucibleRecipe)r).recipeOutput.isItemEqual(stack))
return (CrucibleRecipe)r;
}
}
return null;
}
/**
* Used by the thaumonomicon drilldown feature.
* @param stack the item
* @return the thaumcraft recipe key that produces that item.
*/
private static HashMap<int[],Object[]> keyCache = new HashMap<int[],Object[]>();
public static Object[] getCraftingRecipeKey(EntityPlayer player, ItemStack stack) {
int[] key = new int[] {stack.itemID,stack.getItemDamage()};
if (keyCache.containsKey(key)) {
if (keyCache.get(key)==null) return null;
if (ThaumcraftApiHelper.isResearchComplete(player.username, (String)(keyCache.get(key))[0]))
return keyCache.get(key);
else
return null;
}
for (ResearchCategoryList rcl:ResearchCategories.researchCategories.values()) {
for (ResearchItem ri:rcl.research.values()) {
if (ri.getPages()==null) continue;
for (int a=0;a<ri.getPages().length;a++) {
ResearchPage page = ri.getPages()[a];
if (page.recipeOutput!=null && stack !=null && page.recipeOutput.isItemEqual(stack)) {
keyCache.put(key,new Object[] {ri.key,a});
if (ThaumcraftApiHelper.isResearchComplete(player.username, ri.key))
return new Object[] {ri.key,a};
else
return null;
}
}
}
}
keyCache.put(key,null);
return null;
}
//ASPECTS////////////////////////////////////////
public static Map<List,AspectList> objectTags = new HashMap<List,AspectList>();
/**
* Checks to see if the passed item/block already has aspects associated with it.
* @param id
* @param meta
* @return
*/
public static boolean exists(int id, int meta) {
AspectList tmp = ThaumcraftApi.objectTags.get(Arrays.asList(id,meta));
if (tmp==null) {
tmp = ThaumcraftApi.objectTags.get(Arrays.asList(id,-1));
if (meta==-1 && tmp==null) {
int index=0;
do {
tmp = ThaumcraftApi.objectTags.get(Arrays.asList(id,index));
index++;
} while (index<16 && tmp==null);
}
if (tmp==null) return false;
}
return true;
}
/**
* Used to assign apsects to the given item/block. Here is an example of the declaration for cobblestone:<p>
* <i>ThaumcraftApi.registerObjectTag(Block.cobblestone.blockID, -1, (new ObjectTags()).add(EnumTag.ROCK, 1).add(EnumTag.DESTRUCTION, 1));</i>
* @param id
* @param meta pass -1 if all damage values of this item/block should have the same aspects
* @param aspects A ObjectTags object of the associated aspects
*/
public static void registerObjectTag(int id, int meta, AspectList aspects) {
objectTags.put(Arrays.asList(id,meta), aspects);
}
/**
* Used to assign apsects to the given item/block. Here is an example of the declaration for cobblestone:<p>
* <i>ThaumcraftApi.registerObjectTag(Block.cobblestone.blockID, new int[]{0,1}, (new ObjectTags()).add(EnumTag.ROCK, 1).add(EnumTag.DESTRUCTION, 1));</i>
* @param id
* @param meta A range of meta values if you wish to lump several item meta's together as being the "same" item (i.e. stair orientations)
* @param aspects A ObjectTags object of the associated aspects
*/
public static void registerObjectTag(int id, int[] meta, AspectList aspects) {
objectTags.put(Arrays.asList(id,meta), aspects);
}
/**
* Used to assign apsects to the given ore dictionary item.
* @param oreDict the ore dictionary name
* @param aspects A ObjectTags object of the associated aspects
*/
public static void registerObjectTag(String oreDict, AspectList aspects) {
ArrayList<ItemStack> ores = OreDictionary.getOres(oreDict);
if (ores!=null && ores.size()>0) {
for (ItemStack ore:ores) {
int d = ore.getItemDamage();
if (d==OreDictionary.WILDCARD_VALUE) d = -1;
objectTags.put(Arrays.asList(ore.itemID, d), aspects);
}
}
}
/**
* Used to assign aspects to the given item/block.
* Attempts to automatically generate aspect tags by checking registered recipes.
* Here is an example of the declaration for pistons:<p>
* <i>ThaumcraftApi.registerComplexObjectTag(Block.pistonBase.blockID, 0, (new ObjectTags()).add(EnumTag.MECHANISM, 2).add(EnumTag.MOTION, 4));</i>
* @param id
* @param meta pass -1 if all damage values of this item/block should have the same aspects
* @param aspects A ObjectTags object of the associated aspects
*/
public static void registerComplexObjectTag(int id, int meta, AspectList aspects ) {
if (!exists(id,meta)) {
AspectList tmp = ThaumcraftApiHelper.generateTags(id, meta);
if (tmp != null && tmp.size()>0) {
for(Aspect tag:tmp.getAspects()) {
aspects.add(tag, tmp.getAmount(tag));
}
}
registerObjectTag(id,meta,aspects);
} else {
AspectList tmp = ThaumcraftApiHelper.getObjectAspects(new ItemStack(id,1,meta));
for(Aspect tag:aspects.getAspects()) {
tmp.merge(tag, tmp.getAmount(tag));
}
registerObjectTag(id,meta,tmp);
}
}
//CROPS //////////////////////////////////////////////////////////////////////////////////////////
/**
* To define mod crops you need to use FMLInterModComms in your @Mod.Init method.
* There are two 'types' of crops you can add. Standard crops and clickable crops.
*
* Standard crops work like normal vanilla crops - they grow until a certain metadata
* value is reached and you harvest them by destroying the block and collecting the blocks.
* You need to create and ItemStack that tells the golem what block id and metadata represents
* the crop when fully grown.
* Example for vanilla wheat:
* FMLInterModComms.sendMessage("Thaumcraft", "harvestStandardCrop", new ItemStack(Block.crops,1,7));
*
* Clickable crops are crops that you right click to gather their bounty instead of destroying them.
* As for standard crops, you need to create and ItemStack that tells the golem what block id
* and metadata represents the crop when fully grown. The golem will trigger the blocks onBlockActivated method.
* Example (this will technically do nothing since clicking wheat does nothing, but you get the idea):
* FMLInterModComms.sendMessage("Thaumcraft", "harvestClickableCrop", new ItemStack(Block.crops,1,7));
*/
}

View File

@ -0,0 +1,137 @@
package thaumcraft.api;
import java.lang.reflect.Method;
import net.minecraft.item.ItemStack;
import net.minecraftforge.oredict.OreDictionary;
import thaumcraft.api.aspects.Aspect;
import thaumcraft.api.aspects.AspectList;
import cpw.mods.fml.common.FMLLog;
public class ThaumcraftApiHelper {
public static AspectList cullTags(AspectList temp) {
AspectList temp2 = new AspectList();
for (Aspect tag:temp.getAspects()) {
if (tag!=null)
temp2.add(tag, temp.getAmount(tag));
}
while (temp2!=null && temp2.size()>10) {
Aspect lowest = null;
int low = Integer.MAX_VALUE;
for (Aspect tag:temp2.getAspects()) {
if (tag==null) continue;
if (temp2.getAmount(tag)<low) {
low = temp2.getAmount(tag);
lowest = tag;
}
}
temp2.aspects.remove(lowest);
}
return temp2;
}
public static boolean areItemsEqual(ItemStack s1,ItemStack s2)
{
if (s1.isItemStackDamageable() && s2.isItemStackDamageable())
{
return s1.itemID == s2.itemID;
} else
return s1.itemID == s2.itemID && s1.getItemDamage() == s2.getItemDamage();
}
static Method isResearchComplete;
static Method getObjectTags;
static Method getBonusTags;
static Method generateTags;
public static boolean isResearchComplete(String username, String researchkey) {
boolean ot = false;
try {
if(isResearchComplete == null) {
Class fake = Class.forName("thaumcraft.common.lib.research.ResearchManager");
isResearchComplete = fake.getMethod("isResearchComplete", String.class, String.class);
}
ot = (Boolean) isResearchComplete.invoke(null, username, researchkey);
} catch(Exception ex) {
FMLLog.warning("[Thaumcraft API] Could not invoke thaumcraft.common.lib.research.ResearchManager method isResearchComplete");
}
return ot;
}
public static ItemStack getStackInRowAndColumn(Object instance, int row, int column) {
ItemStack ot = null;
try {
Class fake = Class.forName("thaumcraft.common.tiles.TileMagicWorkbench");
Method getStackInRowAndColumn = fake.getMethod("getStackInRowAndColumn", int.class, int.class);
ot = (ItemStack) getStackInRowAndColumn.invoke(instance, row, column);
} catch(Exception ex) {
FMLLog.warning("[Thaumcraft API] Could not invoke thaumcraft.common.tiles.TileMagicWorkbench method getStackInRowAndColumn");
}
return ot;
}
public static AspectList getObjectAspects(ItemStack is) {
AspectList ot = null;
try {
if(getObjectTags == null) {
Class fake = Class.forName("thaumcraft.common.lib.ThaumcraftCraftingManager");
getObjectTags = fake.getMethod("getObjectTags", ItemStack.class);
}
ot = (AspectList) getObjectTags.invoke(null, is);
} catch(Exception ex) {
FMLLog.warning("[Thaumcraft API] Could not invoke thaumcraft.common.lib.ThaumcraftCraftingManager method getObjectTags");
}
return ot;
}
public static AspectList getBonusObjectTags(ItemStack is,AspectList ot) {
try {
if(getBonusTags == null) {
Class fake = Class.forName("thaumcraft.common.lib.ThaumcraftCraftingManager");
getBonusTags = fake.getMethod("getBonusTags", ItemStack.class, AspectList.class);
}
ot = (AspectList) getBonusTags.invoke(null, is, ot);
} catch(Exception ex) {
FMLLog.warning("[Thaumcraft API] Could not invoke thaumcraft.common.lib.ThaumcraftCraftingManager method getBonusTags");
}
return ot;
}
public static AspectList generateTags(int id, int meta) {
try {
if(generateTags == null) {
Class fake = Class.forName("thaumcraft.common.lib.ThaumcraftCraftingManager");
generateTags = fake.getMethod("generateTags", int.class, int.class);
}
return (AspectList) generateTags.invoke(null, id, meta);
} catch(Exception ex) {
FMLLog.warning("[Thaumcraft API] Could not invoke thaumcraft.common.lib.ThaumcraftCraftingManager method generateTags");
}
return null;
}
public static boolean containsMatch(boolean strict, ItemStack[] inputs, ItemStack... targets)
{
for (ItemStack input : inputs)
{
for (ItemStack target : targets)
{
if (itemMatches(target, input, strict))
{
return true;
}
}
}
return false;
}
public static boolean itemMatches(ItemStack target, ItemStack input, boolean strict)
{
if (input == null && target != null || input != null && target == null)
{
return false;
}
return (target.itemID == input.itemID && ((target.getItemDamage() == OreDictionary.WILDCARD_VALUE && !strict) || target.getItemDamage() == input.getItemDamage()));
}
}

View File

@ -0,0 +1,221 @@
package thaumcraft.api.aspects;
import java.util.ArrayList;
import java.util.Collection;
import java.util.LinkedHashMap;
import net.minecraft.util.ResourceLocation;
import net.minecraft.util.StatCollector;
import org.apache.commons.lang3.text.WordUtils;
public class Aspect {
String tag;
Aspect[] components;
int color;
private String chatcolor;
ResourceLocation image;
int blend;
/**
* Use this constructor to register your own aspects.
* @param tag the key that will be used to reference this aspect, as well as its latin display name
* @param color color to display the tag in
* @param components the aspects this one is formed from
* @param image ResourceLocation pointing to a 32x32 icon of the aspect
* @param blend GL11 blendmode (1 or 771). Used for rendering nodes. Default is 1
*/
public Aspect(String tag, int color, Aspect[] components, ResourceLocation image, int blend) {
if (aspects.containsKey(tag)) throw new IllegalArgumentException(tag+" already registered!");
this.tag = tag;
this.components = components;
this.color = color;
this.image = image;
this.blend = blend;
aspects.put(tag, this);
}
/**
* Shortcut constructor I use for the default aspects - you shouldn't be using this.
*/
public Aspect(String tag, int color, Aspect[] components) {
this(tag,color,components,new ResourceLocation("thaumcraft","textures/aspects/"+tag.toLowerCase()+".png"),1);
}
/**
* Shortcut constructor I use for the default aspects - you shouldn't be using this.
*/
public Aspect(String tag, int color, Aspect[] components, int blend) {
this(tag,color,components,new ResourceLocation("thaumcraft","textures/aspects/"+tag.toLowerCase()+".png"),blend);
}
/**
* Shortcut constructor I use for the primal aspects -
* you shouldn't use this as making your own primal aspects will break all the things.
*/
public Aspect(String tag, int color, String chatcolor, int blend) {
this(tag,color,(Aspect[])null, blend);
this.setChatcolor(chatcolor);
}
public int getColor() {
return color;
}
public String getName() {
return WordUtils.capitalizeFully(tag);
}
public String getLocalizedDescription() {
return StatCollector.translateToLocal("tc.aspect."+tag);
}
public String getTag() {
return tag;
}
public void setTag(String tag) {
this.tag = tag;
}
public Aspect[] getComponents() {
return components;
}
public void setComponents(Aspect[] components) {
this.components = components;
}
public ResourceLocation getImage() {
return image;
}
public static Aspect getAspect(String tag) {
return aspects.get(tag);
}
public int getBlend() {
return blend;
}
public void setBlend(int blend) {
this.blend = blend;
}
public boolean isPrimal() {
return getComponents()==null || getComponents().length!=2;
}
///////////////////////////////
public static ArrayList<Aspect> getPrimalAspects() {
ArrayList<Aspect> primals = new ArrayList<Aspect>();
Collection<Aspect> pa = aspects.values();
for (Aspect aspect:pa) {
if (aspect.isPrimal()) primals.add(aspect);
}
return primals;
}
public static ArrayList<Aspect> getCompoundAspects() {
ArrayList<Aspect> compounds = new ArrayList<Aspect>();
Collection<Aspect> pa = aspects.values();
for (Aspect aspect:pa) {
if (!aspect.isPrimal()) compounds.add(aspect);
}
return compounds;
}
public String getChatcolor() {
return chatcolor;
}
public void setChatcolor(String chatcolor) {
this.chatcolor = chatcolor;
}
///////////////////////////////
public static LinkedHashMap<String,Aspect> aspects = new LinkedHashMap<String,Aspect>();
//PRIMAL
public static final Aspect AIR = new Aspect("aer",0xffff7e,"e",1);
public static final Aspect EARTH = new Aspect("terra",0x56c000,"2",1);
public static final Aspect FIRE = new Aspect("ignis",0xff5a01,"c",1);
public static final Aspect WATER = new Aspect("aqua",0x3cd4fc,"3",1);
public static final Aspect ORDER = new Aspect("ordo",0xd5d4ec,"7",1);
public static final Aspect ENTROPY = new Aspect("perditio",0x404040,"8",771);
//SECONDARY TODO
public static final Aspect VOID = new Aspect("vacuos",0x888888, new Aspect[] {AIR, ENTROPY},771);
public static final Aspect LIGHT = new Aspect("lux",0xfff663, new Aspect[] {AIR, FIRE});
public static final Aspect ENERGY = new Aspect("potentia",0xc0ffff, new Aspect[] {ORDER, FIRE});
public static final Aspect MOTION = new Aspect("motus",0xcdccf4, new Aspect[] {AIR, ORDER});
public static final Aspect STONE = new Aspect("saxum",0x808080, new Aspect[] {EARTH, EARTH});
public static final Aspect LIFE = new Aspect("victus",0xde0005, new Aspect[] {WATER, EARTH});
public static final Aspect WEATHER = new Aspect("tempestas",0xFFFFFF, new Aspect[] {AIR, WATER});
public static final Aspect ICE = new Aspect("gelum",0xe1ffff, new Aspect[] {WATER, ORDER});
public static final Aspect CRYSTAL = new Aspect("vitreus",0x80ffff, new Aspect[] {STONE, WATER});
//TERTIARY TODO
public static final Aspect DEATH = new Aspect("mortuus",0x887788, new Aspect[] {LIFE, ENTROPY});
public static final Aspect FLIGHT = new Aspect("volatus",0xe7e7d7, new Aspect[] {AIR, MOTION});
public static final Aspect DARKNESS = new Aspect("tenebrae",0x222222, new Aspect[] {VOID, LIGHT});
public static final Aspect SOUL = new Aspect("spiritus",0xebebfb, new Aspect[] {LIFE, DEATH});
public static final Aspect HEAL = new Aspect("sano",0xff2f34, new Aspect[] {LIFE, LIFE});
public static final Aspect TRAVEL = new Aspect("iter",0xe0585b, new Aspect[] {MOTION, EARTH});
public static final Aspect POISON = new Aspect("venenum",0x89f000, new Aspect[] {WATER, DEATH});
public static final Aspect ELDRITCH = new Aspect("alienis",0x805080, new Aspect[] {VOID, DARKNESS});
public static final Aspect MAGIC = new Aspect("praecantatio",0x9700c0, new Aspect[] {VOID, ENERGY});
public static final Aspect AURA = new Aspect("auram",0xffc0ff, new Aspect[] {MAGIC, AIR});
public static final Aspect TAINT = new Aspect("vitium",0x800080, new Aspect[] {MAGIC, ENTROPY});
public static final Aspect SEED = new Aspect("granum",0xeea16e, new Aspect[] {LIFE, EARTH});
public static final Aspect SLIME = new Aspect("limus",0x01f800, new Aspect[] {LIFE, WATER});
public static final Aspect PLANT = new Aspect("herba",0x01ac00, new Aspect[] {SEED, EARTH});
public static final Aspect TREE = new Aspect("arbor",0x876531, new Aspect[] {EARTH, PLANT});
public static final Aspect BEAST = new Aspect("bestia",0x9f6409, new Aspect[] {MOTION, LIFE});
public static final Aspect FLESH = new Aspect("corpus",0xee478d, new Aspect[] {DEATH,BEAST});
public static final Aspect UNDEAD = new Aspect("exanimis",0x3a4000, new Aspect[] {MOTION, DEATH});
public static final Aspect MIND = new Aspect("cognitio",0xffc2b3, new Aspect[] {EARTH, SOUL});
public static final Aspect SENSES = new Aspect("sensus",0x0fd9ff, new Aspect[] {AIR, SOUL});
public static final Aspect MAN = new Aspect("humanus",0xffd7c0, new Aspect[] {BEAST, MIND});
public static final Aspect CROP = new Aspect("messis",0xe1b371, new Aspect[] {SEED, MAN});
public static final Aspect HARVEST = new Aspect("meto",0xeead82, new Aspect[] {CROP, MAN});
public static final Aspect METAL = new Aspect("metallum",0xb5b5cd, new Aspect[] {STONE, ORDER});
public static final Aspect MINE = new Aspect("perfodio",0xdcd2d8, new Aspect[] {MAN, STONE});
public static final Aspect TOOL = new Aspect("instrumentum",0x4040ee, new Aspect[] {MAN, METAL});
public static final Aspect WEAPON = new Aspect("telum",0xc05050, new Aspect[] {TOOL, ENTROPY});
public static final Aspect ARMOR = new Aspect("tutamen",0x00c0c0, new Aspect[] {TOOL, EARTH});
public static final Aspect HUNGER = new Aspect("fames",0x9a0305, new Aspect[] {LIFE, VOID});
public static final Aspect GREED = new Aspect("lucrum",0xe6be44, new Aspect[] {MAN, HUNGER});
public static final Aspect CRAFT = new Aspect("fabrico",0x809d80, new Aspect[] {MAN,TOOL});
public static final Aspect CLOTH = new Aspect("pannus",0xeaeac2, new Aspect[] {TOOL, BEAST});
public static final Aspect MECHANISM = new Aspect("machina",0x8080a0, new Aspect[] {MOTION, TOOL});
public static final Aspect TRAP = new Aspect("vinculum",0x9a8080, new Aspect[] {MOTION, ENTROPY});
public static final Aspect EXCHANGE = new Aspect("permutatio",0x578357, new Aspect[] {MOTION, WATER});
// public static final Aspect LAVA = new Aspect("lava",0xe85729, new Aspect[] {EARTH, FIRE});
// public static final Aspect STEAM = new Aspect("steam",0xFFFFFF, new Aspect[] {WATER, FIRE});
// public static final Aspect MUD = new Aspect("lutum",0x473423, new Aspect[] {WATER, EARTH});
// public static final Aspect SAND = new Aspect("sand",0xFFFFFF, new Aspect[] {AIR, EARTH});
// public static final Aspect ASTRAL = new Aspect("Astral",0xFFFFFF, new Aspect[] {VOID, DARKNESS});
// public static final Aspect HARM = new Aspect("Harm",0xFFFFFF, new Aspect[] {ENTROPY, LIFE});
// public static final Aspect BIRD = new Aspect("Bird",0xFFFFFF, new Aspect[] {BEAST, AIR});
// public static final Aspect FISH = new Aspect("Fish",0xFFFFFF, new Aspect[] {BEAST, WATER});
}

View File

@ -0,0 +1,249 @@
package thaumcraft.api.aspects;
import java.io.Serializable;
import java.util.LinkedHashMap;
import net.minecraft.item.ItemStack;
import net.minecraft.nbt.NBTTagCompound;
import net.minecraft.nbt.NBTTagList;
import thaumcraft.api.ThaumcraftApiHelper;
public class AspectList implements Serializable {
public LinkedHashMap<Aspect,Integer> aspects = new LinkedHashMap<Aspect,Integer>();//aspects associated with this object
/**
* this creates a new aspect list with preloaded values based off the aspects of the given item.
* @param id the item/block id of an existing item
* @param meta the damage value of an existing item
*/
public AspectList(int id, int meta) {
try {
AspectList temp = ThaumcraftApiHelper.getObjectAspects(new ItemStack(id,1,meta));
if (temp!=null)
for (Aspect tag:temp.getAspects()) {
add(tag,temp.getAmount(tag));
}
} catch (Exception e) {}
}
public AspectList() {
}
public AspectList copy() {
AspectList out = new AspectList();
for (Aspect a:this.getAspects())
out.add(a, this.getAmount(a));
return out;
}
/**
* @return the amount of different aspects in this collection
*/
public int size() {
return aspects.size();
}
/**
* @return the amount of total vis in this collection
*/
public int visSize() {
int q = 0;
for (Aspect as:aspects.keySet()) {
q+=this.getAmount(as);
}
return q;
}
/**
* @return an array of all the aspects in this collection
*/
public Aspect[] getAspects() {
Aspect[] q = new Aspect[1];
return aspects.keySet().toArray(q);
}
/**
* @return an array of all the aspects in this collection
*/
public Aspect[] getPrimalAspects() {
AspectList t = new AspectList();
for (Aspect as:aspects.keySet()) {
if (as.isPrimal()) {
t.add(as,1);
}
}
Aspect[] q = new Aspect[1];
return t.aspects.keySet().toArray(q);
}
/**
* @return an array of all the aspects in this collection sorted by name
*/
public Aspect[] getAspectsSorted() {
Aspect[] out = aspects.keySet().toArray(new Aspect[1]);
boolean change=false;
do {
change=false;
for(int a=0;a<out.length-1;a++) {
Aspect e1 = out[a];
Aspect e2 = out[a+1];
if (e1!=null && e2!=null && e1.getTag().compareTo(e2.getTag())>0) {
out[a] = e2;
out[a+1] = e1;
change = true;
break;
}
}
} while (change==true);
return out;
}
/**
* @return an array of all the aspects in this collection sorted by amount
*/
public Aspect[] getAspectsSortedAmount() {
Aspect[] out = aspects.keySet().toArray(new Aspect[1]);
boolean change=false;
do {
change=false;
for(int a=0;a<out.length-1;a++) {
int e1 = getAmount(out[a]);
int e2 = getAmount(out[a+1]);
if (e1>0 && e2>0 && e2>e1) {
Aspect ea = out[a];
Aspect eb = out[a+1];
out[a] = eb;
out[a+1] = ea;
change = true;
break;
}
}
} while (change==true);
return out;
}
/**
* @param key
* @return the amount associated with the given aspect in this collection
*/
public int getAmount(Aspect key) {
return aspects.get(key)==null?0:aspects.get(key);
}
/**
* Reduces the amount of an aspect in this collection by the given amount.
* @param key
* @param amount
* @return
*/
public boolean reduce(Aspect key, int amount) {
if (getAmount(key)>=amount) {
int am = getAmount(key)-amount;
aspects.put(key, am);
return true;
}
return false;
}
/**
* Reduces the amount of an aspect in this collection by the given amount.
* If reduced to 0 or less the aspect will be removed completely.
* @param key
* @param amount
* @return
*/
public AspectList remove(Aspect key, int amount) {
int am = getAmount(key)-amount;
if (am<=0) aspects.remove(key); else
this.aspects.put(key, am);
return this;
}
/**
* Simply removes the aspect from the list
* @param key
* @param amount
* @return
*/
public AspectList remove(Aspect key) {
aspects.remove(key);
return this;
}
/**
* Adds this aspect and amount to the collection.
* If the aspect exists then its value will be increased by the given amount.
* @param aspect
* @param amount
* @return
*/
public AspectList add(Aspect aspect, int amount) {
if (this.aspects.containsKey(aspect)) {
int oldamount = this.aspects.get(aspect);
amount+=oldamount;
}
this.aspects.put( aspect, amount );
return this;
}
/**
* Adds this aspect and amount to the collection.
* If the aspect exists then only the highest of the old or new amount will be used.
* @param aspect
* @param amount
* @return
*/
public AspectList merge(Aspect aspect, int amount) {
if (this.aspects.containsKey(aspect)) {
int oldamount = this.aspects.get(aspect);
if (amount<oldamount) amount=oldamount;
}
this.aspects.put( aspect, amount );
return this;
}
/**
* Reads the list of aspects from nbt
* @param nbttagcompound
* @return
*/
public void readFromNBT(NBTTagCompound nbttagcompound)
{
aspects.clear();
NBTTagList tlist = nbttagcompound.getTagList("Aspects");
for (int j = 0; j < tlist.tagCount(); j++) {
NBTTagCompound rs = (NBTTagCompound) tlist.tagAt(j);
if (rs.hasKey("key")) {
add( Aspect.getAspect(rs.getString("key")),
rs.getInteger("amount"));
}
}
}
/**
* Writes the list of aspects to nbt
* @param nbttagcompound
* @return
*/
public void writeToNBT(NBTTagCompound nbttagcompound)
{
NBTTagList tlist = new NBTTagList();
nbttagcompound.setTag("Aspects", tlist);
for (Aspect aspect : getAspects())
if (aspect != null) {
NBTTagCompound f = new NBTTagCompound();
f.setString("key", aspect.getTag());
f.setInteger("amount", getAmount(aspect));
tlist.appendTag(f);
}
}
}

View File

@ -0,0 +1,64 @@
package thaumcraft.api.aspects;
/**
*
* @author azanor
*
* Used by blocks like the crucible and alembic to hold their aspects.
* Tiles extending this interface will have their aspects show up when viewed by goggles of revealing
*
*/
public interface IAspectContainer {
public AspectList getAspects();
public void setAspects(AspectList aspects);
/**
* This method is used to add a certain amount of an aspect to the tile entity.
* @param tag
* @param amount
* @return the amount of aspect left over that could not be added.
*/
public int addToContainer(Aspect tag, int amount);
/**
* Removes a certain amount of a specific aspect from the tile entity
* @param tag
* @param amount
* @return true if that amount of aspect was available and was removed
*/
public boolean takeFromContainer(Aspect tag, int amount);
/**
* removes a bunch of different aspects and amounts from the tile entity.
* @param ot the ObjectTags object that contains the aspects and their amounts.
* @return true if all the aspects and their amounts were available and successfully removed
*/
public boolean takeFromContainer(AspectList ot);
/**
* Checks if the tile entity contains the listed amount (or more) of the aspect
* @param tag
* @param amount
* @return
*/
public boolean doesContainerContainAmount(Aspect tag,int amount);
/**
* Checks if the tile entity contains all the listed aspects and their amounts
* @param ot the ObjectTags object that contains the aspects and their amounts.
* @return
*/
public boolean doesContainerContain(AspectList ot);
/**
* Returns how much of the aspect this tile entity contains
* @param tag
* @return the amount of that aspect found
*/
public int containerContains(Aspect tag);
}

View File

@ -0,0 +1,16 @@
package thaumcraft.api.aspects;
/**
* @author Azanor
*
* This interface is implemented by tile entites (or possibly anything else) like jars
* so that they can act as an essentia source for blocks like the infusion altar.
*
*/
public interface IAspectSource extends IAspectContainer {
}

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