mirror of
https://github.com/HbmMods/Hbm-s-Nuclear-Tech-GIT.git
synced 2026-01-25 10:32:49 +00:00
Merge remote-tracking branch 'HbmMods/master' into phosphor
This commit is contained in:
commit
faf57d6b9c
16
.editorconfig
Normal file
16
.editorconfig
Normal file
@ -0,0 +1,16 @@
|
||||
root = true
|
||||
|
||||
[*]
|
||||
charset = utf-8
|
||||
end_of_line = crlf
|
||||
indent_style = tab
|
||||
indent_size = tab
|
||||
insert_final_newline = true
|
||||
trim_trailing_whitespace = true
|
||||
max_line_length = off
|
||||
|
||||
[{*.info,*.json,*.mcmeta,*.md,*.cfg,*.yml,*.toml}]
|
||||
tab_width = 2
|
||||
|
||||
[{*.info,*.mcmeta,*.cfg}]
|
||||
end_of_line = lf
|
||||
51
.gitignore
vendored
51
.gitignore
vendored
@ -1,46 +1,31 @@
|
||||
# eclipse
|
||||
eclipse
|
||||
bin
|
||||
*.launch
|
||||
.settings
|
||||
.metadata
|
||||
.classpath
|
||||
.project
|
||||
/eclipse
|
||||
/bin
|
||||
/*.launch
|
||||
/.settings
|
||||
/.metadata
|
||||
/.classpath
|
||||
/.project
|
||||
|
||||
# idea
|
||||
out
|
||||
*.ipr
|
||||
*.iws
|
||||
*.iml
|
||||
.idea
|
||||
/out
|
||||
/*.ipr
|
||||
/*.iws
|
||||
/*.iml
|
||||
/.idea
|
||||
|
||||
# gradle
|
||||
build
|
||||
.gradle
|
||||
/build
|
||||
/.gradle
|
||||
|
||||
# vscode
|
||||
/.vscode
|
||||
|
||||
# other
|
||||
run
|
||||
/run
|
||||
|
||||
# CurseForge configuration
|
||||
/curseforge.properties
|
||||
|
||||
# Changelog backup
|
||||
/changelog.bak
|
||||
|
||||
screenshots/
|
||||
|
||||
saves/
|
||||
|
||||
usernamecache.json
|
||||
|
||||
options.txt
|
||||
|
||||
logs/
|
||||
|
||||
doc/
|
||||
|
||||
crash-reports/
|
||||
|
||||
config/
|
||||
|
||||
asm/
|
||||
|
||||
38
CONTRIBUTING.md
Normal file
38
CONTRIBUTING.md
Normal file
@ -0,0 +1,38 @@
|
||||
# NTM Contribution Guidelines, Version 1
|
||||
|
||||
## Keep it concise
|
||||
|
||||
The best PRs are the ones that are small and to the point. The entire PR should focus on the thing you're trying to do, whether it's a fix or a feature PR. If your PR adds the Super Weldtronic 9000, there's no reason to include changes and tweaks to other things that have nothing to do with the Super Weldtronic 9000. If you think those changes are still necessary, open a new PR.
|
||||
|
||||
## Keep it clean
|
||||
|
||||
While admittedly my own code isn't the cleanest on earth, please try to keep terrible practices at a minimum. Also avoid things like unused variables and imports, mixed indentation styles or changes that have a high likelihood of breaking things.
|
||||
|
||||
Things you should also avoid include:
|
||||
* new libraries (unless your PR absolutely needs it like for special mod compat)
|
||||
* duplicate util functions (just use what we have, man)
|
||||
* unused or half finished util functions (for obvious reasons)
|
||||
* half finished or obviously broken features (à la "bob will fix it, i'm sure of it", please don't do that)
|
||||
|
||||
## Test your code
|
||||
|
||||
This should go without saying, but please don't PR code that was never actually tested or has obvious compiler errors in it.
|
||||
|
||||
**Addendum:** Because apparently some people think that testing is somehow optional, it is now **mandatory** to test the code both on a client and on a server. If the PR contains compat code, the game has to work **with and without** the mod that the compat is for.
|
||||
|
||||
## Communication
|
||||
|
||||
If you're planning on adding some new thing or doing a grand change, it's best to ask whether that's a good idea before spending 50 hours on a project that won't end up getting merged, due to issues that could have been entirely avoidable with communication.
|
||||
|
||||
## No guarantees
|
||||
|
||||
This ties together with the previous point - there's no guarantees that your PR gets merged no matter how hard or long you've worked on it. However, if you follow these guidelines, there's a good chance that your PR will be accepted.
|
||||
|
||||
## I want to help but don't know where to start
|
||||
|
||||
If you want to help the project, consider getting involved with the [wiki](https://nucleartech.wiki/) first. Writing an article is the easiest and quickest way of helping, and requires no programming knowledge. If you do know Java and want to help, consider these places first:
|
||||
|
||||
* Localization, i.e. translations in different language are always accepted.
|
||||
* `IConfigurableMachine`, an interface that allows machines to be added to the `hbmMachines.json` config, is still not used by many machines.
|
||||
* F1 Presentations, also known as "Stare" or "Jar Presentations", is a neat system of creating a short movie explaining functionality. All the relevant code can be found in `com.hbm.wiaj`.
|
||||
* Adding tooltips to more machines, explaining some of the basics.
|
||||
35
README.md
35
README.md
@ -4,12 +4,16 @@
|
||||
|
||||
[NTM on CurseForge](https://minecraft.curseforge.com/projects/hbms-nuclear-tech-mod?gameCategorySlug=mc-mods&projectID=235439)
|
||||
|
||||
[Official NTM Wiki](https://nucleartech.wiki/wiki/Main_Page)
|
||||
|
||||
[Bobcat's Blog (the blag)](https://hbmmods.github.io/), you can find lengthy yapping, upcoming features and some secrets here.
|
||||
|
||||
**This is for 1.7.10!** For 1.12, check out these projects:
|
||||
|
||||
* NTM Reloaded: https://github.com/TheOriginalGolem/Hbm-s-Nuclear-Tech-GIT/releases
|
||||
* NTM Extended Edition (Alcater): https://github.com/Alcatergit/Hbm-s-Nuclear-Tech-GIT/releases
|
||||
|
||||
For 1.18, try Martin's remake: https://github.com/MartinTheDragon/Nuclear-Tech-Mod-Remake/releases
|
||||
For 1.18, try Martin's remake: https://codeberg.org/MartinTheDragon/Nuclear-Tech-Mod-Remake/releases
|
||||
|
||||
## Downloading pre-compiled versions from GitHub
|
||||
|
||||
@ -91,9 +95,29 @@ If you want to make some changes to the mod, follow this guide:
|
||||
* Click **Add Standard VM**; in the JRE home, navigate to the directory where the JDK is installed, then click finish and select it.
|
||||
10. Code!
|
||||
|
||||
## Contributing animations
|
||||
Weapon animations in NTM are stored in JSON files, which are used alongside OBJ models to produce high quality animations with reasonable filesizes. Import/Export Blender addons are available for versions 2.79, 3.2, and 4.0 in `tools`, and they should function reasonably well in newer versions as well. See the comments in the header of the export scripts for usage instructions.
|
||||
|
||||
## Compatibility notice
|
||||
NTM has certain behaviors intended to fix vanilla code or to increase compatibility in certain cases where it otherwise would not be possible. These behaviors have the potential of not playing well with other mods, and while no such cases are currently known, here's a list of them.
|
||||
|
||||
### Thermos
|
||||
Thermos servers (along with its forks such as Crucible) have a "performance" feature that causes all tile entity ticking to slow down if there's no player present in the same chunk. For obvious reasons, this will heavily impact machines and cause phantom issues that, not having knowledge of this "performance" feature, are near impossible to diagnose. By default, NTM will crash on servers running the Thermos base code and print a lengthy message informing server owners about this "performance" feature as well as how to fix the issues it causes. The error message is printed in plain English on the top of the crash log, failure to read (as well as understand) it will leave the server inoperable.
|
||||
|
||||
### Shaders
|
||||
Shaders (loaded by either Optifine, Iris or otherwise) will in all likelihood break when a gun is held. This is because guns need to skip vanilla's first person item setup for the rendering, however shaders apparently use the setup step for setting certain GL states, and skipping that will break rendering. [Shader Fixer](https://modrinth.com/mod/shader-fixer) is a mod with various fixes, among which is explicit compatibility for NTM's guns.
|
||||
|
||||
### Optifine
|
||||
One of the most common "performance" mods on 1.7.10, Optifine, achieves an increase in performance by breaking small things in spots that are usually hard to notice, although this can cause severe issues with NTM. A short list of problems, along with some solutions, follows:
|
||||
* Get rid of Optifine and use one of the many [other, less intrusive performance mods](https://gist.github.com/makamys/7cb74cd71d93a4332d2891db2624e17c).
|
||||
* Blocks with connected textures may become invisible. This can be fixed by toggling triangulation (I do not know what or where this setting is, I just have been told that it exists and that it can fix the problem) or multicore chunk rendering (same here).
|
||||
* Entity "optimization" has a tendency to break chunkloading, this is especially noticeable with missiles which rely heavily on chunkloading to work, causing them to freeze mid-air. It's unclear what setting might fix this, and analysis of Optifine's source code (or rather, lack thereof) has not proven useful either.
|
||||
|
||||
### Angelica
|
||||
In older versions, Angelica caused issues regarding model rendering, often times making 3D models transparent. Ever since the switch to VBOs, models work fine. Another issue was blocks with connected textures not rendering at all, but this too was fixed, meaning as of time of writing there are no major incompatibilities known with Angelica. However there a few minor issues that persist, but those can be fixed:
|
||||
* Often times when making a new world, all items appear as white squares. Somehow, scrolling though the NEI pages fixes this permanently
|
||||
* Reeds will render weirdly, this is an incompatibility with the "Compact Vertex Format" feature. Disabling it will make reeds look normal. Alternatively, reed rendering can be disabled by using `/ntmclient set RENDER_REEDS false`, which works around the issue by not rendering the underwater portion of reeds at all.
|
||||
|
||||
### Skybox chainloader
|
||||
NTM adds a few small things to the skybox using a custom skybox renderer. Minecraft can only have a single skybox renderer loaded, so setting the skybox to the NTM custom one would break compatibility with other mods' skyboxes. To mend this, NTM employs a **chainloader**. This chainloader will detect if a different skybox is loaded, save a reference to that skybox and then use NTM's skybox, which when used will also make sure to run the previous modded skybox renderer. In the event that NTM's skybox were to cause trouble, it can be disabled with the config option `1.31_enableSkyboxes`.
|
||||
|
||||
@ -106,5 +130,14 @@ An often overlooked aspect of Minecraft is its stats, the game keeps track of ho
|
||||
### Keybind overlap
|
||||
An often annoying aspect of modded Minecraft is its keybinds. Even though multiple binds can be assigned the same key, all but one will show up as "conflicting" and only the non-conflicting one will work. Which one this is is usually arbitrary, and there is no reason to have such limitation. Often times keybinds are only applicable in certain scenarios, and a commonly found degree of overlap is within reason. Therefore, NTM will run its own key handling code which allows conflicting keybinds to work. If there should be any issues with this behavior, it can be disabled with the config option `1.34_enableKeybindOverlap`.
|
||||
|
||||
### Render distance capping
|
||||
There is a common crash caused by Minecraft's render distance slider going out of bounds, this usually happens when uninstalling a mod that extends the render distance (like Optifine) or when downgrading the Minecraft version (newer versions have higher render distance caps). To prevent crashes, the mod will attempt to decrease the render distance if it's above 16 unless Optifine is installed. If this behavior is not desired (for example, because another mod that allows higher render distance is being used), it can be disabled with the config option `1.25_enableRenderDistCheck`.
|
||||
|
||||
### Log spam caused by ComparableStack
|
||||
In some modpacks (exact mods needed to replicate this are unknown), it's possible that invalid registered items may cause problems for NEI handlers. To prevent crashes, the ComparableStack class used to represent stacks will default to a safe registered item, and print a log message. In certain situations, this may cause dozens of errors to be printed at once, potentially even lagging the game. If that happens, the log message (but not the error handling) can be disabled with the config option `1.28_enableSilentCompStackErrors`.
|
||||
|
||||
### Sound system limit
|
||||
By default, the sound system only allows a limited amount of sounds to run at once (28 regular sounds and 4 streaming sounds), this causes issues when there's many machines running at once, since their looped sounds will constantly interrupt each other, causing them to immediately restart, which in some isolated cases has proven to cause massive lagspikes. To prevent this, NTM will increase the sound limit to 1000 regular sounds and 50 streaming sounds, this can be disabled with the config option `1.39_enableSoundExtension`.
|
||||
|
||||
# License
|
||||
This software is licensed under the GNU Lesser General Public License version 3. In short: This software is free, you may run the software freely, create modified versions, distribute this software and distribute modified versions, as long as the modified software too has a free software license (with an exception for linking to this software, as stated by the "Lesser" part of the LGPL, where this may not be required). You win this round, Stallman. The full license can be found in the `LICENSE` and `LICENSE.LESSER` files.
|
||||
|
||||
@ -71,6 +71,10 @@ repositories {
|
||||
name = 'ModMaven'
|
||||
url = 'https://modmaven.dev'
|
||||
}
|
||||
maven {
|
||||
name = "gt"
|
||||
url = "https://gregtech.mechaenetia.com/"
|
||||
}
|
||||
//maven {
|
||||
// name = "CurseForge"
|
||||
// url = "https://minecraft.curseforge.com/api/maven/"
|
||||
@ -87,7 +91,8 @@ dependencies {
|
||||
implementation 'codechicken:NotEnoughItems:1.7.10-1.0.3.74:dev'
|
||||
compileOnly 'codechicken:NotEnoughItems:1.7.10-1.0.3.74:src'
|
||||
|
||||
//compileOnly 'inventory-tweaks:InventoryTweaks:1.62+beta.84:api'
|
||||
compileOnly "inventorytweaks:InventoryTweaks:1.59-dev:deobf"
|
||||
|
||||
implementation "li.cil.oc:OpenComputers:MC1.7.10-1.5.+:api"
|
||||
}
|
||||
|
||||
|
||||
85
changelog
85
changelog
@ -1,55 +1,40 @@
|
||||
## The performance update
|
||||
* my boy gammawave basically did the entire thing
|
||||
* packet sending should be more performant now, which affects most machines
|
||||
* RBMKs are now *much* more performant with their simulation and packets
|
||||
|
||||
## Added
|
||||
* Glpyhids
|
||||
* Hives will spawn randomly in the world
|
||||
* Hives will constantly spawn new glyphids
|
||||
* If exposed to soot, hives will create glyphid scouts, which when far enough from another hive will explode and generate a new hive
|
||||
* Higher soot levels create stronger glyphids
|
||||
* Glyphids possess armor which has a chance of breaking off and fully absorbing damage
|
||||
* Each glyphid has five armor plates
|
||||
* Glyphid types include multiple tiers of melee glyphids as well as a few ranged ones, the scout, and a nuclear variant
|
||||
* Compressor
|
||||
* Can compress fluids, turning them into higher pressure variants
|
||||
* Higher pressure fluid can use the same ducts as regular fluids, connections work the same so long as the input tank can accept the higher pressure type
|
||||
* Can also turn steam into higher pressure types
|
||||
* Vacuum refining now requires oil at 2 PU
|
||||
* Some chemical plant recipes also require compressed fluid, TATB requires sour gas at 1 PU and osmiridic solution requires hydrogen peroxide at 5 PU
|
||||
* A new rocket artillery ammo type that creates volcanic lava on impact
|
||||
* BDCL
|
||||
* A type of lubricant that is easy to make and can be used in hydraulic piston and electric press recipes instead of regular lubricant
|
||||
* FBI drones
|
||||
* A configurable amount of drones can now spawn during FBI raids
|
||||
* They will hover over players, dropping bombs
|
||||
* 10 gauge slug
|
||||
* Shredder
|
||||
* A b-side for the autoshotgun
|
||||
* Fires 12 gauge, accelerated by plasma, which bursts on impact
|
||||
* Fragments move slowly and have damaging ricochet effects
|
||||
* Fragments keep the effects of the original shell (e.g. explosive shell will spawn a single explosive fragment)
|
||||
* Other gun stuff
|
||||
|
||||
## Changed
|
||||
* Updated russian localization
|
||||
* Fluid traits can now be configured, any fluid can now have any fluid with variable stats assigned to them
|
||||
* Large explosions now load the central chunk they are in, this can be disabled in the config
|
||||
* Burning leaded fuels now releases poisonous heavy metals into the atmosphere
|
||||
* The pollution detector now displays rounded values
|
||||
* More machines and especially destroyed ones now release soot
|
||||
* The iGen has been rebalanced again, delete your machine config file for the changes to take effect
|
||||
* The lubricant power multiplier has been increased from 1.1 to 1.5
|
||||
* The fluid divisor has been lowered from 5,000 to 1,000, meaning the iGen now burns flammable liquids at full efficiency
|
||||
* Removed the config for having an additional keybind for dashing, the keybind is now always active since it no longer conflicts with crouching
|
||||
* Crucible recipes no longer use foundry scraps to visualize the recipes, instead they use a lava-like texture
|
||||
* Fusion reactors are now made from welded magnets which are created by welding a cast steel plate onto a magnet
|
||||
* Due to the cost of the cast plates, fusion reactor magnets are now cheaper to compensate
|
||||
* Consequently, particle accelerators are now also cheaper due to being made from mostly fusion reactor magnets
|
||||
* The blowtorch now consumes only 250mB per operation, allowing for up to 16 things to be welded with a single fill
|
||||
* The page and notebook items have been replaced with more dynamic book items that get their data from NBT
|
||||
* C4 can now be made by irradiating PVC
|
||||
* Play stupid games, win stupid prizes
|
||||
* Gas grenades now use the new gas system which should be a lot more pleasant to look at and less heavy on the TPS
|
||||
* Leaded fuels now release heavy metal into the air, heavy metal can cause lead poisoning
|
||||
* Lower heavy metal concentrations can also cause heavy metal poisoning when breaking blocks
|
||||
* Gas artillery shell now create heavy metal and poisonous pollution
|
||||
* FBI agents will now target the player from a much larger distance
|
||||
* Black powder bullets now have 75% base damage instead of 50%
|
||||
* Ball and powder type rounds no longer have a bonus on headshot
|
||||
* Shot and powder now does way less damage
|
||||
* Some secret ammo types are now craftable
|
||||
* Updated the assault rifle's texture
|
||||
* Shooting at old CRT screens now breaks them
|
||||
* Leviathan turbines now have a tooltip showing their buffers
|
||||
* Fullerene now only uses visible light instead of UV to make, meaning fullerite can be obtained without a fusion or watz reactor (still requiring vacuum oil though)
|
||||
* Crumb yields from bedrock ore processing has been heavily decreased, all recipes that yield crumbs produce no more than one pile
|
||||
|
||||
## Fixed
|
||||
* Fixed potential crash or logspam regarding the pollution handler
|
||||
* Fixed missiles leaving behind a 3x3 grid of loaded chunks after being destroyed
|
||||
* Fixed coal ore yielding coal in the crucible instead of making carbon
|
||||
* Fixed a potential issue where BuildCraft generators can't supply the RF to HE converter
|
||||
* Fixed combustion engine sound sometimes continue playing even when turned off
|
||||
* Fixed large mining drill not properly performing a block check and potentially deleting blocks when placed
|
||||
* Fixed calcium solution not having a fluid texture
|
||||
* Fixed `ITEM_TOOLTIP_SHOW_CUSTOM_NUKE` client config overriding `ITEM_TOOLTIP_SHOW_OREDICT` due to name overlap
|
||||
* Fixed certain secret weapon creation condition not working properly
|
||||
* Fixed artillery rockets getting stuck in the air when their target is not set to a block
|
||||
* Fixed potential issue of ABMs getting stuck mid-flight when their target is destroyed prematurely
|
||||
* Fixed mistakes in the fragment names for de_DE
|
||||
* Fixed nitra rocket duplication only yielding one rocket
|
||||
* Fixed rotary furnace not always properly showing the metal pouring effect
|
||||
* Fixed T45 model not lifting its arms when a new gun is held
|
||||
* Like previously, due to the archaic nature of the model, the rotations are not very precise, and will most likely break when holding an akimbo gun
|
||||
* Potentially fixed an issue where cargo planes do not successfully spawn on lower render distances
|
||||
* Fixed glyphids not calling their `onDeath` function properly, causing them to not drop anything and preventing the appropriate forge events from firing
|
||||
* Fixed GL state leak caused by plasma blast particles, causing other particles (especially bones) to render weird
|
||||
* Fixed night vision goggles being constantly disabled due to m1tty's night vision removal out of water
|
||||
* Fixed armor on test dummies entering the sneaked state in third person view when the player sneaks
|
||||
|
||||
@ -1,17 +1,62 @@
|
||||
mod_version=1.0.27
|
||||
# Empty build number makes a release type
|
||||
mod_build_number=4641
|
||||
mod_build_number=5202
|
||||
|
||||
credits=HbMinecraft, rodolphito (explosion algorithms), grangerave (explosion algorithms),\
|
||||
\ Hoboy (textures, models), Doctor17 (russian localization), Drillgon200 (effects, models,\
|
||||
\ porting), UFFR (RTGs, guns, casings, euphemium capacitor), Pu-238 (Tom impact effects), Bismarck\
|
||||
\ (chinese localization), Frooz (models), Minecreep (models), VT-6/24 (models, textures), Pheo (textures,\
|
||||
\ various machines, models, weapons), Vær (gas centrifuges, better worldgen, ZIRNOX, CP-1 parts, starter guide),\
|
||||
\ Adam29 (liquid petroleum, ethanol, electric furnace), Pashtet (russian localization), MartinTheDragon\
|
||||
\ (calculator, chunk-based fallout), haru315 (spiral point algorithm), Sten89 (models), Pixelguru26\
|
||||
\ (textures), TheBlueHat (textures), Alcater (GUI textures, porting), impbk2002 (project settings),\
|
||||
\ Burningwater202 (laminate glass), OvermindDL1 (project settings), TehTemmie (reacher radiation function),\
|
||||
\ Toshayo (satellite loot system, project settings, gradle curse task), Silly541 (config for safe ME drives),\
|
||||
\ Voxelstice (OpenComputers integration, turbine spinup), BallOfEnergy1 (OpenComputers integration), martemen\
|
||||
\ (project settings), Pvndols (thorium fuel recipe, gas turbine), JamesH2 (blood mechanics, nitric acid,\
|
||||
\ particle emitter), sdddddf80 (recipe configs, chinese localization), SuperCraftAlex (tooltips)
|
||||
credits=HbMinecraft,\
|
||||
\ rodolphito (explosion algorithms),\
|
||||
\ grangerave (explosion algorithms),\
|
||||
\ Hoboy (textures, models),\
|
||||
\ Drillgon200 (effects, models, porting),\
|
||||
\ MartinTheDragon (calculator, chunk-based fallout, bendable cranes, pipe improvements, PWR sounds),\
|
||||
\ Alcater (GUI textures, porting),\
|
||||
\ MellowArpeggiation (new animation system, turbine sounds, sound fixes, industrial lights, better particle diodes),\
|
||||
\ Pheo (textures, various machines, models, weapons),\
|
||||
\ Vær (gas centrifuges, better worldgen, ZIRNOX, CP-1 parts, starter guide, new cyclotron, weapon animations),\
|
||||
\ LePeep (coilgun model, BDCL QC),\
|
||||
\ Adam29 (liquid petroleum, ethanol, electric furnace),\
|
||||
\ Pvndols (thorium fuel recipe, gas turbine),\
|
||||
\ JamesH2 (blood mechanics, nitric acid, particle emitter),\
|
||||
\ PastaBaguette (coal horse decal),\
|
||||
\ Doctor17 (russian localization)),\
|
||||
\ Pashtet (russian localization),\
|
||||
\ Bismarck (chinese localization),\
|
||||
\ Creeper-banner (chinese localization),\
|
||||
\ 5467864 (chinese localization),\
|
||||
\ eeeeee0a (chinese localization),\
|
||||
\ hz0909adc (chinese localization),\
|
||||
\ LSKLW (chinese localization),\
|
||||
\ R-Kaenbyou (chinese localization),\
|
||||
\ scp-000000000 (chinese localization),\
|
||||
\ UnnameTokiko (chinese localization),\
|
||||
\ Herobrine 457985 (chinese localization),\
|
||||
\ xxwinhere (chinese localization),\
|
||||
\ Maksymisio (polish localization)\
|
||||
\ el3ctro4ndre (italian localization),\
|
||||
\ Pu-238 (Tom impact effects),\
|
||||
\ UFFR (RTG pellets, guns, casings, euphemium capacitor),\
|
||||
\ Frooz (gun models),\
|
||||
\ VT-6/24 (models, textures),\
|
||||
\ Nos (models),\
|
||||
\ Minecreep (models),\
|
||||
\ 70k (textures, glyphid AI, strand caster, electrolyzer changes),\
|
||||
\ haru315 (spiral point algorithm),\
|
||||
\ Sten89 (models),\
|
||||
\ Pixelguru26 (textures),\
|
||||
\ TheBlueHat (textures),\
|
||||
\ Burningwater202 (laminate glass),\
|
||||
\ TehTemmie (reacher radiation function),\
|
||||
\ Silly541 (config for safe ME drives),\
|
||||
\ Voxelstice (OpenComputers integration, turbine spinup),\
|
||||
\ BallOfEnergy1 (OpenComputers integration),\
|
||||
\ sdddddf80 (recipe configs, chinese localization, custom machine holograms),\
|
||||
\ Abel1502 (optimization, crate upgrade recipes, strand caster improvements, varous tweaks),\
|
||||
\ SuperCraftAlex (tooltips)\
|
||||
\ Ice-Arrow (research reactor tweaks),\
|
||||
\ 245tt (anvil GUI improvements),\
|
||||
\ KoblizekXD (doors),\
|
||||
\ FOlkvangrField (custom machine parts),\
|
||||
\ RosaTryp (centrifuge config),\
|
||||
\ Toshayo (satellite loot system, project settings, gradle curse task),\
|
||||
\ martemen (project settings),\
|
||||
\ OvermindDL1 (project settings),\
|
||||
\ impbk2002 (project settings)\
|
||||
|
||||
15
src/main/java/api/hbm/block/IFuckingExplode.java
Normal file
15
src/main/java/api/hbm/block/IFuckingExplode.java
Normal file
@ -0,0 +1,15 @@
|
||||
package api.hbm.block;
|
||||
|
||||
import com.hbm.entity.item.EntityTNTPrimedBase;
|
||||
|
||||
import net.minecraft.world.World;
|
||||
|
||||
public interface IFuckingExplode {
|
||||
|
||||
// Anything that can be detonated by another explosion should implement this and spawn an EntityTNTPrimedBase when hit by an explosion
|
||||
// This prevents chained explosions causing a stack overflow
|
||||
// Note that the block can still safely immediately explode, as long as the source isn't another explosion
|
||||
|
||||
public void explodeEntity(World world, double x, double y, double z, EntityTNTPrimedBase entity);
|
||||
|
||||
}
|
||||
@ -1,160 +0,0 @@
|
||||
package api.hbm.energy;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
|
||||
import net.minecraft.tileentity.TileEntity;
|
||||
import net.minecraftforge.common.util.ForgeDirection;
|
||||
|
||||
/**
|
||||
* For compatible cables with no buffer, using the IPowertNet. You can make your own cables with IEnergyConnector as well, but they won't join their power network.
|
||||
* @author hbm
|
||||
*/
|
||||
public interface IEnergyConductor extends IEnergyConnector {
|
||||
|
||||
public IPowerNet getPowerNet();
|
||||
|
||||
public void setPowerNet(IPowerNet network);
|
||||
|
||||
/**
|
||||
* A unique identifier for every conductor tile. Used to prevent duplicates when loading previously persistent unloaded tiles.
|
||||
* @return
|
||||
*/
|
||||
public default int getIdentity() {
|
||||
return getIdentityFromTile((TileEntity) this);
|
||||
}
|
||||
|
||||
public static int getIdentityFromTile(TileEntity te) {
|
||||
return getIdentityFromPos(te.xCoord, te.yCoord, te.zCoord);
|
||||
}
|
||||
|
||||
public static int getIdentityFromPos(int x, int y, int z) {
|
||||
final int prime = 27644437; // must be this large to minimize localized collisions
|
||||
int result = 1;
|
||||
result = prime * result + x;
|
||||
result = prime * result + y;
|
||||
result = prime * result + z;
|
||||
return result;
|
||||
}
|
||||
|
||||
/**
|
||||
* Whether the link should be part of reeval when the network is changed.
|
||||
* I.e. if this link should join any of the new networks (FALSE for switches that are turned off for example)
|
||||
* @return
|
||||
*/
|
||||
public default boolean canReevaluate() {
|
||||
return !((TileEntity) this).isInvalid();
|
||||
}
|
||||
|
||||
/**
|
||||
* When a link leaves the network, the net has to manually calculate the resulting networks.
|
||||
* Each link has to decide what other links will join the same net.
|
||||
* @param copy
|
||||
*/
|
||||
public default void reevaluate(HashMap<Integer, IEnergyConductor> copy, HashMap<Integer, Integer> proxies) {
|
||||
|
||||
for(int[] pos : getConnectionPoints()) {
|
||||
int newX = pos[0];
|
||||
int newY = pos[1];
|
||||
int newZ = pos[2];
|
||||
int id = IEnergyConductor.getIdentityFromPos(newX, newY, newZ);
|
||||
|
||||
IEnergyConductor neighbor = copy.get(id);
|
||||
|
||||
if(neighbor == null) {
|
||||
Integer newId = proxies.get(id);
|
||||
|
||||
if(newId != null) {
|
||||
neighbor = copy.get(newId);
|
||||
}
|
||||
}
|
||||
|
||||
if(neighbor != null && this.canReevaluate() && neighbor.canReevaluate()) {
|
||||
|
||||
if(neighbor.getPowerNet() != null) {
|
||||
|
||||
//neighbor net and no self net
|
||||
if(this.getPowerNet() == null) {
|
||||
neighbor.getPowerNet().joinLink(this);
|
||||
//neighbor net and self net
|
||||
} else {
|
||||
this.getPowerNet().joinNetworks(neighbor.getPowerNet());
|
||||
}
|
||||
|
||||
//bidirectional re-eval, experimental and technically optional, only useful as a fallback
|
||||
} /*else {
|
||||
|
||||
//no neighbor net and no self net
|
||||
if(this.getPowerNet() == null) {
|
||||
this.setPowerNet(new PowerNet().joinLink(this));
|
||||
neighbor.setPowerNet(this.getPowerNet().joinLink(neighbor));
|
||||
//no neighbor net and self net
|
||||
} else {
|
||||
neighbor.setPowerNet(this.getPowerNet().joinLink(neighbor));
|
||||
}
|
||||
}*/
|
||||
|
||||
//extensive debugging has shown that bidirectional re-eval is complete shit
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a list of positions for the re-eval process. In short - what positions should be considered as connected.
|
||||
* Also used by pylons to quickly figure out what positions to connect to.
|
||||
* DEFAULT: Connects to all six neighboring blocks.
|
||||
* @return
|
||||
*/
|
||||
public default List<int[]> getConnectionPoints() {
|
||||
|
||||
List<int[]> pos = new ArrayList();
|
||||
TileEntity tile = (TileEntity) this;
|
||||
|
||||
for(ForgeDirection dir : ForgeDirection.VALID_DIRECTIONS) {
|
||||
int newX = tile.xCoord + dir.offsetX;
|
||||
int newY = tile.yCoord + dir.offsetY;
|
||||
int newZ = tile.zCoord + dir.offsetZ;
|
||||
|
||||
pos.add(new int[] {newX, newY, newZ});
|
||||
}
|
||||
|
||||
return pos;
|
||||
}
|
||||
|
||||
/**
|
||||
* Since isLoaded is only currently used for weeding out unwanted subscribers, and cables shouldn't (although technically can) be
|
||||
* subscribers, we just default to true because I don't feel like wasting time implementing things that we don't actually need.
|
||||
* Perhaps this indicates a minor flaw in the new API, but I physically lack the ability to worry about it.
|
||||
*/
|
||||
@Override
|
||||
public default boolean isLoaded() {
|
||||
return true;
|
||||
}
|
||||
|
||||
//TODO: check if this standard implementation doesn't break anything (it shouldn't but right now it's a bit redundant) also: remove duplicate implementations
|
||||
@Override
|
||||
public default long transferPower(long power) {
|
||||
|
||||
if(this.getPowerNet() == null)
|
||||
return power;
|
||||
|
||||
return this.getPowerNet().transferPower(power);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns whether the conductor has mutliblock proxies which need to be taken into consideration for re-eval.
|
||||
* @return
|
||||
*/
|
||||
public default boolean hasProxies() {
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the identities (position-based) of proxies which resolve into the conductor's own identity.
|
||||
* @return
|
||||
*/
|
||||
public default List<Integer> getProxies() {
|
||||
return new ArrayList();
|
||||
}
|
||||
}
|
||||
@ -1,121 +0,0 @@
|
||||
package api.hbm.energy;
|
||||
|
||||
import com.hbm.packet.AuxParticlePacketNT;
|
||||
import com.hbm.packet.PacketDispatcher;
|
||||
|
||||
import cpw.mods.fml.common.network.NetworkRegistry.TargetPoint;
|
||||
import net.minecraft.nbt.NBTTagCompound;
|
||||
import net.minecraft.tileentity.TileEntity;
|
||||
import net.minecraft.util.Vec3;
|
||||
import net.minecraft.world.World;
|
||||
import net.minecraftforge.common.util.ForgeDirection;
|
||||
|
||||
/**
|
||||
* For anything that connects to power and can be transferred power to, the bottom-level interface.
|
||||
* This is mean for TILE ENTITIES
|
||||
* @author hbm
|
||||
*/
|
||||
public interface IEnergyConnector extends ILoadedTile {
|
||||
|
||||
/**
|
||||
* Returns the amount of power that remains in the source after transfer
|
||||
* @param power
|
||||
* @return
|
||||
*/
|
||||
public long transferPower(long power);
|
||||
|
||||
/**
|
||||
* Whether the given side can be connected to
|
||||
* dir refers to the side of this block, not the connecting block doing the check
|
||||
* @param dir
|
||||
* @return
|
||||
*/
|
||||
public default boolean canConnect(ForgeDirection dir) {
|
||||
return dir != ForgeDirection.UNKNOWN;
|
||||
}
|
||||
|
||||
/**
|
||||
* The current power of either the machine or an entire network
|
||||
* @return
|
||||
*/
|
||||
public long getPower();
|
||||
|
||||
/**
|
||||
* The capacity of either the machine or an entire network
|
||||
* @return
|
||||
*/
|
||||
public long getMaxPower();
|
||||
|
||||
public default long getTransferWeight() {
|
||||
return Math.max(getMaxPower() - getPower(), 0);
|
||||
}
|
||||
|
||||
/**
|
||||
* Basic implementation of subscribing to a nearby power grid
|
||||
* @param world
|
||||
* @param x
|
||||
* @param y
|
||||
* @param z
|
||||
*/
|
||||
public default void trySubscribe(World world, int x, int y, int z, ForgeDirection dir) {
|
||||
|
||||
TileEntity te = world.getTileEntity(x, y, z);
|
||||
boolean red = false;
|
||||
|
||||
if(te instanceof IEnergyConductor) {
|
||||
IEnergyConductor con = (IEnergyConductor) te;
|
||||
|
||||
if(!con.canConnect(dir.getOpposite()))
|
||||
return;
|
||||
|
||||
if(con.getPowerNet() != null && !con.getPowerNet().isSubscribed(this))
|
||||
con.getPowerNet().subscribe(this);
|
||||
|
||||
if(con.getPowerNet() != null)
|
||||
red = true;
|
||||
}
|
||||
|
||||
if(particleDebug) {//
|
||||
NBTTagCompound data = new NBTTagCompound();
|
||||
data.setString("type", "network");
|
||||
data.setString("mode", "power");
|
||||
double posX = x + 0.5 + dir.offsetX * 0.5 + world.rand.nextDouble() * 0.5 - 0.25;
|
||||
double posY = y + 0.5 + dir.offsetY * 0.5 + world.rand.nextDouble() * 0.5 - 0.25;
|
||||
double posZ = z + 0.5 + dir.offsetZ * 0.5 + world.rand.nextDouble() * 0.5 - 0.25;
|
||||
data.setDouble("mX", -dir.offsetX * (red ? 0.025 : 0.1));
|
||||
data.setDouble("mY", -dir.offsetY * (red ? 0.025 : 0.1));
|
||||
data.setDouble("mZ", -dir.offsetZ * (red ? 0.025 : 0.1));
|
||||
PacketDispatcher.wrapper.sendToAllAround(new AuxParticlePacketNT(data, posX, posY, posZ), new TargetPoint(world.provider.dimensionId, posX, posY, posZ, 25));
|
||||
}
|
||||
}
|
||||
|
||||
public default void tryUnsubscribe(World world, int x, int y, int z) {
|
||||
|
||||
TileEntity te = world.getTileEntity(x, y, z);
|
||||
|
||||
if(te instanceof IEnergyConductor) {
|
||||
IEnergyConductor con = (IEnergyConductor) te;
|
||||
|
||||
if(con.getPowerNet() != null && con.getPowerNet().isSubscribed(this))
|
||||
con.getPowerNet().unsubscribe(this);
|
||||
}
|
||||
}
|
||||
|
||||
public static final boolean particleDebug = false;
|
||||
|
||||
public default Vec3 getDebugParticlePos() {
|
||||
TileEntity te = (TileEntity) this;
|
||||
Vec3 vec = Vec3.createVectorHelper(te.xCoord + 0.5, te.yCoord + 1, te.zCoord + 0.5);
|
||||
return vec;
|
||||
}
|
||||
|
||||
public default ConnectionPriority getPriority() {
|
||||
return ConnectionPriority.NORMAL;
|
||||
}
|
||||
|
||||
public enum ConnectionPriority {
|
||||
LOW,
|
||||
NORMAL,
|
||||
HIGH
|
||||
}
|
||||
}
|
||||
@ -1,19 +0,0 @@
|
||||
package api.hbm.energy;
|
||||
|
||||
public interface IEnergyGenerator extends IEnergyUser {
|
||||
|
||||
/**
|
||||
* Standard implementation for machines that can only send energy but never receive it.
|
||||
* @param power
|
||||
*/
|
||||
@Override
|
||||
public default long transferPower(long power) {
|
||||
return power;
|
||||
}
|
||||
|
||||
/* should stop making non-receivers from interfering by applying their weight which doesn't even matter */
|
||||
@Override
|
||||
public default long getTransferWeight() {
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
@ -1,112 +0,0 @@
|
||||
package api.hbm.energy;
|
||||
|
||||
import com.hbm.packet.AuxParticlePacketNT;
|
||||
import com.hbm.packet.PacketDispatcher;
|
||||
|
||||
import cpw.mods.fml.common.network.NetworkRegistry.TargetPoint;
|
||||
import net.minecraft.nbt.NBTTagCompound;
|
||||
import net.minecraft.tileentity.TileEntity;
|
||||
import net.minecraft.world.World;
|
||||
import net.minecraftforge.common.util.ForgeDirection;
|
||||
|
||||
/**
|
||||
* For machines and things that have an energy buffer and are affected by EMPs
|
||||
* @author hbm
|
||||
*/
|
||||
public interface IEnergyUser extends IEnergyConnector {
|
||||
|
||||
/**
|
||||
* Not to be used for actual energy transfer, rather special external things like EMPs and sync packets
|
||||
*/
|
||||
public void setPower(long power);
|
||||
|
||||
/**
|
||||
* Standard implementation for power transfer.
|
||||
* Turns out you can override interfaces to provide a default implementation. Neat.
|
||||
* @param long power
|
||||
*/
|
||||
@Override
|
||||
public default long transferPower(long power) {
|
||||
|
||||
this.setPower(this.getPower() + power);
|
||||
|
||||
if(this.getPower() > this.getMaxPower()) {
|
||||
|
||||
long overshoot = this.getPower() - this.getMaxPower();
|
||||
this.setPower(this.getMaxPower());
|
||||
return overshoot;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* Standard implementation of sending power
|
||||
* @param world
|
||||
* @param x
|
||||
* @param y
|
||||
* @param z
|
||||
* @param dir
|
||||
*/
|
||||
public default void sendPower(World world, int x, int y, int z, ForgeDirection dir) {
|
||||
|
||||
TileEntity te = world.getTileEntity(x, y, z);
|
||||
boolean wasSubscribed = false;
|
||||
boolean red = false;
|
||||
|
||||
// first we make sure we're not subscribed to the network that we'll be supplying
|
||||
if(te instanceof IEnergyConductor) {
|
||||
IEnergyConductor con = (IEnergyConductor) te;
|
||||
|
||||
if(con.canConnect(dir.getOpposite()) && con.getPowerNet() != null && con.getPowerNet().isSubscribed(this)) {
|
||||
con.getPowerNet().unsubscribe(this);
|
||||
wasSubscribed = true;
|
||||
}
|
||||
}
|
||||
|
||||
//then we add energy
|
||||
if(te instanceof IEnergyConnector) {
|
||||
IEnergyConnector con = (IEnergyConnector) te;
|
||||
|
||||
if(con.canConnect(dir.getOpposite())) {
|
||||
long oldPower = this.getPower();
|
||||
long transfer = oldPower - con.transferPower(oldPower);
|
||||
this.setPower(oldPower - transfer);
|
||||
red = true;
|
||||
}
|
||||
}
|
||||
|
||||
//then we subscribe if possible
|
||||
if(wasSubscribed && te instanceof IEnergyConductor) {
|
||||
IEnergyConductor con = (IEnergyConductor) te;
|
||||
|
||||
if(con.getPowerNet() != null && !con.getPowerNet().isSubscribed(this)) {
|
||||
con.getPowerNet().subscribe(this);
|
||||
}
|
||||
}
|
||||
|
||||
if(particleDebug) {
|
||||
NBTTagCompound data = new NBTTagCompound();
|
||||
data.setString("type", "network");
|
||||
data.setString("mode", "power");
|
||||
double posX = x + 0.5 - dir.offsetX * 0.5 + world.rand.nextDouble() * 0.5 - 0.25;
|
||||
double posY = y + 0.5 - dir.offsetY * 0.5 + world.rand.nextDouble() * 0.5 - 0.25;
|
||||
double posZ = z + 0.5 - dir.offsetZ * 0.5 + world.rand.nextDouble() * 0.5 - 0.25;
|
||||
data.setDouble("mX", dir.offsetX * (red ? 0.025 : 0.1));
|
||||
data.setDouble("mY", dir.offsetY * (red ? 0.025 : 0.1));
|
||||
data.setDouble("mZ", dir.offsetZ * (red ? 0.025 : 0.1));
|
||||
PacketDispatcher.wrapper.sendToAllAround(new AuxParticlePacketNT(data, posX, posY, posZ), new TargetPoint(world.provider.dimensionId, posX, posY, posZ, 25));
|
||||
}
|
||||
}
|
||||
|
||||
public default void updateStandardConnections(World world, TileEntity te) {
|
||||
updateStandardConnections(world, te.xCoord, te.yCoord, te.zCoord);
|
||||
}
|
||||
|
||||
public default void updateStandardConnections(World world, int x, int y, int z) {
|
||||
|
||||
for(ForgeDirection dir : ForgeDirection.VALID_DIRECTIONS) {
|
||||
this.trySubscribe(world, x + dir.offsetX, y + dir.offsetY, z + dir.offsetZ, dir);
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -1,6 +0,0 @@
|
||||
package api.hbm.energy;
|
||||
|
||||
public interface ILoadedTile {
|
||||
|
||||
public boolean isLoaded();
|
||||
}
|
||||
@ -1,37 +0,0 @@
|
||||
package api.hbm.energy;
|
||||
|
||||
import java.math.BigInteger;
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* Not mandatory to use, but making your cables IPowerNet-compliant will allow them to connect to NTM cables.
|
||||
* Cables will still work without it as long as they implement IEnergyConductor (or even IEnergyConnector) + self-built network code
|
||||
* @author hbm
|
||||
*/
|
||||
public interface IPowerNet {
|
||||
|
||||
public void joinNetworks(IPowerNet network);
|
||||
|
||||
public IPowerNet joinLink(IEnergyConductor conductor);
|
||||
public void leaveLink(IEnergyConductor conductor);
|
||||
|
||||
public void subscribe(IEnergyConnector connector);
|
||||
public void unsubscribe(IEnergyConnector connector);
|
||||
public boolean isSubscribed(IEnergyConnector connector);
|
||||
|
||||
public void destroy();
|
||||
|
||||
/**
|
||||
* When a link is removed, instead of destroying the network, causing it to be recreated from currently loaded conductors,
|
||||
* we re-evaluate it, creating new nets based on the previous links.
|
||||
*/
|
||||
public void reevaluate();
|
||||
|
||||
public boolean isValid();
|
||||
|
||||
public List<IEnergyConductor> getLinks();
|
||||
public List<IEnergyConnector> getSubscribers();
|
||||
|
||||
public long transferPower(long power);
|
||||
public BigInteger getTotalTransfer();
|
||||
}
|
||||
@ -1,241 +0,0 @@
|
||||
package api.hbm.energy;
|
||||
|
||||
import java.math.BigInteger;
|
||||
import java.util.ArrayList;
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
|
||||
import com.hbm.config.GeneralConfig;
|
||||
|
||||
import api.hbm.energy.IEnergyConnector.ConnectionPriority;
|
||||
import net.minecraft.tileentity.TileEntity;
|
||||
|
||||
/**
|
||||
* Basic IPowerNet implementation. The behavior of this demo might change inbetween releases, but the API remains the same.
|
||||
* For more consistency please implement your own IPowerNet.
|
||||
* @author hbm
|
||||
*/
|
||||
public class PowerNet implements IPowerNet {
|
||||
|
||||
private boolean valid = true;
|
||||
private HashMap<Integer, IEnergyConductor> links = new HashMap();
|
||||
private HashMap<Integer, Integer> proxies = new HashMap();
|
||||
private List<IEnergyConnector> subscribers = new ArrayList();
|
||||
|
||||
public static List<PowerNet> trackingInstances = null;
|
||||
protected BigInteger totalTransfer = BigInteger.ZERO;
|
||||
|
||||
@Override
|
||||
public void joinNetworks(IPowerNet network) {
|
||||
|
||||
if(network == this)
|
||||
return; //wtf?!
|
||||
|
||||
for(IEnergyConductor conductor : network.getLinks()) {
|
||||
joinLink(conductor);
|
||||
}
|
||||
network.getLinks().clear();
|
||||
|
||||
for(IEnergyConnector connector : network.getSubscribers()) {
|
||||
this.subscribe(connector);
|
||||
}
|
||||
|
||||
network.destroy();
|
||||
}
|
||||
|
||||
@Override
|
||||
public IPowerNet joinLink(IEnergyConductor conductor) {
|
||||
|
||||
if(conductor.getPowerNet() != null)
|
||||
conductor.getPowerNet().leaveLink(conductor);
|
||||
|
||||
conductor.setPowerNet(this);
|
||||
int identity = conductor.getIdentity();
|
||||
this.links.put(identity, conductor);
|
||||
|
||||
if(conductor.hasProxies()) {
|
||||
for(Integer i : conductor.getProxies()) {
|
||||
this.proxies.put(i, identity);
|
||||
}
|
||||
}
|
||||
|
||||
return this;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void leaveLink(IEnergyConductor conductor) {
|
||||
conductor.setPowerNet(null);
|
||||
int identity = conductor.getIdentity();
|
||||
this.links.remove(identity);
|
||||
|
||||
if(conductor.hasProxies()) {
|
||||
for(Integer i : conductor.getProxies()) {
|
||||
this.proxies.remove(i);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void subscribe(IEnergyConnector connector) {
|
||||
this.subscribers.add(connector);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void unsubscribe(IEnergyConnector connector) {
|
||||
this.subscribers.remove(connector);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isSubscribed(IEnergyConnector connector) {
|
||||
return this.subscribers.contains(connector);
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<IEnergyConductor> getLinks() {
|
||||
List<IEnergyConductor> linkList = new ArrayList();
|
||||
linkList.addAll(this.links.values());
|
||||
return linkList;
|
||||
}
|
||||
|
||||
public HashMap<Integer, Integer> getProxies() {
|
||||
HashMap<Integer, Integer> proxyCopy = new HashMap(proxies);
|
||||
return proxyCopy;
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<IEnergyConnector> getSubscribers() {
|
||||
return this.subscribers;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void destroy() {
|
||||
this.valid = false;
|
||||
this.subscribers.clear();
|
||||
|
||||
for(IEnergyConductor link : this.links.values()) {
|
||||
link.setPowerNet(null);
|
||||
}
|
||||
|
||||
this.links.clear();
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isValid() {
|
||||
return this.valid;
|
||||
}
|
||||
|
||||
@Override
|
||||
public BigInteger getTotalTransfer() {
|
||||
return this.totalTransfer;
|
||||
}
|
||||
|
||||
public long lastCleanup = System.currentTimeMillis();
|
||||
|
||||
@Override
|
||||
public long transferPower(long power) {
|
||||
|
||||
/*if(lastCleanup + 45 < System.currentTimeMillis()) {
|
||||
cleanup(this.subscribers);
|
||||
lastCleanup = System.currentTimeMillis();
|
||||
}*/
|
||||
|
||||
trackingInstances = new ArrayList();
|
||||
trackingInstances.add(this);
|
||||
return fairTransfer(this.subscribers, power);
|
||||
}
|
||||
|
||||
public static void cleanup(List<IEnergyConnector> subscribers) {
|
||||
|
||||
subscribers.removeIf(x ->
|
||||
x == null || !(x instanceof TileEntity) || ((TileEntity)x).isInvalid() || !x.isLoaded()
|
||||
);
|
||||
}
|
||||
|
||||
public static long fairTransfer(List<IEnergyConnector> subscribers, long power) {
|
||||
|
||||
if(subscribers.isEmpty())
|
||||
return power;
|
||||
|
||||
cleanup(subscribers);
|
||||
|
||||
ConnectionPriority[] priorities = new ConnectionPriority[] {ConnectionPriority.HIGH, ConnectionPriority.NORMAL, ConnectionPriority.LOW};
|
||||
|
||||
long totalTransfer = 0;
|
||||
|
||||
for(ConnectionPriority p : priorities) {
|
||||
|
||||
List<IEnergyConnector> subList = new ArrayList();
|
||||
subscribers.forEach(x -> {
|
||||
if(x.getPriority() == p) {
|
||||
subList.add(x);
|
||||
}
|
||||
});
|
||||
|
||||
if(subList.isEmpty())
|
||||
continue;
|
||||
|
||||
List<Long> weight = new ArrayList();
|
||||
long totalReq = 0;
|
||||
|
||||
for(IEnergyConnector con : subList) {
|
||||
long req = con.getTransferWeight();
|
||||
weight.add(req);
|
||||
totalReq += req;
|
||||
}
|
||||
|
||||
if(totalReq == 0)
|
||||
continue;
|
||||
|
||||
long totalGiven = 0;
|
||||
|
||||
for(int i = 0; i < subList.size(); i++) {
|
||||
IEnergyConnector con = subList.get(i);
|
||||
long req = weight.get(i);
|
||||
double fraction = (double)req / (double)totalReq;
|
||||
|
||||
long given = (long) Math.floor(fraction * power);
|
||||
|
||||
totalGiven += (given - con.transferPower(given));
|
||||
}
|
||||
|
||||
power -= totalGiven;
|
||||
totalTransfer += totalGiven;
|
||||
}
|
||||
|
||||
if(trackingInstances != null) {
|
||||
|
||||
for(int i = 0; i < trackingInstances.size(); i++) {
|
||||
PowerNet net = trackingInstances.get(i);
|
||||
net.totalTransfer = net.totalTransfer.add(BigInteger.valueOf(totalTransfer));
|
||||
}
|
||||
}
|
||||
|
||||
return power;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void reevaluate() {
|
||||
|
||||
if(!GeneralConfig.enableReEval) {
|
||||
this.destroy();
|
||||
return;
|
||||
}
|
||||
|
||||
HashMap<Integer, IEnergyConductor> copy = new HashMap(links);
|
||||
HashMap<Integer, Integer> proxyCopy = new HashMap(proxies);
|
||||
|
||||
for(IEnergyConductor link : copy.values()) {
|
||||
this.leaveLink(link);
|
||||
}
|
||||
|
||||
for(IEnergyConductor link : copy.values()) {
|
||||
|
||||
link.setPowerNet(null);
|
||||
link.reevaluate(copy, proxyCopy);
|
||||
|
||||
if(link.getPowerNet() == null) {
|
||||
link.setPowerNet(new PowerNet().joinLink(link));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -1,4 +1,4 @@
|
||||
package api.hbm.energy;
|
||||
package api.hbm.energymk2;
|
||||
|
||||
import net.minecraft.item.Item;
|
||||
import net.minecraft.item.ItemStack;
|
||||
@ -10,7 +10,7 @@ public interface IBatteryItem {
|
||||
public void setCharge(ItemStack stack, long i);
|
||||
public void dischargeBattery(ItemStack stack, long i);
|
||||
public long getCharge(ItemStack stack);
|
||||
public long getMaxCharge();
|
||||
public long getMaxCharge(ItemStack stack);
|
||||
public long getChargeRate();
|
||||
public long getDischargeRate();
|
||||
|
||||
23
src/main/java/api/hbm/energymk2/IEnergyConductorMK2.java
Normal file
23
src/main/java/api/hbm/energymk2/IEnergyConductorMK2.java
Normal file
@ -0,0 +1,23 @@
|
||||
package api.hbm.energymk2;
|
||||
|
||||
import com.hbm.lib.Library;
|
||||
import com.hbm.util.fauxpointtwelve.BlockPos;
|
||||
import com.hbm.util.fauxpointtwelve.DirPos;
|
||||
|
||||
import api.hbm.energymk2.Nodespace.PowerNode;
|
||||
import net.minecraft.tileentity.TileEntity;
|
||||
|
||||
public interface IEnergyConductorMK2 extends IEnergyConnectorMK2 {
|
||||
|
||||
public default PowerNode createNode() {
|
||||
TileEntity tile = (TileEntity) this;
|
||||
return new PowerNode(new BlockPos(tile.xCoord, tile.yCoord, tile.zCoord)).setConnections(
|
||||
new DirPos(tile.xCoord + 1, tile.yCoord, tile.zCoord, Library.POS_X),
|
||||
new DirPos(tile.xCoord - 1, tile.yCoord, tile.zCoord, Library.NEG_X),
|
||||
new DirPos(tile.xCoord, tile.yCoord + 1, tile.zCoord, Library.POS_Y),
|
||||
new DirPos(tile.xCoord, tile.yCoord - 1, tile.zCoord, Library.NEG_Y),
|
||||
new DirPos(tile.xCoord, tile.yCoord, tile.zCoord + 1, Library.POS_Z),
|
||||
new DirPos(tile.xCoord, tile.yCoord, tile.zCoord - 1, Library.NEG_Z)
|
||||
);
|
||||
}
|
||||
}
|
||||
@ -1,4 +1,4 @@
|
||||
package api.hbm.energy;
|
||||
package api.hbm.energymk2;
|
||||
|
||||
import net.minecraft.world.IBlockAccess;
|
||||
import net.minecraftforge.common.util.ForgeDirection;
|
||||
16
src/main/java/api/hbm/energymk2/IEnergyConnectorMK2.java
Normal file
16
src/main/java/api/hbm/energymk2/IEnergyConnectorMK2.java
Normal file
@ -0,0 +1,16 @@
|
||||
package api.hbm.energymk2;
|
||||
|
||||
import net.minecraftforge.common.util.ForgeDirection;
|
||||
|
||||
public interface IEnergyConnectorMK2 {
|
||||
|
||||
/**
|
||||
* Whether the given side can be connected to
|
||||
* dir refers to the side of this block, not the connecting block doing the check
|
||||
* @param dir
|
||||
* @return
|
||||
*/
|
||||
public default boolean canConnect(ForgeDirection dir) {
|
||||
return dir != ForgeDirection.UNKNOWN;
|
||||
}
|
||||
}
|
||||
29
src/main/java/api/hbm/energymk2/IEnergyHandlerMK2.java
Normal file
29
src/main/java/api/hbm/energymk2/IEnergyHandlerMK2.java
Normal file
@ -0,0 +1,29 @@
|
||||
package api.hbm.energymk2;
|
||||
|
||||
import com.hbm.util.CompatEnergyControl;
|
||||
|
||||
import api.hbm.tile.ILoadedTile;
|
||||
import net.minecraft.nbt.NBTTagCompound;
|
||||
import net.minecraft.tileentity.TileEntity;
|
||||
import net.minecraft.util.Vec3;
|
||||
|
||||
/** DO NOT USE DIRECTLY! This is simply the common ancestor to providers and receivers, because all this behavior has to be excluded from conductors! */
|
||||
public interface IEnergyHandlerMK2 extends IEnergyConnectorMK2, ILoadedTile {
|
||||
|
||||
public long getPower();
|
||||
public void setPower(long power);
|
||||
public long getMaxPower();
|
||||
|
||||
public static final boolean particleDebug = false;
|
||||
|
||||
public default Vec3 getDebugParticlePosMK2() {
|
||||
TileEntity te = (TileEntity) this;
|
||||
Vec3 vec = Vec3.createVectorHelper(te.xCoord + 0.5, te.yCoord + 1, te.zCoord + 0.5);
|
||||
return vec;
|
||||
}
|
||||
|
||||
public default void provideInfoForECMK2(NBTTagCompound data) {
|
||||
data.setLong(CompatEnergyControl.L_ENERGY_HE, this.getPower());
|
||||
data.setLong(CompatEnergyControl.L_CAPACITY_HE, this.getMaxPower());
|
||||
}
|
||||
}
|
||||
68
src/main/java/api/hbm/energymk2/IEnergyProviderMK2.java
Normal file
68
src/main/java/api/hbm/energymk2/IEnergyProviderMK2.java
Normal file
@ -0,0 +1,68 @@
|
||||
package api.hbm.energymk2;
|
||||
|
||||
import com.hbm.packet.PacketDispatcher;
|
||||
import com.hbm.packet.toclient.AuxParticlePacketNT;
|
||||
import com.hbm.util.Compat;
|
||||
|
||||
import api.hbm.energymk2.Nodespace.PowerNode;
|
||||
import cpw.mods.fml.common.network.NetworkRegistry.TargetPoint;
|
||||
import net.minecraft.nbt.NBTTagCompound;
|
||||
import net.minecraft.tileentity.TileEntity;
|
||||
import net.minecraft.world.World;
|
||||
import net.minecraftforge.common.util.ForgeDirection;
|
||||
|
||||
/** If it sends energy, use this */
|
||||
public interface IEnergyProviderMK2 extends IEnergyHandlerMK2 {
|
||||
|
||||
/** Uses up available power, default implementation has no sanity checking, make sure that the requested power is lequal to the current power */
|
||||
public default void usePower(long power) {
|
||||
this.setPower(this.getPower() - power);
|
||||
}
|
||||
|
||||
public default long getProviderSpeed() {
|
||||
return this.getMaxPower();
|
||||
}
|
||||
|
||||
public default void tryProvide(World world, int x, int y, int z, ForgeDirection dir) {
|
||||
|
||||
TileEntity te = Compat.getTileStandard(world, x, y, z);
|
||||
boolean red = false;
|
||||
|
||||
if(te instanceof IEnergyConductorMK2) {
|
||||
IEnergyConductorMK2 con = (IEnergyConductorMK2) te;
|
||||
if(con.canConnect(dir.getOpposite())) {
|
||||
|
||||
PowerNode node = Nodespace.getNode(world, x, y, z);
|
||||
|
||||
if(node != null && node.net != null) {
|
||||
node.net.addProvider(this);
|
||||
red = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if(te instanceof IEnergyReceiverMK2 && te != this) {
|
||||
IEnergyReceiverMK2 rec = (IEnergyReceiverMK2) te;
|
||||
if(rec.canConnect(dir.getOpposite())) {
|
||||
long provides = Math.min(this.getPower(), this.getProviderSpeed());
|
||||
long receives = Math.min(rec.getMaxPower() - rec.getPower(), rec.getReceiverSpeed());
|
||||
long toTransfer = Math.min(provides, receives);
|
||||
toTransfer -= rec.transferPower(toTransfer);
|
||||
this.usePower(toTransfer);
|
||||
}
|
||||
}
|
||||
|
||||
if(particleDebug) {
|
||||
NBTTagCompound data = new NBTTagCompound();
|
||||
data.setString("type", "network");
|
||||
data.setString("mode", "power");
|
||||
double posX = x + 0.5 - dir.offsetX * 0.5 + world.rand.nextDouble() * 0.5 - 0.25;
|
||||
double posY = y + 0.5 - dir.offsetY * 0.5 + world.rand.nextDouble() * 0.5 - 0.25;
|
||||
double posZ = z + 0.5 - dir.offsetZ * 0.5 + world.rand.nextDouble() * 0.5 - 0.25;
|
||||
data.setDouble("mX", dir.offsetX * (red ? 0.025 : 0.1));
|
||||
data.setDouble("mY", dir.offsetY * (red ? 0.025 : 0.1));
|
||||
data.setDouble("mZ", dir.offsetZ * (red ? 0.025 : 0.1));
|
||||
PacketDispatcher.wrapper.sendToAllAround(new AuxParticlePacketNT(data, posX, posY, posZ), new TargetPoint(world.provider.dimensionId, posX, posY, posZ, 25));
|
||||
}
|
||||
}
|
||||
}
|
||||
111
src/main/java/api/hbm/energymk2/IEnergyReceiverMK2.java
Normal file
111
src/main/java/api/hbm/energymk2/IEnergyReceiverMK2.java
Normal file
@ -0,0 +1,111 @@
|
||||
package api.hbm.energymk2;
|
||||
|
||||
import com.hbm.interfaces.NotableComments;
|
||||
import com.hbm.packet.PacketDispatcher;
|
||||
import com.hbm.packet.toclient.AuxParticlePacketNT;
|
||||
import com.hbm.util.Compat;
|
||||
|
||||
import api.hbm.energymk2.Nodespace.PowerNode;
|
||||
import cpw.mods.fml.common.network.NetworkRegistry.TargetPoint;
|
||||
import net.minecraft.nbt.NBTTagCompound;
|
||||
import net.minecraft.tileentity.TileEntity;
|
||||
import net.minecraft.world.World;
|
||||
import net.minecraftforge.common.util.ForgeDirection;
|
||||
|
||||
/** If it receives energy, use this */
|
||||
@NotableComments
|
||||
public interface IEnergyReceiverMK2 extends IEnergyHandlerMK2 {
|
||||
|
||||
public default long transferPower(long power) {
|
||||
if(power + this.getPower() <= this.getMaxPower()) {
|
||||
this.setPower(power + this.getPower());
|
||||
return 0;
|
||||
}
|
||||
long capacity = this.getMaxPower() - this.getPower();
|
||||
long overshoot = power - capacity;
|
||||
this.setPower(this.getMaxPower());
|
||||
return overshoot;
|
||||
}
|
||||
|
||||
public default long getReceiverSpeed() {
|
||||
return this.getMaxPower();
|
||||
}
|
||||
|
||||
public default void trySubscribe(World world, int x, int y, int z, ForgeDirection dir) {
|
||||
|
||||
TileEntity te = Compat.getTileStandard(world, x, y, z);
|
||||
boolean red = false;
|
||||
|
||||
if(te instanceof IEnergyConductorMK2) {
|
||||
IEnergyConductorMK2 con = (IEnergyConductorMK2) te;
|
||||
if(!con.canConnect(dir.getOpposite())) return;
|
||||
|
||||
PowerNode node = Nodespace.getNode(world, x, y, z);
|
||||
|
||||
if(node != null && node.net != null) {
|
||||
node.net.addReceiver(this);
|
||||
red = true;
|
||||
}
|
||||
}
|
||||
|
||||
if(particleDebug) {
|
||||
NBTTagCompound data = new NBTTagCompound();
|
||||
data.setString("type", "network");
|
||||
data.setString("mode", "power");
|
||||
double posX = x + 0.5 + dir.offsetX * 0.5 + world.rand.nextDouble() * 0.5 - 0.25;
|
||||
double posY = y + 0.5 + dir.offsetY * 0.5 + world.rand.nextDouble() * 0.5 - 0.25;
|
||||
double posZ = z + 0.5 + dir.offsetZ * 0.5 + world.rand.nextDouble() * 0.5 - 0.25;
|
||||
data.setDouble("mX", -dir.offsetX * (red ? 0.025 : 0.1));
|
||||
data.setDouble("mY", -dir.offsetY * (red ? 0.025 : 0.1));
|
||||
data.setDouble("mZ", -dir.offsetZ * (red ? 0.025 : 0.1));
|
||||
PacketDispatcher.wrapper.sendToAllAround(new AuxParticlePacketNT(data, posX, posY, posZ), new TargetPoint(world.provider.dimensionId, posX, posY, posZ, 25));
|
||||
}
|
||||
}
|
||||
|
||||
public default void tryUnsubscribe(World world, int x, int y, int z) {
|
||||
|
||||
TileEntity te = world.getTileEntity(x, y, z);
|
||||
|
||||
if(te instanceof IEnergyConductorMK2) {
|
||||
IEnergyConductorMK2 con = (IEnergyConductorMK2) te;
|
||||
PowerNode node = con.createNode();
|
||||
|
||||
if(node != null && node.net != null) {
|
||||
node.net.removeReceiver(this);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Project MKUltra was an illegal human experiments program designed and undertaken by the U.S. Central Intelligence Agency (CIA)
|
||||
* to develop procedures and identify drugs that could be used during interrogations to weaken people and force confessions through
|
||||
* brainwashing and psychological torture. It began in 1953 and was halted in 1973. MKUltra used numerous methods to manipulate
|
||||
* its subjects' mental states and brain functions, such as the covert administration of high doses of psychoactive drugs (especially LSD)
|
||||
* and other chemicals without the subjects' consent, electroshocks, hypnosis, sensory deprivation, isolation, verbal and sexual
|
||||
* abuse, and other forms of torture.
|
||||
* MKUltra was preceded by Project Artichoke. It was organized through the CIA's Office of Scientific Intelligence and coordinated
|
||||
* with the United States Army Biological Warfare Laboratories. The program engaged in illegal activities, including the
|
||||
* use of U.S. and Canadian citizens as unwitting test subjects. MKUltra's scope was broad, with activities carried
|
||||
* out under the guise of research at more than 80 institutions aside from the military, including colleges and universities,
|
||||
* hospitals, prisons, and pharmaceutical companies. The CIA operated using front organizations, although some top officials at these
|
||||
* institutions were aware of the CIA's involvement.
|
||||
* MKUltra was revealed to the public in 1975 by the Church Committee of the United States Congress and Gerald Ford's United States
|
||||
* President's Commission on CIA activities within the United States (the Rockefeller Commission). Investigative efforts were hampered
|
||||
* by CIA Director Richard Helms's order that all MKUltra files be destroyed in 1973; the Church Committee and Rockefeller Commission
|
||||
* investigations relied on the sworn testimony of direct participants and on the small number of documents that survived Helms's order.
|
||||
* In 1977, a Freedom of Information Act request uncovered a cache of 20,000 documents relating to MKUltra, which led to Senate hearings.
|
||||
* Some surviving information about MKUltra was declassified in 2001.
|
||||
* */
|
||||
public default ConnectionPriority getPriority() {
|
||||
return ConnectionPriority.NORMAL;
|
||||
}
|
||||
|
||||
/** More is better-er */
|
||||
public enum ConnectionPriority {
|
||||
LOWEST,
|
||||
LOW,
|
||||
NORMAL,
|
||||
HIGH,
|
||||
HIGHEST
|
||||
}
|
||||
}
|
||||
198
src/main/java/api/hbm/energymk2/Nodespace.java
Normal file
198
src/main/java/api/hbm/energymk2/Nodespace.java
Normal file
@ -0,0 +1,198 @@
|
||||
package api.hbm.energymk2;
|
||||
|
||||
import java.util.HashMap;
|
||||
import java.util.HashSet;
|
||||
import java.util.Map.Entry;
|
||||
import java.util.Set;
|
||||
|
||||
import com.hbm.interfaces.NotableComments;
|
||||
import com.hbm.util.fauxpointtwelve.BlockPos;
|
||||
import com.hbm.util.fauxpointtwelve.DirPos;
|
||||
|
||||
import net.minecraft.server.MinecraftServer;
|
||||
import net.minecraft.world.World;
|
||||
|
||||
/**
|
||||
* The "Nodespace" is an intermediate, "ethereal" layer of abstraction that tracks nodes (i.e. cables) even when they are no longer loaded, allowing continued operation even when unloaded
|
||||
* @author hbm
|
||||
*
|
||||
*/
|
||||
public class Nodespace {
|
||||
|
||||
/** Contains all "NodeWorld" instances, i.e. lists of nodes existing per world */
|
||||
public static HashMap<World, NodeWorld> worlds = new HashMap<>();
|
||||
public static Set<PowerNetMK2> activePowerNets = new HashSet<>();
|
||||
|
||||
public static PowerNode getNode(World world, int x, int y, int z) {
|
||||
NodeWorld nodeWorld = worlds.get(world);
|
||||
if(nodeWorld != null) return nodeWorld.nodes.get(new BlockPos(x, y, z));
|
||||
return null;
|
||||
}
|
||||
|
||||
public static void createNode(World world, PowerNode node) {
|
||||
NodeWorld nodeWorld = worlds.get(world);
|
||||
if(nodeWorld == null) {
|
||||
nodeWorld = new NodeWorld();
|
||||
worlds.put(world, nodeWorld);
|
||||
}
|
||||
nodeWorld.pushNode(node);
|
||||
}
|
||||
|
||||
public static void destroyNode(World world, int x, int y, int z) {
|
||||
PowerNode node = getNode(world, x, y, z);
|
||||
if(node != null) {
|
||||
worlds.get(world).popNode(node);
|
||||
}
|
||||
}
|
||||
|
||||
/** Goes over each node and manages connections */
|
||||
public static void updateNodespace() {
|
||||
|
||||
for(World world : MinecraftServer.getServer().worldServers) {
|
||||
NodeWorld nodes = worlds.get(world);
|
||||
|
||||
if(nodes == null)
|
||||
continue;
|
||||
|
||||
for(Entry<BlockPos, PowerNode> entry : nodes.nodes.entrySet()) {
|
||||
PowerNode node = entry.getValue();
|
||||
if(!node.hasValidNet() || node.recentlyChanged) {
|
||||
checkNodeConnection(world, node);
|
||||
node.recentlyChanged = false;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
updatePowerNets();
|
||||
}
|
||||
|
||||
private static void updatePowerNets() {
|
||||
|
||||
for(PowerNetMK2 net : activePowerNets) net.resetEnergyTracker(); //reset has to be done before everything else
|
||||
for(PowerNetMK2 net : activePowerNets) net.transferPower();
|
||||
}
|
||||
|
||||
/** Goes over each connection point of the given node, tries to find neighbor nodes and to join networks with them */
|
||||
private static void checkNodeConnection(World world, PowerNode node) {
|
||||
|
||||
for(DirPos con : node.connections) {
|
||||
|
||||
PowerNode conNode = getNode(world, con.getX(), con.getY(), con.getZ()); // get whatever neighbor node intersects with that connection
|
||||
|
||||
if(conNode != null) { // if there is a node at that place
|
||||
|
||||
if(conNode.hasValidNet() && conNode.net == node.net) continue; // if the net is valid and both nodes have the same net, skip
|
||||
|
||||
if(checkConnection(conNode, con, false)) {
|
||||
connectToNode(node, conNode);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if(node.net == null || !node.net.isValid()) new PowerNetMK2().joinLink(node);
|
||||
}
|
||||
|
||||
public static boolean checkConnection(PowerNode connectsTo, DirPos connectFrom, boolean skipSideCheck) {
|
||||
|
||||
for(DirPos revCon : connectsTo.connections) {
|
||||
|
||||
if(revCon.getX() - revCon.getDir().offsetX == connectFrom.getX() && revCon.getY() - revCon.getDir().offsetY == connectFrom.getY() && revCon.getZ() - revCon.getDir().offsetZ == connectFrom.getZ() && (revCon.getDir() == connectFrom.getDir().getOpposite() || skipSideCheck)) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
/** Links two nodes with different or potentially no networks */
|
||||
private static void connectToNode(PowerNode origin, PowerNode connection) {
|
||||
|
||||
if(origin.hasValidNet() && connection.hasValidNet()) { // both nodes have nets, but the nets are different (previous assumption), join networks
|
||||
if(origin.net.links.size() > connection.net.links.size()) {
|
||||
origin.net.joinNetworks(connection.net);
|
||||
} else {
|
||||
connection.net.joinNetworks(origin.net);
|
||||
}
|
||||
} else if(!origin.hasValidNet() && connection.hasValidNet()) { // origin has no net, connection does, have origin join connection's net
|
||||
connection.net.joinLink(origin);
|
||||
} else if(origin.hasValidNet() && !connection.hasValidNet()) { // ...and vice versa
|
||||
origin.net.joinLink(connection);
|
||||
}
|
||||
}
|
||||
|
||||
public static class NodeWorld {
|
||||
|
||||
/** Contains a map showing where each node is, a node is every spot that a cable exists at.
|
||||
* Instead of the old proxy system, things like substation now create multiple nodes at their connection points */
|
||||
public HashMap<BlockPos, PowerNode> nodes = new HashMap<>();
|
||||
|
||||
/** Adds a node at all its positions to the nodespace */
|
||||
public void pushNode(PowerNode node) {
|
||||
for(BlockPos pos : node.positions) {
|
||||
nodes.put(pos, node);
|
||||
}
|
||||
}
|
||||
|
||||
/** Removes the specified node from all positions from nodespace */
|
||||
public void popNode(PowerNode node) {
|
||||
if(node.net != null) node.net.destroy();
|
||||
for(BlockPos pos : node.positions) {
|
||||
nodes.remove(pos);
|
||||
node.expired = true;
|
||||
}
|
||||
}
|
||||
|
||||
/** Grabs the node at one position, then removes it from all positions it occupies */
|
||||
public void popNode(BlockPos pos) {
|
||||
PowerNode node = nodes.get(pos);
|
||||
if(node != null) popNode(node);
|
||||
}
|
||||
}
|
||||
|
||||
@NotableComments
|
||||
public static class PowerNode {
|
||||
|
||||
public BlockPos[] positions;
|
||||
public DirPos[] connections;
|
||||
public PowerNetMK2 net;
|
||||
public boolean expired = false;
|
||||
/**
|
||||
* Okay so here's the deal: The code has shit idiot brain fungus. I don't know why. I re-tested every part involved several times.
|
||||
* I don't know why. But for some reason, during neighbor checks, on certain arbitrary fucking places, the joining operation just fails.
|
||||
* Disallowing nodes to create new networks fixed the problem completely, which is hardly surprising since they wouldn't be able to make
|
||||
* a new net anyway and they will re-check neighbors until a net is found, so the solution is tautological in nature. So I tried limiting
|
||||
* creation of new networks. Didn't work. So what's there left to do? Hand out a mark to any node that has changed networks, and let those
|
||||
* recently modified nodes do another re-check. This creates a second layer of redundant operations, and in theory doubles (in practice,
|
||||
* it might be an extra 20% due to break-off section sizes) the amount of CPU time needed for re-building the networks after joining or
|
||||
* breaking, but it seems to allow those parts to connect back to their neighbor nets as they are supposed to. I am not proud of this solution,
|
||||
* this issue shouldn't exist to begin with and I am going fucking insane but it is what it is.
|
||||
*/
|
||||
public boolean recentlyChanged = true;
|
||||
|
||||
public PowerNode(BlockPos... positions) {
|
||||
this.positions = positions;
|
||||
}
|
||||
|
||||
public PowerNode setConnections(DirPos... connections) {
|
||||
this.connections = connections;
|
||||
return this;
|
||||
}
|
||||
|
||||
public PowerNode addConnection(DirPos connection) {
|
||||
DirPos[] newCons = new DirPos[this.connections.length + 1];
|
||||
for(int i = 0; i < this.connections.length; i++) newCons[i] = this.connections[i];
|
||||
newCons[newCons.length - 1] = connection;
|
||||
this.connections = newCons;
|
||||
return this;
|
||||
}
|
||||
|
||||
public boolean hasValidNet() {
|
||||
return this.net != null && this.net.isValid();
|
||||
}
|
||||
|
||||
public void setNet(PowerNetMK2 net) {
|
||||
this.net = net;
|
||||
this.recentlyChanged = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
363
src/main/java/api/hbm/energymk2/PowerNetMK2.java
Normal file
363
src/main/java/api/hbm/energymk2/PowerNetMK2.java
Normal file
@ -0,0 +1,363 @@
|
||||
package api.hbm.energymk2;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Comparator;
|
||||
import java.util.HashMap;
|
||||
import java.util.HashSet;
|
||||
import java.util.Iterator;
|
||||
import java.util.List;
|
||||
import java.util.Set;
|
||||
|
||||
import com.hbm.util.Tuple.Pair;
|
||||
|
||||
import java.util.Map.Entry;
|
||||
import java.util.Random;
|
||||
|
||||
import api.hbm.energymk2.IEnergyReceiverMK2.ConnectionPriority;
|
||||
import api.hbm.energymk2.Nodespace.PowerNode;
|
||||
|
||||
public class PowerNetMK2 {
|
||||
|
||||
public static Random rand = new Random();
|
||||
public boolean valid = true;
|
||||
public Set<PowerNode> links = new HashSet();
|
||||
|
||||
/** Maps all active subscribers to a timestamp, handy for handling timeouts. In a good system this shouldn't be necessary, but the previous system taught me to be cautious anyway */
|
||||
public HashMap<IEnergyReceiverMK2, Long> receiverEntries = new HashMap();
|
||||
public HashMap<IEnergyProviderMK2, Long> providerEntries = new HashMap();
|
||||
|
||||
public long energyTracker = 0L;
|
||||
|
||||
public PowerNetMK2() {
|
||||
Nodespace.activePowerNets.add(this);
|
||||
}
|
||||
|
||||
/// SUBSCRIBER HANDLING ///
|
||||
public boolean isSubscribed(IEnergyReceiverMK2 receiver) {
|
||||
return this.receiverEntries.containsKey(receiver);
|
||||
}
|
||||
|
||||
public void addReceiver(IEnergyReceiverMK2 receiver) {
|
||||
this.receiverEntries.put(receiver, System.currentTimeMillis());
|
||||
}
|
||||
|
||||
public void removeReceiver(IEnergyReceiverMK2 receiver) {
|
||||
this.receiverEntries.remove(receiver);
|
||||
}
|
||||
|
||||
/// PROVIDER HANDLING ///
|
||||
public boolean isProvider(IEnergyProviderMK2 provider) {
|
||||
return this.providerEntries.containsKey(provider);
|
||||
}
|
||||
|
||||
public void addProvider(IEnergyProviderMK2 provider) {
|
||||
this.providerEntries.put(provider, System.currentTimeMillis());
|
||||
}
|
||||
|
||||
public void removeProvider(IEnergyProviderMK2 provider) {
|
||||
this.providerEntries.remove(provider);
|
||||
}
|
||||
|
||||
/// LINK JOINING ///
|
||||
|
||||
/** Combines two networks into one */
|
||||
public void joinNetworks(PowerNetMK2 network) {
|
||||
|
||||
if(network == this) return; //wtf?!
|
||||
|
||||
List<PowerNode> oldNodes = new ArrayList(network.links.size());
|
||||
oldNodes.addAll(network.links); // might prevent oddities related to joining - nvm it does nothing
|
||||
|
||||
for(PowerNode conductor : oldNodes) forceJoinLink(conductor);
|
||||
network.links.clear();
|
||||
|
||||
for(IEnergyReceiverMK2 connector : network.receiverEntries.keySet()) this.addReceiver(connector);
|
||||
for(IEnergyProviderMK2 connector : network.providerEntries.keySet()) this.addProvider(connector);
|
||||
network.destroy();
|
||||
}
|
||||
|
||||
/** Adds the power node as part of this network's links */
|
||||
public PowerNetMK2 joinLink(PowerNode node) {
|
||||
if(node.net != null) node.net.leaveLink(node);
|
||||
return forceJoinLink(node);
|
||||
}
|
||||
|
||||
/** Adds the power node as part of this network's links, skips the part about removing it from existing networks */
|
||||
public PowerNetMK2 forceJoinLink(PowerNode node) {
|
||||
this.links.add(node);
|
||||
node.setNet(this);
|
||||
return this;
|
||||
}
|
||||
|
||||
/** Removes the specified power node */
|
||||
public void leaveLink(PowerNode node) {
|
||||
node.setNet(null);
|
||||
this.links.remove(node);
|
||||
}
|
||||
|
||||
/// GENERAL POWER NET CONTROL ///
|
||||
public void invalidate() {
|
||||
this.valid = false;
|
||||
Nodespace.activePowerNets.remove(this);
|
||||
}
|
||||
|
||||
public boolean isValid() {
|
||||
return this.valid;
|
||||
}
|
||||
|
||||
public void destroy() {
|
||||
this.invalidate();
|
||||
for(PowerNode link : this.links) if(link.net == this) link.setNet(null);
|
||||
this.links.clear();
|
||||
this.receiverEntries.clear();
|
||||
this.providerEntries.clear();
|
||||
}
|
||||
|
||||
public void resetEnergyTracker() {
|
||||
this.energyTracker = 0;
|
||||
}
|
||||
|
||||
protected static int timeout = 3_000;
|
||||
|
||||
public void transferPower() {
|
||||
|
||||
if(providerEntries.isEmpty()) return;
|
||||
if(receiverEntries.isEmpty()) return;
|
||||
|
||||
long timestamp = System.currentTimeMillis();
|
||||
|
||||
List<Pair<IEnergyProviderMK2, Long>> providers = new ArrayList();
|
||||
long powerAvailable = 0;
|
||||
|
||||
Iterator<Entry<IEnergyProviderMK2, Long>> provIt = providerEntries.entrySet().iterator();
|
||||
while(provIt.hasNext()) {
|
||||
Entry<IEnergyProviderMK2, Long> entry = provIt.next();
|
||||
if(timestamp - entry.getValue() > timeout) { provIt.remove(); continue; }
|
||||
long src = Math.min(entry.getKey().getPower(), entry.getKey().getProviderSpeed());
|
||||
providers.add(new Pair(entry.getKey(), src));
|
||||
powerAvailable += src;
|
||||
}
|
||||
|
||||
List<Pair<IEnergyReceiverMK2, Long>>[] receivers = new ArrayList[ConnectionPriority.values().length];
|
||||
for(int i = 0; i < receivers.length; i++) receivers[i] = new ArrayList();
|
||||
long[] demand = new long[ConnectionPriority.values().length];
|
||||
long totalDemand = 0;
|
||||
|
||||
Iterator<Entry<IEnergyReceiverMK2, Long>> recIt = receiverEntries.entrySet().iterator();
|
||||
|
||||
while(recIt.hasNext()) {
|
||||
Entry<IEnergyReceiverMK2, Long> entry = recIt.next();
|
||||
if(timestamp - entry.getValue() > timeout) { recIt.remove(); continue; }
|
||||
long rec = Math.min(entry.getKey().getMaxPower() - entry.getKey().getPower(), entry.getKey().getReceiverSpeed());
|
||||
int p = entry.getKey().getPriority().ordinal();
|
||||
receivers[p].add(new Pair(entry.getKey(), rec));
|
||||
demand[p] += rec;
|
||||
totalDemand += rec;
|
||||
}
|
||||
|
||||
long toTransfer = Math.min(powerAvailable, totalDemand);
|
||||
long energyUsed = 0;
|
||||
|
||||
for(int i = ConnectionPriority.values().length - 1; i >= 0; i--) {
|
||||
List<Pair<IEnergyReceiverMK2, Long>> list = receivers[i];
|
||||
long priorityDemand = demand[i];
|
||||
|
||||
for(Pair<IEnergyReceiverMK2, Long> entry : list) {
|
||||
double weight = (double) entry.getValue() / (double) (priorityDemand);
|
||||
long toSend = (long) Math.max(toTransfer * weight, 0D);
|
||||
energyUsed += (toSend - entry.getKey().transferPower(toSend)); //leftovers are subtracted from the intended amount to use up
|
||||
}
|
||||
|
||||
toTransfer -= energyUsed;
|
||||
}
|
||||
|
||||
this.energyTracker += energyUsed;
|
||||
long leftover = energyUsed;
|
||||
|
||||
for(Pair<IEnergyProviderMK2, Long> entry : providers) {
|
||||
double weight = (double) entry.getValue() / (double) powerAvailable;
|
||||
long toUse = (long) Math.max(energyUsed * weight, 0D);
|
||||
entry.getKey().usePower(toUse);
|
||||
leftover -= toUse;
|
||||
}
|
||||
|
||||
//rounding error compensation, detects surplus that hasn't been used and removes it from random providers
|
||||
int iterationsLeft = 100; // whiles without emergency brakes are a bad idea
|
||||
while(iterationsLeft > 0 && leftover > 0 && providers.size() > 0) {
|
||||
iterationsLeft--;
|
||||
|
||||
Pair<IEnergyProviderMK2, Long> selected = providers.get(rand.nextInt(providers.size()));
|
||||
IEnergyProviderMK2 scapegoat = selected.getKey();
|
||||
|
||||
long toUse = Math.min(leftover, scapegoat.getPower());
|
||||
scapegoat.usePower(toUse);
|
||||
leftover -= toUse;
|
||||
}
|
||||
}
|
||||
|
||||
@Deprecated public void transferPowerOld() {
|
||||
|
||||
if(providerEntries.isEmpty()) return;
|
||||
if(receiverEntries.isEmpty()) return;
|
||||
|
||||
long timestamp = System.currentTimeMillis();
|
||||
long transferCap = 100_000_000_000_000_00L; // that ought to be enough
|
||||
|
||||
long supply = 0;
|
||||
long demand = 0;
|
||||
long[] priorityDemand = new long[ConnectionPriority.values().length];
|
||||
|
||||
Iterator<Entry<IEnergyProviderMK2, Long>> provIt = providerEntries.entrySet().iterator();
|
||||
while(provIt.hasNext()) {
|
||||
Entry<IEnergyProviderMK2, Long> entry = provIt.next();
|
||||
if(timestamp - entry.getValue() > timeout) { provIt.remove(); continue; }
|
||||
supply += Math.min(entry.getKey().getPower(), entry.getKey().getProviderSpeed());
|
||||
}
|
||||
|
||||
if(supply <= 0) return;
|
||||
|
||||
Iterator<Entry<IEnergyReceiverMK2, Long>> recIt = receiverEntries.entrySet().iterator();
|
||||
while(recIt.hasNext()) {
|
||||
Entry<IEnergyReceiverMK2, Long> entry = recIt.next();
|
||||
if(timestamp - entry.getValue() > timeout) { recIt.remove(); continue; }
|
||||
long rec = Math.min(entry.getKey().getMaxPower() - entry.getKey().getPower(), entry.getKey().getReceiverSpeed());
|
||||
demand += rec;
|
||||
for(int i = 0; i <= entry.getKey().getPriority().ordinal(); i++) priorityDemand[i] += rec;
|
||||
}
|
||||
|
||||
if(demand <= 0) return;
|
||||
|
||||
long toTransfer = Math.min(supply, demand);
|
||||
if(toTransfer > transferCap) toTransfer = transferCap;
|
||||
if(toTransfer <= 0) return;
|
||||
|
||||
List<IEnergyProviderMK2> buffers = new ArrayList();
|
||||
List<IEnergyProviderMK2> providers = new ArrayList();
|
||||
Set<IEnergyReceiverMK2> receiverSet = receiverEntries.keySet();
|
||||
for(IEnergyProviderMK2 provider : providerEntries.keySet()) {
|
||||
if(receiverSet.contains(provider)) {
|
||||
buffers.add(provider);
|
||||
} else {
|
||||
providers.add(provider);
|
||||
}
|
||||
}
|
||||
providers.addAll(buffers); //makes buffers go last
|
||||
List<IEnergyReceiverMK2> receivers = new ArrayList() {{ addAll(receiverSet); }};
|
||||
|
||||
receivers.sort(COMP);
|
||||
|
||||
int maxIteration = 1000;
|
||||
|
||||
//how much the current sender/receiver have already sent/received
|
||||
long prevSrc = 0;
|
||||
long prevDest = 0;
|
||||
|
||||
while(!receivers.isEmpty() && !providers.isEmpty() && maxIteration > 0) {
|
||||
maxIteration--;
|
||||
|
||||
IEnergyProviderMK2 src = providers.get(0);
|
||||
IEnergyReceiverMK2 dest = receivers.get(0);
|
||||
|
||||
if(src.getPower() <= 0) { providers.remove(0); prevSrc = 0; continue; }
|
||||
|
||||
if(src == dest) { // STALEMATE DETECTED
|
||||
//if this happens, a buffer will waste both its share of transfer and receiving potential and do effectively nothing, essentially breaking
|
||||
|
||||
//try if placing the conflicting provider at the end of the list does anything
|
||||
//we do this first because providers have no priority, so we may shuffle those around as much as we want
|
||||
if(providers.size() > 1) {
|
||||
providers.add(providers.get(0));
|
||||
providers.remove(0);
|
||||
prevSrc = 0; //this might cause slight issues due to the tracking being effectively lost while there still might be pending operations
|
||||
continue;
|
||||
}
|
||||
//if that didn't work, try shifting the receiver by one place (to minimize priority breakage)
|
||||
if(receivers.size() > 1) {
|
||||
receivers.add(2, receivers.get(0));
|
||||
receivers.remove(0);
|
||||
prevDest = 0; //ditto
|
||||
continue;
|
||||
}
|
||||
|
||||
//if neither option could be performed, the only conclusion is that this buffer mode battery is alone in the power net, in which case: not my provlem
|
||||
}
|
||||
|
||||
long pd = priorityDemand[dest.getPriority().ordinal()];
|
||||
|
||||
long receiverShare = Math.min((long) Math.ceil((double) Math.min(dest.getMaxPower() - dest.getPower(), dest.getReceiverSpeed()) * (double) supply / (double) pd), dest.getReceiverSpeed()) - prevDest;
|
||||
long providerShare = Math.min((long) Math.ceil((double) Math.min(src.getPower(), src.getProviderSpeed()) * (double) demand / (double) supply), src.getProviderSpeed()) - prevSrc;
|
||||
|
||||
long toDrain = Math.min((long) (src.getPower()), providerShare);
|
||||
long toFill = Math.min(dest.getMaxPower() - dest.getPower(), receiverShare);
|
||||
|
||||
long finalTransfer = Math.min(toDrain, toFill);
|
||||
if(toFill <= 0) { receivers.remove(0); prevDest = 0; continue; }
|
||||
|
||||
finalTransfer -= dest.transferPower(finalTransfer);
|
||||
src.usePower(finalTransfer);
|
||||
|
||||
prevSrc += finalTransfer;
|
||||
prevDest += finalTransfer;
|
||||
|
||||
if(prevSrc >= src.getProviderSpeed()) { providers.remove(0); prevSrc = 0; continue; }
|
||||
if(prevDest >= dest.getReceiverSpeed()) { receivers.remove(0); prevDest = 0; continue; }
|
||||
|
||||
toTransfer -= finalTransfer;
|
||||
this.energyTracker += finalTransfer;
|
||||
}
|
||||
}
|
||||
|
||||
public long sendPowerDiode(long power) {
|
||||
|
||||
if(receiverEntries.isEmpty()) return power;
|
||||
|
||||
long timestamp = System.currentTimeMillis();
|
||||
|
||||
List<Pair<IEnergyReceiverMK2, Long>>[] receivers = new ArrayList[ConnectionPriority.values().length];
|
||||
for(int i = 0; i < receivers.length; i++) receivers[i] = new ArrayList();
|
||||
long[] demand = new long[ConnectionPriority.values().length];
|
||||
long totalDemand = 0;
|
||||
|
||||
Iterator<Entry<IEnergyReceiverMK2, Long>> recIt = receiverEntries.entrySet().iterator();
|
||||
|
||||
while(recIt.hasNext()) {
|
||||
Entry<IEnergyReceiverMK2, Long> entry = recIt.next();
|
||||
if(timestamp - entry.getValue() > timeout) { recIt.remove(); continue; }
|
||||
long rec = Math.min(entry.getKey().getMaxPower() - entry.getKey().getPower(), entry.getKey().getReceiverSpeed());
|
||||
int p = entry.getKey().getPriority().ordinal();
|
||||
receivers[p].add(new Pair(entry.getKey(), rec));
|
||||
demand[p] += rec;
|
||||
totalDemand += rec;
|
||||
}
|
||||
|
||||
long toTransfer = Math.min(power, totalDemand);
|
||||
long energyUsed = 0;
|
||||
|
||||
for(int i = ConnectionPriority.values().length - 1; i >= 0; i--) {
|
||||
List<Pair<IEnergyReceiverMK2, Long>> list = receivers[i];
|
||||
long priorityDemand = demand[i];
|
||||
|
||||
for(Pair<IEnergyReceiverMK2, Long> entry : list) {
|
||||
double weight = (double) entry.getValue() / (double) (priorityDemand);
|
||||
long toSend = (long) Math.max(toTransfer * weight, 0D);
|
||||
energyUsed += (toSend - entry.getKey().transferPower(toSend)); //leftovers are subtracted from the intended amount to use up
|
||||
}
|
||||
|
||||
toTransfer -= energyUsed;
|
||||
}
|
||||
|
||||
this.energyTracker += energyUsed;
|
||||
|
||||
return power - energyUsed;
|
||||
}
|
||||
|
||||
public static final ReceiverComparator COMP = new ReceiverComparator();
|
||||
|
||||
public static class ReceiverComparator implements Comparator<IEnergyReceiverMK2> {
|
||||
|
||||
@Override
|
||||
public int compare(IEnergyReceiverMK2 o1, IEnergyReceiverMK2 o2) {
|
||||
return o2.getPriority().ordinal() - o1.getPriority().ordinal();
|
||||
}
|
||||
}
|
||||
}
|
||||
33
src/main/java/api/hbm/energymk2/package-info.java
Normal file
33
src/main/java/api/hbm/energymk2/package-info.java
Normal file
@ -0,0 +1,33 @@
|
||||
/**
|
||||
*
|
||||
*/
|
||||
/**
|
||||
* @author hbm
|
||||
*
|
||||
*/
|
||||
package api.hbm.energymk2;
|
||||
|
||||
// i have snorted two lines of pure caffeine and taken one large paracetamol laced with even more caffine, let's fucking go
|
||||
|
||||
//most of the new classes are just copy pasted mashed up shit from yesteryear, what a productive segment that was
|
||||
|
||||
/*
|
||||
|
||||
before my caffine high ends entirely and i black out, here's the gist:
|
||||
* diodes are handled like energy receiver and simply chain-load the power net they output into in a recursive function, this might be a bit laggy compared to the rest of the system, but it's still way less laggy than the old one
|
||||
* instead of power nets being bound to tile entities directly, tiles spawn ethereal "nodes" similar to the drone waypoints which can be saved using world data, meaning that breaking cables will delete nodes, but unloading them will keep them alive in "node space" which is what's actually used to check for connections
|
||||
* power nets may cache some positional info in order to limit the amount of nodes, this should prevent horrific freezes in the unlikely event that some retard makes a superflat world out of cables
|
||||
* general energy transmission will work in a similar fashion as martin explained his, but somewhat simplified; the system will determine supply and demand and then split those evenly if possible, retrying within one operation is only necessary for minor restrictions like priority, any leftovers from rounding don't have to be re-tried because the next tick will already take care of that
|
||||
* invest funds in more coal mare nudes
|
||||
* battery "fair share" transfer will most likely no longer work, but that's not really as relevant these days considering there's capacitors and because batteries have transfer speed limits anyway
|
||||
* most of the machine's functions will be repurposed, the "sendPower" method will no longer send power directly but register the machine to the network as a power source
|
||||
* if all else fails and martin still hasn't surrendered his code, i will beg greg for his wisdom (but without loss or tiering because fuck that)
|
||||
*
|
||||
* | | ||
|
||||
* ____|____
|
||||
* |
|
||||
* || | |_
|
||||
*
|
||||
* ...i said WITHOUT loss
|
||||
|
||||
*/
|
||||
@ -1,5 +1,6 @@
|
||||
package api.hbm.entity;
|
||||
|
||||
@Deprecated //Use IRadarDetectableNT instead, old interface will still work though
|
||||
public interface IRadarDetectable {
|
||||
|
||||
public static enum RadarTargetType {
|
||||
@ -15,7 +16,7 @@ public interface IRadarDetectable {
|
||||
MISSILE_20("Size 20 Custom Missile"), //size 20 custom missiles
|
||||
MISSILE_AB("Anti-Ballistic Missile"), //anti ballistic missile
|
||||
PLAYER("Player"), //airborne players
|
||||
ARTILLERY("Artillery Shell"); //airborne players
|
||||
ARTILLERY("Artillery Shell"); //artillery shells
|
||||
|
||||
public String name;
|
||||
|
||||
|
||||
45
src/main/java/api/hbm/entity/IRadarDetectableNT.java
Normal file
45
src/main/java/api/hbm/entity/IRadarDetectableNT.java
Normal file
@ -0,0 +1,45 @@
|
||||
package api.hbm.entity;
|
||||
|
||||
public interface IRadarDetectableNT {
|
||||
|
||||
public static final int TIER0 = 0;
|
||||
public static final int TIER1 = 1;
|
||||
public static final int TIER2 = 2;
|
||||
public static final int TIER3 = 3;
|
||||
public static final int TIER4 = 4;
|
||||
public static final int TIER10 = 5;
|
||||
public static final int TIER10_15 = 6;
|
||||
public static final int TIER15 = 7;
|
||||
public static final int TIER15_20 = 8;
|
||||
public static final int TIER20 = 9;
|
||||
public static final int TIER_AB = 10;
|
||||
public static final int PLAYER = 11;
|
||||
public static final int ARTY = 12;
|
||||
/** Reserved type that shows a unique purple blip. Used for when nothing else applies. */
|
||||
public static final int SPECIAL = 13;
|
||||
|
||||
/** Name use for radar display, uses I18n for lookup */
|
||||
public String getUnlocalizedName();
|
||||
/** The type of dot to show on the radar as well as the redstone level in tier mode */
|
||||
public int getBlipLevel();
|
||||
/** Whether the object can be seen by this type of radar */
|
||||
public boolean canBeSeenBy(Object radar);
|
||||
/** Whether the object is currently visible, as well as whether the radar's setting allow for picking this up */
|
||||
public boolean paramsApplicable(RadarScanParams params);
|
||||
/** Whether this radar entry should be counted for the redstone output */
|
||||
public boolean suppliesRedstone(RadarScanParams params);
|
||||
|
||||
public static class RadarScanParams {
|
||||
public boolean scanMissiles = true;
|
||||
public boolean scanShells = true;
|
||||
public boolean scanPlayers = true;
|
||||
public boolean smartMode = true;
|
||||
|
||||
public RadarScanParams(boolean m, boolean s, boolean p, boolean smart) {
|
||||
this.scanMissiles = m;
|
||||
this.scanShells = s;
|
||||
this.scanPlayers = p;
|
||||
this.smartMode = smart;
|
||||
}
|
||||
}
|
||||
}
|
||||
16
src/main/java/api/hbm/entity/IResistanceProvider.java
Normal file
16
src/main/java/api/hbm/entity/IResistanceProvider.java
Normal file
@ -0,0 +1,16 @@
|
||||
package api.hbm.entity;
|
||||
|
||||
import net.minecraft.util.DamageSource;
|
||||
|
||||
/**
|
||||
* Allows custom entities to specify threshold and resistance values based on incoming damage, type and piercing values, along with whatever other internal stats
|
||||
* the entity has (like glyphid armor). Obviously only works for our own custom entities implementing this, everything else will have to work with the less powerful
|
||||
* (but still very useful) entity stats in the DamageResistanceHandler.
|
||||
*
|
||||
* @author hbm
|
||||
*/
|
||||
public interface IResistanceProvider {
|
||||
|
||||
public float[] getCurrentDTDR(DamageSource damage, float amount, float pierceDT, float pierce);
|
||||
public void onDamageDealt(DamageSource damage, float amount);
|
||||
}
|
||||
66
src/main/java/api/hbm/entity/RadarEntry.java
Normal file
66
src/main/java/api/hbm/entity/RadarEntry.java
Normal file
@ -0,0 +1,66 @@
|
||||
package api.hbm.entity;
|
||||
|
||||
import cpw.mods.fml.common.network.ByteBufUtils;
|
||||
import io.netty.buffer.ByteBuf;
|
||||
import net.minecraft.entity.Entity;
|
||||
import net.minecraft.entity.player.EntityPlayer;
|
||||
|
||||
public class RadarEntry {
|
||||
|
||||
/** Name use for radar display, uses I18n for lookup */
|
||||
public String unlocalizedName;
|
||||
/** The type of dot to show on the radar as well as the redstone level in tier mode */
|
||||
public int blipLevel;
|
||||
public int posX;
|
||||
public int posY;
|
||||
public int posZ;
|
||||
public int dim;
|
||||
public int entityID;
|
||||
/** Whether this radar entry should be counted for the redstone output */
|
||||
public boolean redstone;
|
||||
|
||||
public RadarEntry() { } //blank ctor for packets
|
||||
|
||||
public RadarEntry(String name, int level, int x, int y, int z, int dim, int entityID, boolean redstone) {
|
||||
this.unlocalizedName = name;
|
||||
this.blipLevel = level;
|
||||
this.posX = x;
|
||||
this.posY = y;
|
||||
this.posZ = z;
|
||||
this.dim = dim;
|
||||
this.entityID = entityID;
|
||||
this.redstone = redstone;
|
||||
}
|
||||
|
||||
public RadarEntry(IRadarDetectableNT detectable, Entity entity, boolean redstone) {
|
||||
this(detectable.getUnlocalizedName(), detectable.getBlipLevel(), (int) Math.floor(entity.posX), (int) Math.floor(entity.posY), (int) Math.floor(entity.posZ), entity.dimension, entity.getEntityId(), redstone);
|
||||
}
|
||||
|
||||
public RadarEntry(IRadarDetectable detectable, Entity entity) {
|
||||
this(detectable.getTargetType().name, detectable.getTargetType().ordinal(), (int) Math.floor(entity.posX), (int) Math.floor(entity.posY), (int) Math.floor(entity.posZ), entity.dimension, entity.getEntityId(), entity.motionY < 0);
|
||||
}
|
||||
|
||||
public RadarEntry(EntityPlayer player) {
|
||||
this(player.getDisplayName(), IRadarDetectableNT.PLAYER, (int) Math.floor(player.posX), (int) Math.floor(player.posY), (int) Math.floor(player.posZ), player.dimension, player.getEntityId(), true);
|
||||
}
|
||||
|
||||
public void fromBytes(ByteBuf buf) {
|
||||
this.unlocalizedName = ByteBufUtils.readUTF8String(buf);
|
||||
this.blipLevel = buf.readShort();
|
||||
this.posX = buf.readInt();
|
||||
this.posY = buf.readInt();
|
||||
this.posZ = buf.readInt();
|
||||
this.dim = buf.readShort();
|
||||
this.entityID = buf.readInt();
|
||||
}
|
||||
|
||||
public void toBytes(ByteBuf buf) {
|
||||
ByteBufUtils.writeUTF8String(buf, this.unlocalizedName);
|
||||
buf.writeShort(this.blipLevel);
|
||||
buf.writeInt(this.posX);
|
||||
buf.writeInt(this.posY);
|
||||
buf.writeInt(this.posZ);
|
||||
buf.writeShort(this.dim);
|
||||
buf.writeInt(this.entityID);
|
||||
}
|
||||
}
|
||||
@ -14,4 +14,8 @@ public interface IFillableItem {
|
||||
public boolean providesFluid(FluidType type, ItemStack stack);
|
||||
/** Provides fluid with the maximum being the requested amount */
|
||||
public int tryEmpty(FluidType type, int amount, ItemStack stack);
|
||||
/** Returns the first (or only) corrently held type, may return null. Currently only used for setting bedrock ores */
|
||||
public FluidType getFirstFluidType(ItemStack stack);
|
||||
/** Returns the fillstate for the specified fluid. Currently only used for setting bedrock ores */
|
||||
public int getFill(ItemStack stack);
|
||||
}
|
||||
|
||||
@ -1,16 +1,18 @@
|
||||
package api.hbm.fluid;
|
||||
|
||||
import com.hbm.inventory.fluid.FluidType;
|
||||
import com.hbm.packet.AuxParticlePacketNT;
|
||||
import com.hbm.packet.PacketDispatcher;
|
||||
import com.hbm.packet.toclient.AuxParticlePacketNT;
|
||||
import com.hbm.util.Compat;
|
||||
|
||||
import api.hbm.tile.ILoadedTile;
|
||||
import cpw.mods.fml.common.network.NetworkRegistry.TargetPoint;
|
||||
import net.minecraft.nbt.NBTTagCompound;
|
||||
import net.minecraft.tileentity.TileEntity;
|
||||
import net.minecraft.world.World;
|
||||
import net.minecraftforge.common.util.ForgeDirection;
|
||||
|
||||
public interface IFluidConnector {
|
||||
public interface IFluidConnector extends ILoadedTile {
|
||||
|
||||
/**
|
||||
* Returns the amount of fluid that remains
|
||||
@ -44,7 +46,7 @@ public interface IFluidConnector {
|
||||
*/
|
||||
public default void trySubscribe(FluidType type, World world, int x, int y, int z, ForgeDirection dir) {
|
||||
|
||||
TileEntity te = world.getTileEntity(x, y, z);
|
||||
TileEntity te = Compat.getTileStandard(world, x, y, z);
|
||||
boolean red = false;
|
||||
|
||||
if(te instanceof IFluidConductor) {
|
||||
|
||||
@ -2,8 +2,9 @@ package api.hbm.fluid;
|
||||
|
||||
import com.hbm.inventory.fluid.FluidType;
|
||||
import com.hbm.inventory.fluid.tank.FluidTank;
|
||||
import com.hbm.packet.AuxParticlePacketNT;
|
||||
import com.hbm.packet.PacketDispatcher;
|
||||
import com.hbm.packet.toclient.AuxParticlePacketNT;
|
||||
import com.hbm.util.Compat;
|
||||
|
||||
import cpw.mods.fml.common.network.NetworkRegistry.TargetPoint;
|
||||
import net.minecraft.nbt.NBTTagCompound;
|
||||
@ -37,8 +38,11 @@ public interface IFluidUser extends IFluidConnector {
|
||||
|
||||
if(con.canConnect(type, dir.getOpposite())) {
|
||||
long toSend = this.getTotalFluidForSend(type, pressure);
|
||||
long transfer = toSend - con.transferFluid(type, pressure, toSend);
|
||||
this.removeFluidForTransfer(type, pressure, transfer);
|
||||
|
||||
if(toSend > 0) {
|
||||
long transfer = toSend - con.transferFluid(type, pressure, toSend);
|
||||
this.removeFluidForTransfer(type, pressure, transfer);
|
||||
}
|
||||
red = true;
|
||||
}
|
||||
}
|
||||
@ -68,7 +72,7 @@ public interface IFluidUser extends IFluidConnector {
|
||||
|
||||
public static IPipeNet getPipeNet(World world, int x, int y, int z, FluidType type) {
|
||||
|
||||
TileEntity te = world.getTileEntity(x, y, z);
|
||||
TileEntity te = Compat.getTileStandard(world, x, y, z);
|
||||
|
||||
if(te instanceof IFluidConductor) {
|
||||
IFluidConductor con = (IFluidConductor) te;
|
||||
|
||||
@ -15,17 +15,18 @@ public class PipeNet implements IPipeNet {
|
||||
private FluidType type;
|
||||
private List<IFluidConductor> links = new ArrayList();
|
||||
private HashSet<IFluidConnector> subscribers = new HashSet();
|
||||
|
||||
|
||||
public static List<PipeNet> trackingInstances = null;
|
||||
protected BigInteger totalTransfer = BigInteger.ZERO;
|
||||
|
||||
public List<String> debug = new ArrayList();
|
||||
|
||||
public PipeNet(FluidType type) {
|
||||
this.type = type;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void joinNetworks(IPipeNet network) {
|
||||
|
||||
|
||||
if(network == this)
|
||||
return;
|
||||
|
||||
@ -34,11 +35,11 @@ public class PipeNet implements IPipeNet {
|
||||
this.getLinks().add(conductor);
|
||||
}
|
||||
network.getLinks().clear();
|
||||
|
||||
|
||||
for(IFluidConnector connector : network.getSubscribers()) {
|
||||
this.subscribe(connector);
|
||||
}
|
||||
|
||||
|
||||
network.destroy();
|
||||
}
|
||||
|
||||
@ -54,10 +55,10 @@ public class PipeNet implements IPipeNet {
|
||||
|
||||
@Override
|
||||
public IPipeNet joinLink(IFluidConductor conductor) {
|
||||
|
||||
|
||||
if(conductor.getPipeNet(type) != null)
|
||||
conductor.getPipeNet(type).leaveLink(conductor);
|
||||
|
||||
|
||||
conductor.setPipeNet(type, this);
|
||||
this.links.add(conductor);
|
||||
return this;
|
||||
@ -86,54 +87,75 @@ public class PipeNet implements IPipeNet {
|
||||
|
||||
@Override
|
||||
public long transferFluid(long fill, int pressure) {
|
||||
|
||||
this.subscribers.removeIf(x ->
|
||||
x == null || !(x instanceof TileEntity) || ((TileEntity)x).isInvalid()
|
||||
|
||||
subscribers.removeIf(x ->
|
||||
x == null || !(x instanceof TileEntity) || ((TileEntity)x).isInvalid() || !x.isLoaded()
|
||||
);
|
||||
|
||||
|
||||
if(this.subscribers.isEmpty())
|
||||
return fill;
|
||||
|
||||
|
||||
trackingInstances = new ArrayList();
|
||||
trackingInstances.add(this);
|
||||
List<IFluidConnector> subList = new ArrayList(subscribers);
|
||||
return fairTransfer(subList, type, pressure, fill);
|
||||
}
|
||||
|
||||
|
||||
public static long fairTransfer(List<IFluidConnector> subList, FluidType type, int pressure, long fill) {
|
||||
|
||||
|
||||
if(fill <= 0) return 0;
|
||||
|
||||
List<Long> weight = new ArrayList();
|
||||
long totalReq = 0;
|
||||
|
||||
|
||||
for(IFluidConnector con : subList) {
|
||||
long req = con.getDemand(type, pressure);
|
||||
weight.add(req);
|
||||
totalReq += req;
|
||||
}
|
||||
|
||||
|
||||
if(totalReq == 0)
|
||||
return fill;
|
||||
|
||||
|
||||
long totalGiven = 0;
|
||||
|
||||
|
||||
for(int i = 0; i < subList.size(); i++) {
|
||||
IFluidConnector con = subList.get(i);
|
||||
long req = weight.get(i);
|
||||
double fraction = (double)req / (double)totalReq;
|
||||
|
||||
|
||||
long given = (long) Math.floor(fraction * fill);
|
||||
|
||||
totalGiven += (given - con.transferFluid(type, pressure, given));
|
||||
|
||||
if(given > 0) {
|
||||
|
||||
totalGiven += (given - con.transferFluid(type, pressure, given));
|
||||
|
||||
if(con instanceof TileEntity) {
|
||||
TileEntity tile = (TileEntity) con;
|
||||
tile.getWorldObj().markTileEntityChunkModified(tile.xCoord, tile.yCoord, tile.zCoord, tile);
|
||||
}
|
||||
|
||||
/* debug code
|
||||
if(trackingInstances != null) {
|
||||
for(int j = 0; j < trackingInstances.size(); j++) {
|
||||
PipeNet net = trackingInstances.get(j);
|
||||
SimpleDateFormat sdf = new SimpleDateFormat("HH:mm:ss:SSS");
|
||||
sdf.setTimeZone(TimeZone.getTimeZone("UTC"));
|
||||
log(net, sdf.format(new Date(System.currentTimeMillis())) + " Sending " + given + "mB to " + conToString(con));
|
||||
}
|
||||
}
|
||||
*/
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
if(trackingInstances != null) {
|
||||
|
||||
|
||||
for(int i = 0; i < trackingInstances.size(); i++) {
|
||||
PipeNet net = trackingInstances.get(i);
|
||||
net.totalTransfer = net.totalTransfer.add(BigInteger.valueOf(totalGiven));
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
return fill - totalGiven;
|
||||
}
|
||||
|
||||
@ -146,10 +168,10 @@ public class PipeNet implements IPipeNet {
|
||||
public void destroy() {
|
||||
this.valid = false;
|
||||
this.subscribers.clear();
|
||||
|
||||
|
||||
for(IFluidConductor con : this.links)
|
||||
con.setPipeNet(type, null);
|
||||
|
||||
|
||||
this.links.clear();
|
||||
}
|
||||
|
||||
@ -162,4 +184,22 @@ public class PipeNet implements IPipeNet {
|
||||
public BigInteger getTotalTransfer() {
|
||||
return this.totalTransfer;
|
||||
}
|
||||
|
||||
public static void log(PipeNet net, String msg) {
|
||||
net.debug.add(msg);
|
||||
|
||||
while(net.debug.size() > 50) {
|
||||
net.debug.remove(0);
|
||||
}
|
||||
}
|
||||
|
||||
public static String conToString(IFluidConnector con) {
|
||||
|
||||
if(con instanceof TileEntity) {
|
||||
TileEntity tile = (TileEntity) con;
|
||||
return tile.getClass().getSimpleName() + " @ " + tile.xCoord + "/" + tile.yCoord + "/" + tile.zCoord;
|
||||
}
|
||||
|
||||
return "" + con;
|
||||
}
|
||||
}
|
||||
|
||||
@ -1,17 +0,0 @@
|
||||
package api.hbm.item;
|
||||
|
||||
import cpw.mods.fml.relauncher.Side;
|
||||
import cpw.mods.fml.relauncher.SideOnly;
|
||||
import net.minecraft.entity.player.EntityPlayer;
|
||||
import net.minecraft.item.ItemStack;
|
||||
|
||||
public interface IButtonReceiver {
|
||||
|
||||
/**
|
||||
* Called in ModEventHandlerClient for any keyboard input related to this item
|
||||
* @param stack
|
||||
* @param player
|
||||
*/
|
||||
@SideOnly(Side.CLIENT)
|
||||
public void handleKeyboardInput(ItemStack stack, EntityPlayer player);
|
||||
}
|
||||
@ -1,20 +0,0 @@
|
||||
package api.hbm.item;
|
||||
|
||||
import cpw.mods.fml.relauncher.Side;
|
||||
import cpw.mods.fml.relauncher.SideOnly;
|
||||
import net.minecraft.entity.player.EntityPlayer;
|
||||
import net.minecraft.item.ItemStack;
|
||||
|
||||
public interface IClickReceiver {
|
||||
|
||||
/**
|
||||
* Called in ModEventHandlerClient for any mouse input related to this item
|
||||
* @param stack
|
||||
* @param player
|
||||
* @param button
|
||||
* @param state
|
||||
* @return true if the event should be canceled
|
||||
*/
|
||||
@SideOnly(Side.CLIENT)
|
||||
public boolean handleMouseInput(ItemStack stack, EntityPlayer player, int button, boolean state);
|
||||
}
|
||||
9
src/main/java/api/hbm/redstoneoverradio/IRORInfo.java
Normal file
9
src/main/java/api/hbm/redstoneoverradio/IRORInfo.java
Normal file
@ -0,0 +1,9 @@
|
||||
package api.hbm.redstoneoverradio;
|
||||
|
||||
public interface IRORInfo {
|
||||
|
||||
public static String PREFIX_VALUE = "VAL:";
|
||||
public static String PREFIX_FUNCTION = "FUN:";
|
||||
|
||||
public String[] getFunctionInfo();
|
||||
}
|
||||
32
src/main/java/api/hbm/redstoneoverradio/IRORInteractive.java
Normal file
32
src/main/java/api/hbm/redstoneoverradio/IRORInteractive.java
Normal file
@ -0,0 +1,32 @@
|
||||
package api.hbm.redstoneoverradio;
|
||||
|
||||
public interface IRORInteractive extends IRORInfo {
|
||||
|
||||
public static String NAME_SEPARATOR = "!";
|
||||
public static String PARAM_SEPARATOR = ":";
|
||||
|
||||
public static String EX_NULL = "Exception: Null Command";
|
||||
public static String EX_NAME = "Exception: Multiple Name Separators";
|
||||
|
||||
/** Runs a function on the ROR component, usually causing the component to change or do something. Returns are optional. */
|
||||
public Object runRORFunction(String name, String[] params);
|
||||
|
||||
/** Extracts the command name from a full command string */
|
||||
public static String getCommand(String input) {
|
||||
if(input == null || input.isEmpty()) throw new RORFunctionException(EX_NULL);
|
||||
String[] parts = input.split(NAME_SEPARATOR);
|
||||
if(parts.length <= 0 || parts.length > 2) throw new RORFunctionException(EX_NAME);
|
||||
return parts[0];
|
||||
}
|
||||
|
||||
/** Extracts the param list from a full command string */
|
||||
public static String[] getParams(String input) {
|
||||
if(input == null || input.isEmpty()) throw new RORFunctionException(EX_NULL);
|
||||
String[] parts = input.split(NAME_SEPARATOR);
|
||||
if(parts.length <= 0 || parts.length > 2) throw new RORFunctionException(EX_NAME);
|
||||
if(parts.length == 1) return new String[0];
|
||||
String paramList = parts[1];
|
||||
String[] params = paramList.split(PARAM_SEPARATOR);
|
||||
return params;
|
||||
}
|
||||
}
|
||||
@ -0,0 +1,7 @@
|
||||
package api.hbm.redstoneoverradio;
|
||||
|
||||
public interface IRORValueProvider extends IRORInfo {
|
||||
|
||||
/** Grabs the specified value from this ROR component, operations should not cause any changes with the component itself */
|
||||
public Object provideRORValue(String name);
|
||||
}
|
||||
@ -0,0 +1,8 @@
|
||||
package api.hbm.redstoneoverradio;
|
||||
|
||||
public class RORFunctionException extends RuntimeException {
|
||||
|
||||
public RORFunctionException(String message) {
|
||||
super(message);
|
||||
}
|
||||
}
|
||||
46
src/main/java/api/hbm/redstoneoverradio/package-info.java
Normal file
46
src/main/java/api/hbm/redstoneoverradio/package-info.java
Normal file
@ -0,0 +1,46 @@
|
||||
/**
|
||||
* @author hbm
|
||||
*
|
||||
*/
|
||||
package api.hbm.redstoneoverradio;
|
||||
|
||||
/*
|
||||
|
||||
__ __ __ _________ ________ __ __ __ __ ______ __
|
||||
/_/| /_/\ /_/| /________/\ /_______/| /_/| /_/| /_/|_____ /_/| /_____/| /_/|
|
||||
| || | \\ | || | ___ \ \ | ______|/ | |\_| || | |/_____| || |___ || | ||
|
||||
| || | \ \\ | || | || \ \/ | ||___ | \/_/ |/ | ______ || /__| || | ||__
|
||||
| || | |\ \\| || | || \ || | |/__/| \ // | |/_____| || | ___|/ | |/_/|
|
||||
| || | ||\ \| || | || | || | ____|/ > </\ |____ ____|/_ | |/__/| | __|/
|
||||
| || | || \ | || | ||___/ |/ | ||_____ / __ \/| /_____| |______/| |______|/ | ||
|
||||
| || | || \ || | |/__/ / | |/____/| | /| \ || |________________|/ | ||
|
||||
|__|/ |__|/ \__|/ |_________/ |________|/ |__|/ |__|/ |__|/
|
||||
|
||||
(not AN index, INDEX is just the codename)
|
||||
(also no i did not use an ASCII font generator i spent like half an hour on this)
|
||||
|
||||
INDEX includes Redstone-over-Radio APIs for interacting with ROR torches in ways more complex than simple comparator output,
|
||||
simply put, certain ROR torches may run functions on the ROR component or read more complex values. This means that with the ROR
|
||||
system alone, one can make complex monitoring and logic systems controlling machines via redstone automation.
|
||||
|
||||
INDEX includes:
|
||||
- IRORInfo, an interface that provides a list of all valid functions. This interface should never be implemented directly because
|
||||
it is worthless on its own, rather it is extended by all other ROR API interfaces
|
||||
- IRORValueProvider, a simple interface that returns values based on names, serving as a simple getter. Get operations should never
|
||||
cause changes within the ROR component, and should be kept simple
|
||||
- IRORInteractive, an interface providing functions equivalent to java, usually performing a state change within the component and
|
||||
optionally returning a value
|
||||
|
||||
On the implementation side we can expect:
|
||||
- ROR readers, torches which have a list of named values which are read, as well as frequencies on which these values are boradcasted
|
||||
- ROR controllers, torches which have one frequency and can receive commands with parameters which will be executed on the component
|
||||
- ROR programmers, torches which have a list of frequencies and return frequencies which can receive commands with parameters and
|
||||
then send the return value on the return frequency
|
||||
- ROR logic receivers, torches which can turn signals into redstone based on various factors like arithmetic comparison and string
|
||||
operators like matches, matches not and substring (thanks to vær for taking care of that)
|
||||
|
||||
ROR programmers can indeed do everything that the readers and controllers can, but their added complexity requires more GUI elements
|
||||
which are more time-consuming to set up and limits the amount of command channels available, hence why readers and controllers exist
|
||||
when only a simple solution is required
|
||||
|
||||
*/
|
||||
20
src/main/java/api/hbm/tile/IInfoProviderEC.java
Normal file
20
src/main/java/api/hbm/tile/IInfoProviderEC.java
Normal file
@ -0,0 +1,20 @@
|
||||
package api.hbm.tile;
|
||||
|
||||
import net.minecraft.nbt.NBTTagCompound;
|
||||
|
||||
/**
|
||||
* Info providers for ENERGY CONTROL
|
||||
*
|
||||
* For EC's implementation, refer to:
|
||||
* https://github.com/Zuxelus/Energy-Control/blob/1.7.10/src/main/java/com/zuxelus/energycontrol/crossmod/CrossHBM.java
|
||||
* https://github.com/Zuxelus/Energy-Control/blob/1.7.10/src/main/java/com/zuxelus/energycontrol/items/cards/ItemCardHBM.java
|
||||
* https://github.com/Zuxelus/Energy-Control/blob/1.7.10/src/main/java/com/zuxelus/energycontrol/utils/DataHelper.java
|
||||
*
|
||||
* (keys are from DataHelper.java and CrossHBM.java)
|
||||
*
|
||||
* */
|
||||
public interface IInfoProviderEC {
|
||||
|
||||
/** Adds any custom data that isn't covered by the standard energy and fluid implementations. */
|
||||
public void provideExtraInfo(NBTTagCompound data);
|
||||
}
|
||||
6
src/main/java/api/hbm/tile/ILoadedTile.java
Normal file
6
src/main/java/api/hbm/tile/ILoadedTile.java
Normal file
@ -0,0 +1,6 @@
|
||||
package api.hbm.tile;
|
||||
|
||||
public interface ILoadedTile {
|
||||
|
||||
public boolean isLoaded();
|
||||
}
|
||||
@ -1,17 +1,18 @@
|
||||
package com.hbm.blocks;
|
||||
|
||||
import com.hbm.lib.RefStrings;
|
||||
|
||||
import net.minecraft.block.Block;
|
||||
import net.minecraft.block.material.Material;
|
||||
import net.minecraft.entity.EnumCreatureType;
|
||||
import net.minecraft.entity.item.EntityItem;
|
||||
import net.minecraft.item.ItemStack;
|
||||
import net.minecraft.world.IBlockAccess;
|
||||
import net.minecraft.world.World;
|
||||
|
||||
public class BlockBase extends Block {
|
||||
|
||||
|
||||
private boolean beaconable = false;
|
||||
private boolean canSpawn = true;
|
||||
|
||||
public BlockBase() {
|
||||
super(Material.rock);
|
||||
@ -20,14 +21,14 @@ public class BlockBase extends Block {
|
||||
public BlockBase(Material material) {
|
||||
super(material);
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public Block setBlockName(String name) {
|
||||
super.setBlockName(name);
|
||||
this.setBlockTextureName(RefStrings.MODID + ":" + name);
|
||||
return this;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Daisychainable setter for making the block a beacon base block
|
||||
* @return
|
||||
@ -37,11 +38,21 @@ public class BlockBase extends Block {
|
||||
return this;
|
||||
}
|
||||
|
||||
public BlockBase noMobSpawn() {
|
||||
this.canSpawn = false;
|
||||
return this;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean canCreatureSpawn(EnumCreatureType type, IBlockAccess world, int x, int y, int z) {
|
||||
return this.canSpawn ? super.canCreatureSpawn(type, world, x, y, z) : false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isBeaconBase(IBlockAccess worldObj, int x, int y, int z, int beaconX, int beaconY, int beaconZ) {
|
||||
return this.beaconable;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Sets the block to air and drops it
|
||||
* @param world
|
||||
@ -50,7 +61,7 @@ public class BlockBase extends Block {
|
||||
* @param z
|
||||
*/
|
||||
public void dismantle(World world, int x, int y, int z) {
|
||||
|
||||
|
||||
world.setBlockToAir(x, y, z);
|
||||
|
||||
ItemStack itemstack = new ItemStack(this, 1);
|
||||
|
||||
@ -1,14 +1,10 @@
|
||||
package com.hbm.blocks;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import java.util.Random;
|
||||
|
||||
import com.hbm.handler.MultiblockHandlerXR;
|
||||
import com.hbm.handler.ThreeInts;
|
||||
import com.hbm.interfaces.ICopiable;
|
||||
import com.hbm.main.MainRegistry;
|
||||
import com.hbm.tileentity.IPersistentNBT;
|
||||
|
||||
import cpw.mods.fml.common.network.internal.FMLNetworkHandler;
|
||||
import cpw.mods.fml.relauncher.Side;
|
||||
import cpw.mods.fml.relauncher.SideOnly;
|
||||
@ -32,11 +28,14 @@ import net.minecraft.world.World;
|
||||
import net.minecraftforge.client.event.DrawBlockHighlightEvent;
|
||||
import net.minecraftforge.common.util.ForgeDirection;
|
||||
|
||||
public abstract class BlockDummyable extends BlockContainer implements ICustomBlockHighlight {
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import java.util.Random;
|
||||
|
||||
public abstract class BlockDummyable extends BlockContainer implements ICustomBlockHighlight, ICopiable {
|
||||
|
||||
public BlockDummyable(Material mat) {
|
||||
super(mat);
|
||||
this.maxY = 0.999D; //item bounce prevention
|
||||
this.setTickRandomly(true);
|
||||
}
|
||||
|
||||
@ -50,7 +49,7 @@ public abstract class BlockDummyable extends BlockContainer implements ICustomBl
|
||||
public static final int offset = 10;
|
||||
// meta offset from dummy to extra rotation
|
||||
public static final int extra = 6;
|
||||
|
||||
|
||||
/*
|
||||
* An extra integer that can be set before block set operations (such as makeExtra) and intercepted in createNewTileEntity.
|
||||
* This way we can inelegantly add variation to the tiles created even if the metadata would be the same.
|
||||
@ -60,11 +59,11 @@ public abstract class BlockDummyable extends BlockContainer implements ICustomBl
|
||||
public static int overrideTileMeta = 0;
|
||||
|
||||
public static boolean safeRem = false;
|
||||
|
||||
|
||||
public static void setOverride(int i) {
|
||||
overrideTileMeta = i;
|
||||
}
|
||||
|
||||
|
||||
public static void resetOverride() {
|
||||
overrideTileMeta = 0;
|
||||
}
|
||||
@ -179,7 +178,7 @@ public abstract class BlockDummyable extends BlockContainer implements ICustomBl
|
||||
if(i == 3) {
|
||||
dir = ForgeDirection.getOrientation(4);
|
||||
}
|
||||
|
||||
|
||||
dir = getDirModified(dir);
|
||||
|
||||
if(!checkRequirement(world, x, y, z, dir, o)) {
|
||||
@ -221,7 +220,7 @@ public abstract class BlockDummyable extends BlockContainer implements ICustomBl
|
||||
public void onBlockAdded(World world, int x, int y, int z) {
|
||||
lastBlockSet = new BlockPos(x, y, z);
|
||||
}*/
|
||||
|
||||
|
||||
/**
|
||||
* A bit more advanced than the dir modifier, but it is important that the resulting direction meta is in the core range.
|
||||
* Using the "extra" metas is technically possible but requires a bit of tinkering, e.g. preventing a recursive loop
|
||||
@ -237,7 +236,7 @@ public abstract class BlockDummyable extends BlockContainer implements ICustomBl
|
||||
protected int getMetaForCore(World world, int x, int y, int z, EntityPlayer player, int original) {
|
||||
return original;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Allows to modify the general placement direction as if the player had another rotation.
|
||||
* Quite basic due to only having 1 param but it's more meant to fix/limit the amount of directions
|
||||
@ -272,7 +271,7 @@ public abstract class BlockDummyable extends BlockContainer implements ICustomBl
|
||||
world.setBlock(x, y, z, this, meta + extra, 3);
|
||||
this.safeRem = false;
|
||||
}
|
||||
|
||||
|
||||
public void removeExtra(World world, int x, int y, int z) {
|
||||
|
||||
if(world.getBlock(x, y, z) != this)
|
||||
@ -310,7 +309,7 @@ public abstract class BlockDummyable extends BlockContainer implements ICustomBl
|
||||
// if(pos != null) {
|
||||
|
||||
ForgeDirection d = ForgeDirection.getOrientation(i);
|
||||
|
||||
|
||||
if(world.getBlock(x - d.offsetX, y - d.offsetY, z - d.offsetZ) == this)
|
||||
world.setBlockToAir(x - d.offsetX, y - d.offsetY, z - d.offsetZ);
|
||||
// }
|
||||
@ -385,7 +384,7 @@ public abstract class BlockDummyable extends BlockContainer implements ICustomBl
|
||||
}
|
||||
|
||||
protected boolean standardOpenBehavior(World world, int x, int y, int z, EntityPlayer player, int id) {
|
||||
|
||||
|
||||
if(world.isRemote) {
|
||||
return true;
|
||||
} else if(!player.isSneaking()) {
|
||||
@ -403,14 +402,14 @@ public abstract class BlockDummyable extends BlockContainer implements ICustomBl
|
||||
|
||||
@Override
|
||||
public void onBlockHarvested(World world, int x, int y, int z, int meta, EntityPlayer player) {
|
||||
|
||||
|
||||
if(!player.capabilities.isCreativeMode) {
|
||||
harvesters.set(player);
|
||||
this.dropBlockAsItem(world, x, y, z, meta, 0);
|
||||
harvesters.set(null);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* Called after the block and TE are already gone, so this method is of no use to us.
|
||||
*/
|
||||
@ -419,53 +418,53 @@ public abstract class BlockDummyable extends BlockContainer implements ICustomBl
|
||||
player.addStat(StatList.mineBlockStatArray[getIdFromBlock(this)], 1);
|
||||
player.addExhaustion(0.025F);
|
||||
}
|
||||
|
||||
|
||||
public boolean useDetailedHitbox() {
|
||||
return !bounding.isEmpty();
|
||||
}
|
||||
|
||||
|
||||
public List<AxisAlignedBB> bounding = new ArrayList();
|
||||
|
||||
@Override
|
||||
public void addCollisionBoxesToList(World world, int x, int y, int z, AxisAlignedBB entityBounding, List list, Entity entity) {
|
||||
|
||||
|
||||
if(!this.useDetailedHitbox()) {
|
||||
super.addCollisionBoxesToList(world, x, y, z, entityBounding, list, entity);
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
int[] pos = this.findCore(world, x, y, z);
|
||||
|
||||
|
||||
if(pos == null)
|
||||
return;
|
||||
|
||||
|
||||
x = pos[0];
|
||||
y = pos[1];
|
||||
z = pos[2];
|
||||
|
||||
|
||||
for(AxisAlignedBB aabb :this.bounding) {
|
||||
AxisAlignedBB boxlet = getAABBRotationOffset(aabb, x + 0.5, y, z + 0.5, ForgeDirection.getOrientation(world.getBlockMetadata(x, y, z) - this.offset).getRotation(ForgeDirection.UP));
|
||||
|
||||
|
||||
if(entityBounding.intersectsWith(boxlet)) {
|
||||
list.add(boxlet);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
public static AxisAlignedBB getAABBRotationOffset(AxisAlignedBB aabb, double x, double y, double z, ForgeDirection dir) {
|
||||
|
||||
|
||||
AxisAlignedBB newBox = null;
|
||||
|
||||
if(dir == ForgeDirection.NORTH) newBox = AxisAlignedBB.getBoundingBox(aabb.minX, aabb.minY, aabb.minZ, aabb.maxX, aabb.maxY, aabb.maxZ);
|
||||
if(dir == ForgeDirection.EAST) newBox = AxisAlignedBB.getBoundingBox(-aabb.maxZ, aabb.minY, aabb.minX, -aabb.minZ, aabb.maxY, aabb.maxX);
|
||||
if(dir == ForgeDirection.SOUTH) newBox = AxisAlignedBB.getBoundingBox(-aabb.maxX, aabb.minY, -aabb.maxZ, -aabb.minX, aabb.maxY, -aabb.minZ);
|
||||
if(dir == ForgeDirection.WEST) newBox = AxisAlignedBB.getBoundingBox(aabb.minZ, aabb.minY, -aabb.maxX, aabb.maxZ, aabb.maxY, -aabb.minX);
|
||||
|
||||
|
||||
if(newBox != null) {
|
||||
newBox.offset(x, y, z);
|
||||
return newBox;
|
||||
}
|
||||
|
||||
|
||||
return AxisAlignedBB.getBoundingBox(aabb.minX, aabb.minY, aabb.minZ, aabb.maxX, aabb.maxY, aabb.maxZ).offset(x + 0.5, y + 0.5, z + 0.5);
|
||||
}
|
||||
|
||||
@ -477,35 +476,62 @@ public abstract class BlockDummyable extends BlockContainer implements ICustomBl
|
||||
this.setBlockBounds(0.0F, 0.0F, 0.0F, 1.0F, 0.999F, 1.0F); //for some fucking reason setting maxY to something that isn't 1 magically fixes item collisions
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
@SideOnly(Side.CLIENT)
|
||||
public boolean shouldDrawHighlight(World world, int x, int y, int z) {
|
||||
return !this.bounding.isEmpty();
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
@SideOnly(Side.CLIENT)
|
||||
public void drawHighlight(DrawBlockHighlightEvent event, World world, int x, int y, int z) {
|
||||
|
||||
|
||||
int[] pos = this.findCore(world, x, y, z);
|
||||
if(pos == null) return;
|
||||
|
||||
|
||||
x = pos[0];
|
||||
y = pos[1];
|
||||
z = pos[2];
|
||||
|
||||
|
||||
EntityPlayer player = event.player;
|
||||
float interp = event.partialTicks;
|
||||
double dX = player.lastTickPosX + (player.posX - player.lastTickPosX) * (double) interp;
|
||||
double dY = player.lastTickPosY + (player.posY - player.lastTickPosY) * (double) interp;
|
||||
double dZ = player.lastTickPosZ + (player.posZ - player.lastTickPosZ) * (double)interp;
|
||||
float exp = 0.002F;
|
||||
|
||||
|
||||
int meta = world.getBlockMetadata(x, y, z);
|
||||
|
||||
ICustomBlockHighlight.setup();
|
||||
for(AxisAlignedBB aabb : this.bounding) event.context.drawOutlinedBoundingBox(getAABBRotationOffset(aabb.expand(exp, exp, exp), 0, 0, 0, ForgeDirection.getOrientation(meta - offset).getRotation(ForgeDirection.UP)).getOffsetBoundingBox(x - dX + 0.5, y - dY, z - dZ + 0.5), -1);
|
||||
ICustomBlockHighlight.cleanup();
|
||||
}
|
||||
|
||||
@Override
|
||||
public NBTTagCompound getSettings(World world, int x, int y, int z) {
|
||||
int[] pos = findCore(world, x, y, z);
|
||||
TileEntity tile = world.getTileEntity(pos[0], pos[1], pos[2]);
|
||||
if (tile instanceof ICopiable)
|
||||
return ((ICopiable) tile).getSettings(world, pos[0], pos[1], pos[2]);
|
||||
else
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void pasteSettings(NBTTagCompound nbt, int index, World world, EntityPlayer player, int x, int y, int z) {
|
||||
int[] pos = findCore(world, x, y, z);
|
||||
TileEntity tile = world.getTileEntity(pos[0], pos[1], pos[2]);
|
||||
if (tile instanceof ICopiable)
|
||||
((ICopiable) tile).pasteSettings(nbt, index, world, player, pos[0], pos[1], pos[2]);
|
||||
}
|
||||
|
||||
@Override
|
||||
public String[] infoForDisplay(World world, int x, int y, int z) {
|
||||
int[] pos = findCore(world, x, y, z);
|
||||
TileEntity tile = world.getTileEntity(pos[0], pos[1], pos[2]);
|
||||
if (tile instanceof ICopiable)
|
||||
return ((ICopiable) tile).infoForDisplay(world, x, y, z);
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
@ -1,9 +1,6 @@
|
||||
package com.hbm.blocks;
|
||||
|
||||
import java.util.Locale;
|
||||
|
||||
import com.hbm.util.EnumUtil;
|
||||
|
||||
import cpw.mods.fml.relauncher.Side;
|
||||
import cpw.mods.fml.relauncher.SideOnly;
|
||||
import net.minecraft.block.material.Material;
|
||||
@ -11,6 +8,8 @@ import net.minecraft.client.renderer.texture.IIconRegister;
|
||||
import net.minecraft.item.ItemStack;
|
||||
import net.minecraft.util.IIcon;
|
||||
|
||||
import java.util.Locale;
|
||||
|
||||
public class BlockEnumMulti extends BlockMulti {
|
||||
|
||||
public Class<? extends Enum> theEnum;
|
||||
@ -23,36 +22,44 @@ public class BlockEnumMulti extends BlockMulti {
|
||||
this.multiName = multiName;
|
||||
this.multiTexture = multiTexture;
|
||||
}
|
||||
|
||||
|
||||
protected IIcon[] icons;
|
||||
|
||||
@Override
|
||||
@SideOnly(Side.CLIENT)
|
||||
public void registerBlockIcons(IIconRegister reg) {
|
||||
|
||||
|
||||
if(multiTexture) {
|
||||
Enum[] enums = theEnum.getEnumConstants();
|
||||
this.icons = new IIcon[enums.length];
|
||||
|
||||
|
||||
for(int i = 0; i < icons.length; i++) {
|
||||
Enum num = enums[i];
|
||||
this.icons[i] = reg.registerIcon(this.getTextureName() + "." + num.name().toLowerCase(Locale.US));
|
||||
this.icons[i] = reg.registerIcon(this.getTextureMultiName(num));
|
||||
}
|
||||
} else {
|
||||
this.blockIcon = reg.registerIcon(this.getTextureName());
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
public String getUnlocalizedName(ItemStack stack) {
|
||||
|
||||
|
||||
if(this.multiName) {
|
||||
Enum num = EnumUtil.grabEnumSafely(this.theEnum, stack.getItemDamage());
|
||||
return super.getUnlocalizedName() + "." + num.name().toLowerCase(Locale.US);
|
||||
return getUnlocalizedMultiName(num);
|
||||
}
|
||||
|
||||
|
||||
return this.getUnlocalizedName();
|
||||
}
|
||||
|
||||
|
||||
public String getTextureMultiName(Enum num) {
|
||||
return this.getTextureName() + "." + num.name().toLowerCase(Locale.US);
|
||||
}
|
||||
|
||||
public String getUnlocalizedMultiName(Enum num) {
|
||||
return super.getUnlocalizedName() + "." + num.name().toLowerCase(Locale.US);
|
||||
}
|
||||
|
||||
@Override
|
||||
@SideOnly(Side.CLIENT)
|
||||
public IIcon getIcon(int side, int meta) {
|
||||
|
||||
@ -11,6 +11,14 @@ public class BlockEnums {
|
||||
BAUXITE
|
||||
}
|
||||
|
||||
public static enum EnumMeteorType {
|
||||
IRON,
|
||||
COPPER,
|
||||
ALUMINIUM,
|
||||
RAREEARTH,
|
||||
COBALT
|
||||
}
|
||||
|
||||
public static enum EnumBiomeType {
|
||||
DESERT,
|
||||
WOODLAND
|
||||
@ -20,6 +28,27 @@ public class BlockEnums {
|
||||
SULFUR,
|
||||
ASBESTOS
|
||||
}
|
||||
|
||||
public static enum EnumCMMaterials {
|
||||
STEEL,
|
||||
ALLOY,
|
||||
DESH,
|
||||
TCALLOY
|
||||
}
|
||||
|
||||
public static enum EnumCMEngines {
|
||||
STANDARD,
|
||||
DESH,
|
||||
BISMUTH
|
||||
}
|
||||
|
||||
public static enum EnumCMCircuit {
|
||||
ALUMINIUM,
|
||||
COPPER,
|
||||
RED_COPPER,
|
||||
GOLD,
|
||||
SCHRABIDIUM
|
||||
}
|
||||
|
||||
/** DECO / STRUCTURE ENUMS */
|
||||
//i apologize in advance
|
||||
@ -37,4 +66,10 @@ public class BlockEnums {
|
||||
GREEN,
|
||||
STEEL
|
||||
}
|
||||
|
||||
public static enum LightType {
|
||||
INCANDESCENT,
|
||||
FLUORESCENT,
|
||||
HALOGEN
|
||||
}
|
||||
}
|
||||
|
||||
95
src/main/java/com/hbm/blocks/BlockFallingNT.java
Normal file
95
src/main/java/com/hbm/blocks/BlockFallingNT.java
Normal file
@ -0,0 +1,95 @@
|
||||
package com.hbm.blocks;
|
||||
|
||||
import com.hbm.entity.item.EntityFallingBlockNT;
|
||||
import cpw.mods.fml.relauncher.Side;
|
||||
import cpw.mods.fml.relauncher.SideOnly;
|
||||
import net.minecraft.block.Block;
|
||||
import net.minecraft.block.material.Material;
|
||||
import net.minecraft.client.renderer.RenderBlocks;
|
||||
import net.minecraft.client.renderer.Tessellator;
|
||||
import net.minecraft.creativetab.CreativeTabs;
|
||||
import net.minecraft.init.Blocks;
|
||||
import net.minecraft.world.World;
|
||||
|
||||
import java.util.Random;
|
||||
|
||||
public class BlockFallingNT extends Block {
|
||||
|
||||
public static boolean fallInstantly;
|
||||
|
||||
public BlockFallingNT() {
|
||||
super(Material.sand);
|
||||
this.setCreativeTab(CreativeTabs.tabBlock);
|
||||
}
|
||||
|
||||
public BlockFallingNT(Material mat) {
|
||||
super(mat);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onBlockAdded(World world, int x, int y, int z) {
|
||||
world.scheduleBlockUpdate(x, y, z, this, this.tickRate(world));
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onNeighborBlockChange(World world, int x, int y, int z, Block block) {
|
||||
world.scheduleBlockUpdate(x, y, z, this, this.tickRate(world));
|
||||
}
|
||||
|
||||
@Override
|
||||
public void updateTick(World world, int x, int y, int z, Random rand) {
|
||||
if(!world.isRemote) {
|
||||
this.fall(world, x, y, z);
|
||||
}
|
||||
}
|
||||
|
||||
protected void fall(World world, int x, int y, int z) {
|
||||
|
||||
if(canFallThrough(world, x, y - 1, z) && y >= 0) {
|
||||
byte range = 32;
|
||||
|
||||
if(!fallInstantly && world.checkChunksExist(x - range, y - range, z - range, x + range, y + range, z + range)) {
|
||||
if(!world.isRemote) {
|
||||
EntityFallingBlockNT entityfallingblock = new EntityFallingBlockNT(world, x + 0.5D, y + 0.5D, z + 0.5D, this, world.getBlockMetadata(x, y, z));
|
||||
this.modifyFallingBlock(entityfallingblock);
|
||||
world.spawnEntityInWorld(entityfallingblock);
|
||||
}
|
||||
} else {
|
||||
world.setBlockToAir(x, y, z);
|
||||
|
||||
while(canFallThrough(world, x, y - 1, z) && y > 0) {
|
||||
--y;
|
||||
}
|
||||
|
||||
if(y > 0) {
|
||||
world.setBlock(x, y, z, this);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
protected void modifyFallingBlock(EntityFallingBlockNT falling) { }
|
||||
|
||||
@Override
|
||||
public int tickRate(World world) {
|
||||
return 2;
|
||||
}
|
||||
|
||||
public static boolean canFallThrough(World world, int x, int y, int z) {
|
||||
Block block = world.getBlock(x, y, z);
|
||||
|
||||
if(block.isAir(world, x, y, z)) {
|
||||
return true;
|
||||
} else if(block == Blocks.fire) {
|
||||
return true;
|
||||
} else {
|
||||
Material material = block.getMaterial();
|
||||
return material == Material.water ? true : material == Material.lava;
|
||||
}
|
||||
}
|
||||
|
||||
public void onLand(World world, int x, int y, int z, int meta) { }
|
||||
|
||||
@SideOnly(Side.CLIENT) public boolean shouldOverrideRenderer() { return false; }
|
||||
@SideOnly(Side.CLIENT) public void overrideRenderer(EntityFallingBlockNT falling, RenderBlocks renderBlocks, Tessellator tessellator) { }
|
||||
}
|
||||
@ -1,7 +1,5 @@
|
||||
package com.hbm.blocks;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
import cpw.mods.fml.relauncher.Side;
|
||||
import cpw.mods.fml.relauncher.SideOnly;
|
||||
import net.minecraft.block.material.Material;
|
||||
@ -9,6 +7,8 @@ import net.minecraft.creativetab.CreativeTabs;
|
||||
import net.minecraft.item.Item;
|
||||
import net.minecraft.item.ItemStack;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
public abstract class BlockMulti extends BlockBase implements IBlockMulti {
|
||||
|
||||
public BlockMulti() {
|
||||
@ -31,8 +31,4 @@ public abstract class BlockMulti extends BlockBase implements IBlockMulti {
|
||||
list.add(new ItemStack(item, 1, i));
|
||||
}
|
||||
}
|
||||
|
||||
public String getUnlocalizedName(ItemStack stack) {
|
||||
return this.getUnlocalizedName();
|
||||
}
|
||||
}
|
||||
|
||||
@ -1,17 +1,19 @@
|
||||
package com.hbm.blocks;
|
||||
|
||||
import cpw.mods.fml.relauncher.Side;
|
||||
import cpw.mods.fml.relauncher.SideOnly;
|
||||
import net.minecraft.block.Block;
|
||||
import net.minecraft.block.material.Material;
|
||||
import net.minecraft.item.Item;
|
||||
import net.minecraft.util.IIcon;
|
||||
import net.minecraft.world.World;
|
||||
import net.minecraftforge.client.event.RenderGameOverlayEvent.Pre;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Random;
|
||||
|
||||
import com.hbm.lib.RefStrings;
|
||||
|
||||
import net.minecraft.block.Block;
|
||||
import net.minecraft.block.material.Material;
|
||||
import net.minecraft.world.World;
|
||||
import net.minecraftforge.client.event.RenderGameOverlayEvent.Pre;
|
||||
|
||||
public class BlockRemap extends Block implements ILookOverlay {
|
||||
|
||||
|
||||
public Block remapBlock;
|
||||
public int remapMeta;
|
||||
|
||||
@ -21,12 +23,16 @@ public class BlockRemap extends Block implements ILookOverlay {
|
||||
this.remapMeta = meta;
|
||||
this.setTickRandomly(true);
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public Block setBlockName(String name) {
|
||||
super.setBlockName(name);
|
||||
this.setBlockTextureName(RefStrings.MODID + ":" + name);
|
||||
return this;
|
||||
@SideOnly(Side.CLIENT)
|
||||
public IIcon getIcon(int meta, int side) {
|
||||
return this.remapBlock.getIcon(meta, side);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Item getItemDropped(int meta, Random rand, int fortune) {
|
||||
return this.remapBlock.getItemDropped(meta, rand, fortune);
|
||||
}
|
||||
|
||||
@Override
|
||||
|
||||
10
src/main/java/com/hbm/blocks/IAnalyzable.java
Normal file
10
src/main/java/com/hbm/blocks/IAnalyzable.java
Normal file
@ -0,0 +1,10 @@
|
||||
package com.hbm.blocks;
|
||||
|
||||
import net.minecraft.world.World;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
public interface IAnalyzable {
|
||||
|
||||
public List<String> getDebugInfo(World world, int x, int y, int z);
|
||||
}
|
||||
@ -1,9 +1,20 @@
|
||||
package com.hbm.blocks;
|
||||
|
||||
import net.minecraft.block.Block;
|
||||
import net.minecraft.item.ItemStack;
|
||||
|
||||
public interface IBlockMulti {
|
||||
|
||||
public int getSubCount();
|
||||
|
||||
public default String getUnlocalizedName(ItemStack stack) {
|
||||
return ((Block)this).getUnlocalizedName();
|
||||
}
|
||||
|
||||
public default String getOverrideDisplayName(ItemStack stack) {
|
||||
return null;
|
||||
}
|
||||
|
||||
public default int rectify(int meta) {
|
||||
return Math.abs(meta % getSubCount());
|
||||
}
|
||||
|
||||
@ -11,4 +11,7 @@ public interface IBlockMultiPass {
|
||||
return renderID;
|
||||
}
|
||||
|
||||
public default boolean shouldRenderItemMulti() {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
@ -1,18 +1,17 @@
|
||||
package com.hbm.blocks;
|
||||
|
||||
import org.lwjgl.opengl.GL11;
|
||||
|
||||
import cpw.mods.fml.relauncher.Side;
|
||||
import cpw.mods.fml.relauncher.SideOnly;
|
||||
import net.minecraft.client.renderer.OpenGlHelper;
|
||||
import net.minecraft.world.World;
|
||||
import net.minecraftforge.client.event.DrawBlockHighlightEvent;
|
||||
import org.lwjgl.opengl.GL11;
|
||||
|
||||
public interface ICustomBlockHighlight {
|
||||
|
||||
@SideOnly(Side.CLIENT) public boolean shouldDrawHighlight(World world, int x, int y, int z);
|
||||
@SideOnly(Side.CLIENT) public void drawHighlight(DrawBlockHighlightEvent event, World world, int x, int y, int z);
|
||||
|
||||
|
||||
@SideOnly(Side.CLIENT)
|
||||
public static void setup() {
|
||||
GL11.glEnable(GL11.GL_BLEND);
|
||||
@ -22,7 +21,7 @@ public interface ICustomBlockHighlight {
|
||||
GL11.glDisable(GL11.GL_TEXTURE_2D);
|
||||
GL11.glDepthMask(false);
|
||||
}
|
||||
|
||||
|
||||
@SideOnly(Side.CLIENT)
|
||||
public static void cleanup() {
|
||||
GL11.glDepthMask(true);
|
||||
|
||||
@ -1,9 +1,5 @@
|
||||
package com.hbm.blocks;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
import org.lwjgl.opengl.GL11;
|
||||
|
||||
import cpw.mods.fml.relauncher.Side;
|
||||
import cpw.mods.fml.relauncher.SideOnly;
|
||||
import net.minecraft.client.Minecraft;
|
||||
@ -11,6 +7,9 @@ import net.minecraft.client.gui.Gui;
|
||||
import net.minecraft.client.gui.ScaledResolution;
|
||||
import net.minecraft.world.World;
|
||||
import net.minecraftforge.client.event.RenderGameOverlayEvent;
|
||||
import org.lwjgl.opengl.GL11;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
public interface ILookOverlay {
|
||||
|
||||
@ -33,14 +32,14 @@ public interface ILookOverlay {
|
||||
|
||||
try {
|
||||
for(String line : text) {
|
||||
|
||||
|
||||
int color = 0xFFFFFF;
|
||||
if(line.startsWith("&[")) {
|
||||
int end = line.lastIndexOf("&]");
|
||||
color = Integer.parseInt(line.substring(2, end));
|
||||
line = line.substring(end + 2);
|
||||
}
|
||||
|
||||
|
||||
mc.fontRenderer.drawStringWithShadow(line, pX, pZ, color);
|
||||
pZ += 10;
|
||||
}
|
||||
|
||||
@ -1,11 +1,11 @@
|
||||
package com.hbm.blocks;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
import net.minecraft.entity.player.EntityPlayer;
|
||||
import net.minecraft.item.ItemStack;
|
||||
import net.minecraft.nbt.NBTTagCompound;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
public interface IPersistentInfoProvider {
|
||||
|
||||
public void addInformation(ItemStack stack, NBTTagCompound persistentTag, EntityPlayer player, List list, boolean ext);
|
||||
|
||||
6
src/main/java/com/hbm/blocks/ISpotlight.java
Normal file
6
src/main/java/com/hbm/blocks/ISpotlight.java
Normal file
@ -0,0 +1,6 @@
|
||||
package com.hbm.blocks;
|
||||
|
||||
public interface ISpotlight {
|
||||
|
||||
public int getBeamLength();
|
||||
}
|
||||
@ -1,23 +1,21 @@
|
||||
package com.hbm.blocks;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
import org.lwjgl.input.Keyboard;
|
||||
|
||||
import com.hbm.util.I18nUtil;
|
||||
|
||||
import net.minecraft.block.Block;
|
||||
import net.minecraft.entity.player.EntityPlayer;
|
||||
import net.minecraft.item.EnumRarity;
|
||||
import net.minecraft.item.ItemStack;
|
||||
import net.minecraft.util.EnumChatFormatting;
|
||||
import org.lwjgl.input.Keyboard;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
public interface ITooltipProvider {
|
||||
|
||||
public void addInformation(ItemStack stack, EntityPlayer player, List list, boolean ext);
|
||||
|
||||
public default void addStandardInfo(ItemStack stack, EntityPlayer player, List list, boolean ext) {
|
||||
|
||||
|
||||
if(Keyboard.isKeyDown(Keyboard.KEY_LSHIFT)) {
|
||||
for(String s : I18nUtil.resolveKeyArray(((Block)this).getUnlocalizedName() + ".desc")) list.add(EnumChatFormatting.YELLOW + s);
|
||||
} else {
|
||||
@ -26,7 +24,7 @@ public interface ITooltipProvider {
|
||||
EnumChatFormatting.DARK_GRAY + "" + EnumChatFormatting.ITALIC + "> to display more info");
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
public default EnumRarity getRarity(ItemStack stack) {
|
||||
return EnumRarity.common;
|
||||
}
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@ -2,18 +2,168 @@ package com.hbm.blocks;
|
||||
|
||||
import net.minecraft.block.Block;
|
||||
|
||||
import java.util.Random;
|
||||
|
||||
public class ModSoundType extends Block.SoundType {
|
||||
protected final String placeSound;
|
||||
protected final String breakSound;
|
||||
protected final String stepSound;
|
||||
|
||||
public ModSoundType(String name, float volume, float pitch) {
|
||||
super(name, volume, pitch);
|
||||
protected ModSoundType(String placeSound, String breakSound, String stepSound, float volume, float pitch) {
|
||||
super("", volume, pitch);
|
||||
this.placeSound = placeSound;
|
||||
this.breakSound = breakSound;
|
||||
this.stepSound = stepSound;
|
||||
}
|
||||
|
||||
public ModEnvelopedSoundType enveloped() {
|
||||
return new ModEnvelopedSoundType(placeSound, breakSound, stepSound, volume, frequency);
|
||||
}
|
||||
|
||||
public ModEnvelopedSoundType enveloped(Random random) {
|
||||
return new ModEnvelopedSoundType(placeSound, breakSound, stepSound, volume, frequency, random);
|
||||
}
|
||||
|
||||
@Override
|
||||
public String func_150496_b() {
|
||||
return placeSound;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getBreakSound() {
|
||||
return "hbm:" + super.getBreakSound();
|
||||
return breakSound;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getStepResourcePath() {
|
||||
return "hbm:" + super.getStepResourcePath();
|
||||
return stepSound;
|
||||
}
|
||||
|
||||
// creates a sound type with vanilla-like sound strings name-spaced to the mod
|
||||
public static ModSoundType mod(String soundName, float volume, float pitch) {
|
||||
return new ModSoundType(modDig(soundName), modDig(soundName), modStep(soundName), volume, pitch);
|
||||
}
|
||||
|
||||
// these permutations allow creating a sound type with one of the three sounds being custom
|
||||
// and the other ones defaulting to vanilla-like sound strings name-spaced to the mod
|
||||
|
||||
public static ModSoundType customPlace(String soundName, String placeSound, float volume, float pitch) {
|
||||
return new ModSoundType(placeSound, modDig(soundName), modStep(soundName), volume, pitch);
|
||||
}
|
||||
|
||||
public static ModSoundType customBreak(String soundName, String breakSound, float volume, float pitch) {
|
||||
return new ModSoundType(modDig(soundName), breakSound, modStep(soundName), volume, pitch);
|
||||
}
|
||||
|
||||
public static ModSoundType customStep(String soundName, String stepSound, float volume, float pitch) {
|
||||
return new ModSoundType(modDig(soundName), modDig(soundName), stepSound, volume, pitch);
|
||||
}
|
||||
|
||||
public static ModSoundType customDig(String soundName, String digSound, float volume, float pitch) {
|
||||
return new ModSoundType(digSound, digSound, modStep(soundName), volume, pitch);
|
||||
}
|
||||
|
||||
// these permutations copy sounds from an existing sound type and modify one of the sounds,
|
||||
// but with a manual path for the custom sound
|
||||
|
||||
public static ModSoundType customPlace(Block.SoundType from, String placeSound, float volume, float pitch) {
|
||||
return new ModSoundType(placeSound, from.getBreakSound(), from.getStepResourcePath(), volume, pitch);
|
||||
}
|
||||
|
||||
public static ModSoundType customBreak(Block.SoundType from, String breakSound, float volume, float pitch) {
|
||||
return new ModSoundType(from.func_150496_b(), breakSound, from.getStepResourcePath(), volume, pitch);
|
||||
}
|
||||
|
||||
public static ModSoundType customStep(Block.SoundType from, String stepSound, float volume, float pitch) {
|
||||
return new ModSoundType(from.func_150496_b(), from.getBreakSound(), stepSound, volume, pitch);
|
||||
}
|
||||
|
||||
public static ModSoundType customDig(Block.SoundType from, String dig, float volume, float pitch) {
|
||||
return new ModSoundType(dig, dig, from.getStepResourcePath(), volume, pitch);
|
||||
}
|
||||
|
||||
// customizes all sounds
|
||||
public static ModSoundType placeBreakStep(String placeSound, String breakSound, String stepSound, float volume, float pitch) {
|
||||
return new ModSoundType(placeSound, breakSound, stepSound, volume, pitch);
|
||||
}
|
||||
|
||||
private static String modDig(String soundName) {
|
||||
return "hbm:dig." + soundName;
|
||||
}
|
||||
|
||||
private static String modStep(String soundName) {
|
||||
return "hbm:step." + soundName;
|
||||
}
|
||||
|
||||
public static class ModEnvelopedSoundType extends ModSoundType {
|
||||
private final Random random;
|
||||
|
||||
ModEnvelopedSoundType(String placeSound, String breakSound, String stepSound, float volume, float pitch, Random random) {
|
||||
super(placeSound, breakSound, stepSound, volume, pitch);
|
||||
this.random = random;
|
||||
}
|
||||
|
||||
ModEnvelopedSoundType(String placeSound, String breakSound, String stepSound, float volume, float pitch) {
|
||||
this(placeSound, breakSound, stepSound, volume, pitch, new Random());
|
||||
}
|
||||
|
||||
// a bit of a hack, but most of the time, playSound is called with the sound path queried first, and then volume and pitch
|
||||
private SubType probableSubType = SubType.PLACE;
|
||||
|
||||
@Override
|
||||
public String func_150496_b() {
|
||||
probableSubType = SubType.PLACE;
|
||||
return super.func_150496_b();
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getBreakSound() {
|
||||
probableSubType = SubType.BREAK;
|
||||
return super.getBreakSound();
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getStepResourcePath() {
|
||||
probableSubType = SubType.STEP;
|
||||
return super.getStepResourcePath();
|
||||
}
|
||||
|
||||
private Envelope volumeEnvelope = null;
|
||||
private Envelope pitchEnvelope = null;
|
||||
|
||||
public ModEnvelopedSoundType volumeFunction(Envelope volumeEnvelope) {
|
||||
this.volumeEnvelope = volumeEnvelope;
|
||||
return this;
|
||||
}
|
||||
|
||||
public ModEnvelopedSoundType pitchFunction(Envelope pitchEnvelope) {
|
||||
this.pitchEnvelope = pitchEnvelope;
|
||||
return this;
|
||||
}
|
||||
|
||||
@Override
|
||||
public float getVolume() {
|
||||
if (volumeEnvelope == null)
|
||||
return super.getVolume();
|
||||
else
|
||||
return volumeEnvelope.compute(super.getVolume(), random, probableSubType);
|
||||
}
|
||||
|
||||
@Override
|
||||
public float getPitch() {
|
||||
if (pitchEnvelope == null)
|
||||
return super.getPitch();
|
||||
else
|
||||
return pitchEnvelope.compute(super.getPitch(), random, probableSubType);
|
||||
}
|
||||
|
||||
@FunctionalInterface
|
||||
public interface Envelope {
|
||||
float compute(float in, Random rand, SubType type);
|
||||
}
|
||||
}
|
||||
|
||||
public enum SubType {
|
||||
PLACE, BREAK, STEP
|
||||
}
|
||||
}
|
||||
|
||||
13
src/main/java/com/hbm/blocks/ModSoundTypes.java
Normal file
13
src/main/java/com/hbm/blocks/ModSoundTypes.java
Normal file
@ -0,0 +1,13 @@
|
||||
package com.hbm.blocks;
|
||||
|
||||
import com.hbm.main.MainRegistry;
|
||||
import net.minecraft.block.Block;
|
||||
|
||||
public class ModSoundTypes {
|
||||
|
||||
public static final ModSoundType grate = ModSoundType.customStep(Block.soundTypeStone, "hbm:step.metalBlock", 0.5F, 1.0F);
|
||||
public static final ModSoundType pipe = ModSoundType.customDig(Block.soundTypeMetal, "hbm:block.pipePlaced", 0.85F, 0.85F).enveloped(MainRegistry.instance.rand).pitchFunction((in, rand, type) -> {
|
||||
if(type == ModSoundType.SubType.BREAK) in -= 0.15F;
|
||||
return in + rand.nextFloat() * 0.2F;
|
||||
});
|
||||
}
|
||||
@ -7,8 +7,10 @@ import static net.minecraftforge.common.util.ForgeDirection.SOUTH;
|
||||
import static net.minecraftforge.common.util.ForgeDirection.UP;
|
||||
import static net.minecraftforge.common.util.ForgeDirection.WEST;
|
||||
|
||||
import java.awt.Color;
|
||||
import java.util.Random;
|
||||
|
||||
import com.hbm.blocks.ModBlocks;
|
||||
import com.hbm.potion.HbmPotion;
|
||||
|
||||
import cpw.mods.fml.relauncher.Side;
|
||||
@ -25,193 +27,146 @@ import net.minecraft.world.World;
|
||||
import net.minecraftforge.common.util.ForgeDirection;
|
||||
|
||||
public class Balefire extends BlockFire {
|
||||
|
||||
private IIcon icon;
|
||||
|
||||
public Balefire() {
|
||||
super();
|
||||
}
|
||||
|
||||
@SideOnly(Side.CLIENT)
|
||||
public void registerBlockIcons(IIconRegister register) {
|
||||
icon = register.registerIcon(this.getTextureName());
|
||||
}
|
||||
|
||||
@SideOnly(Side.CLIENT)
|
||||
public IIcon getFireIcon(int i) {
|
||||
return icon;
|
||||
}
|
||||
|
||||
@SideOnly(Side.CLIENT)
|
||||
public IIcon getIcon(int side, int meta) {
|
||||
return icon;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void updateTick(World world, int x, int y, int z, Random rand) {
|
||||
if(world.getGameRules().getGameRuleBooleanValue("doFireTick")) {
|
||||
|
||||
if(!this.canPlaceBlockAt(world, x, y, z)) {
|
||||
world.setBlockToAir(x, y, z);
|
||||
}
|
||||
|
||||
int meta = world.getBlockMetadata(x, y, z);
|
||||
|
||||
if(meta < 15) world.scheduleBlockUpdate(x, y, z, this, this.tickRate(world) + rand.nextInt(10));
|
||||
|
||||
if(!this.canNeighborBurn(world, x, y, z) && !World.doesBlockHaveSolidTopSurface(world, x, y - 1, z)) {
|
||||
world.setBlockToAir(x, y, z);
|
||||
} else {
|
||||
if(meta < 15) {
|
||||
this.tryCatchFire(world, x + 1, y, z, 500, rand, meta, WEST);
|
||||
this.tryCatchFire(world, x - 1, y, z, 500, rand, meta, EAST);
|
||||
this.tryCatchFire(world, x, y - 1, z, 300, rand, meta, UP);
|
||||
this.tryCatchFire(world, x, y + 1, z, 300, rand, meta, DOWN);
|
||||
this.tryCatchFire(world, x, y, z - 1, 500, rand, meta, SOUTH);
|
||||
this.tryCatchFire(world, x, y, z + 1, 500, rand, meta, NORTH);
|
||||
|
||||
int h = 3;
|
||||
|
||||
for(int ix = x - h; ix <= x + h; ++ix) {
|
||||
for(int iz = z - h; iz <= z + h; ++iz) {
|
||||
for(int iy = y - 1; iy <= y + 4; ++iy) {
|
||||
|
||||
if(ix != x || iy != y || iz != z) {
|
||||
int fireLimit = 100;
|
||||
|
||||
if(iy > y + 1) {
|
||||
fireLimit += (iy - (y + 1)) * 100;
|
||||
}
|
||||
|
||||
if(world.getBlock(ix, iy, iz) == ModBlocks.balefire && world.getBlockMetadata(ix, iy, iz) > meta + 1) {
|
||||
world.setBlock(ix, iy, iz, this, meta + 1, 3);
|
||||
continue;
|
||||
}
|
||||
|
||||
int neighborFireChance = this.getChanceOfNeighborsEncouragingFire(world, ix, iy, iz);
|
||||
|
||||
if(neighborFireChance > 0) {
|
||||
int adjustedFireChance = (neighborFireChance + 40 + world.difficultySetting.getDifficultyId() * 7) / (meta + 30);
|
||||
|
||||
if(adjustedFireChance > 0 && rand.nextInt(fireLimit) <= adjustedFireChance) {
|
||||
world.setBlock(ix, iy, iz, this, meta + 1, 3);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private void tryCatchFire(World world, int x, int y, int z, int chance, Random rand, int fireMetadata, ForgeDirection face) {
|
||||
int flammability = world.getBlock(x, y, z).getFlammability(world, x, y, z, face);
|
||||
|
||||
if(rand.nextInt(chance) < flammability) {
|
||||
boolean flag = world.getBlock(x, y, z) == Blocks.tnt;
|
||||
|
||||
world.setBlock(x, y, z, this, fireMetadata + 1, 3);
|
||||
|
||||
if(flag) {
|
||||
Blocks.tnt.onBlockDestroyedByPlayer(world, x, y, z, 1);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private boolean canNeighborBurn(World world, int x, int y, int z) {
|
||||
return this.canCatchFire(world, x + 1, y, z, WEST)
|
||||
|| this.canCatchFire(world, x - 1, y, z, EAST)
|
||||
|| this.canCatchFire(world, x, y - 1, z, UP)
|
||||
|| this.canCatchFire(world, x, y + 1, z, DOWN)
|
||||
|| this.canCatchFire(world, x, y, z - 1, SOUTH)
|
||||
|| this.canCatchFire(world, x, y, z + 1, NORTH);
|
||||
}
|
||||
|
||||
private int getChanceOfNeighborsEncouragingFire(World world, int x, int y, int z) {
|
||||
|
||||
if(!world.isAirBlock(x, y, z)) {
|
||||
return 0;
|
||||
} else {
|
||||
int spread = 0;
|
||||
spread = this.getChanceToEncourageFire(world, x + 1, y, z, spread, WEST);
|
||||
spread = this.getChanceToEncourageFire(world, x - 1, y, z, spread, EAST);
|
||||
spread = this.getChanceToEncourageFire(world, x, y - 1, z, spread, UP);
|
||||
spread = this.getChanceToEncourageFire(world, x, y + 1, z, spread, DOWN);
|
||||
spread = this.getChanceToEncourageFire(world, x, y, z - 1, spread, SOUTH);
|
||||
spread = this.getChanceToEncourageFire(world, x, y, z + 1, spread, NORTH);
|
||||
return spread;
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean canCatchFire(IBlockAccess world, int x, int y, int z, ForgeDirection face) {
|
||||
return world.getBlock(x, y, z).isFlammable(world, x, y, z, face);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onEntityCollidedWithBlock(World world, int x, int y, int z, Entity entity) {
|
||||
entity.setFire(10);
|
||||
|
||||
if(entity instanceof EntityLivingBase) ((EntityLivingBase) entity).addPotionEffect(new PotionEffect(HbmPotion.radiation.id, 5 * 20, 9));
|
||||
}
|
||||
|
||||
private IIcon field_149850_M;
|
||||
|
||||
public Balefire()
|
||||
{
|
||||
super();
|
||||
}
|
||||
|
||||
@SideOnly(Side.CLIENT)
|
||||
public void registerBlockIcons(IIconRegister p_149651_1_) {
|
||||
|
||||
field_149850_M = p_149651_1_.registerIcon(this.getTextureName());
|
||||
}
|
||||
|
||||
@SideOnly(Side.CLIENT)
|
||||
public IIcon getFireIcon(int p_149840_1_)
|
||||
{
|
||||
return field_149850_M;
|
||||
}
|
||||
|
||||
@SideOnly(Side.CLIENT)
|
||||
public IIcon getIcon(int p_149691_1_, int p_149691_2_)
|
||||
{
|
||||
return field_149850_M;
|
||||
}
|
||||
public void updateTick(World p_149674_1_, int p_149674_2_, int p_149674_3_, int p_149674_4_, Random p_149674_5_)
|
||||
{
|
||||
if (p_149674_1_.getGameRules().getGameRuleBooleanValue("doFireTick"))
|
||||
{
|
||||
boolean flag = p_149674_1_.getBlock(p_149674_2_, p_149674_3_ - 1, p_149674_4_).isFireSource(p_149674_1_, p_149674_2_, p_149674_3_ - 1, p_149674_4_, UP);
|
||||
|
||||
if (!this.canPlaceBlockAt(p_149674_1_, p_149674_2_, p_149674_3_, p_149674_4_))
|
||||
{
|
||||
p_149674_1_.setBlockToAir(p_149674_2_, p_149674_3_, p_149674_4_);
|
||||
}
|
||||
|
||||
/*if (!flag && p_149674_1_.isRaining() && (p_149674_1_.canLightningStrikeAt(p_149674_2_, p_149674_3_, p_149674_4_) || p_149674_1_.canLightningStrikeAt(p_149674_2_ - 1, p_149674_3_, p_149674_4_) || p_149674_1_.canLightningStrikeAt(p_149674_2_ + 1, p_149674_3_, p_149674_4_) || p_149674_1_.canLightningStrikeAt(p_149674_2_, p_149674_3_, p_149674_4_ - 1) || p_149674_1_.canLightningStrikeAt(p_149674_2_, p_149674_3_, p_149674_4_ + 1)))
|
||||
{
|
||||
p_149674_1_.setBlockToAir(p_149674_2_, p_149674_3_, p_149674_4_);
|
||||
}
|
||||
else*/
|
||||
{
|
||||
int l = 0;
|
||||
/*int l = p_149674_1_.getBlockMetadata(p_149674_2_, p_149674_3_, p_149674_4_);
|
||||
|
||||
if (l < 15)
|
||||
{
|
||||
p_149674_1_.setBlockMetadataWithNotify(p_149674_2_, p_149674_3_, p_149674_4_, l + p_149674_5_.nextInt(3) / 2, 4);
|
||||
}*/
|
||||
|
||||
p_149674_1_.scheduleBlockUpdate(p_149674_2_, p_149674_3_, p_149674_4_, this, this.tickRate(p_149674_1_) + p_149674_5_.nextInt(10));
|
||||
|
||||
if (!flag && !this.canNeighborBurn(p_149674_1_, p_149674_2_, p_149674_3_, p_149674_4_))
|
||||
{
|
||||
if (!World.doesBlockHaveSolidTopSurface(p_149674_1_, p_149674_2_, p_149674_3_ - 1, p_149674_4_)/* || l > 3*/)
|
||||
{
|
||||
p_149674_1_.setBlockToAir(p_149674_2_, p_149674_3_, p_149674_4_);
|
||||
}
|
||||
}
|
||||
/*else if (!flag && !this.canCatchFire(p_149674_1_, p_149674_2_, p_149674_3_ - 1, p_149674_4_, UP) && l == 15 && p_149674_5_.nextInt(4) == 0)
|
||||
{
|
||||
//p_149674_1_.setBlockToAir(p_149674_2_, p_149674_3_, p_149674_4_);
|
||||
}*/
|
||||
else
|
||||
{
|
||||
//boolean flag1 = p_149674_1_.isBlockHighHumidity(p_149674_2_, p_149674_3_, p_149674_4_);
|
||||
byte b0 = 0;
|
||||
|
||||
/*if (flag1)
|
||||
{
|
||||
b0 = -50;
|
||||
}*/
|
||||
|
||||
this.tryCatchFire(p_149674_1_, p_149674_2_ + 1, p_149674_3_, p_149674_4_, 300 + b0, p_149674_5_, l, WEST );
|
||||
this.tryCatchFire(p_149674_1_, p_149674_2_ - 1, p_149674_3_, p_149674_4_, 300 + b0, p_149674_5_, l, EAST );
|
||||
this.tryCatchFire(p_149674_1_, p_149674_2_, p_149674_3_ - 1, p_149674_4_, 250 + b0, p_149674_5_, l, UP );
|
||||
this.tryCatchFire(p_149674_1_, p_149674_2_, p_149674_3_ + 1, p_149674_4_, 250 + b0, p_149674_5_, l, DOWN );
|
||||
this.tryCatchFire(p_149674_1_, p_149674_2_, p_149674_3_, p_149674_4_ - 1, 300 + b0, p_149674_5_, l, SOUTH);
|
||||
this.tryCatchFire(p_149674_1_, p_149674_2_, p_149674_3_, p_149674_4_ + 1, 300 + b0, p_149674_5_, l, NORTH);
|
||||
|
||||
for (int i1 = p_149674_2_ - 1; i1 <= p_149674_2_ + 1; ++i1)
|
||||
{
|
||||
for (int j1 = p_149674_4_ - 1; j1 <= p_149674_4_ + 1; ++j1)
|
||||
{
|
||||
for (int k1 = p_149674_3_ - 1; k1 <= p_149674_3_ + 4; ++k1)
|
||||
{
|
||||
if (i1 != p_149674_2_ || k1 != p_149674_3_ || j1 != p_149674_4_)
|
||||
{
|
||||
int l1 = 100;
|
||||
|
||||
if (k1 > p_149674_3_ + 1)
|
||||
{
|
||||
l1 += (k1 - (p_149674_3_ + 1)) * 100;
|
||||
}
|
||||
|
||||
int i2 = this.getChanceOfNeighborsEncouragingFire(p_149674_1_, i1, k1, j1);
|
||||
|
||||
if (i2 > 0)
|
||||
{
|
||||
int j2 = (i2 + 40 + p_149674_1_.difficultySetting.getDifficultyId() * 7) / (l + 30);
|
||||
|
||||
/*if (flag1)
|
||||
{
|
||||
j2 /= 2;
|
||||
}*/
|
||||
|
||||
if (j2 > 0 && p_149674_5_.nextInt(l1) <= j2)
|
||||
{
|
||||
int k2 = l + p_149674_5_.nextInt(5) / 4;
|
||||
|
||||
if (k2 > 15)
|
||||
{
|
||||
k2 = 15;
|
||||
}
|
||||
|
||||
p_149674_1_.setBlock(i1, k1, j1, this, k2, 3);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private void tryCatchFire(World p_149841_1_, int p_149841_2_, int p_149841_3_, int p_149841_4_, int p_149841_5_, Random p_149841_6_, int p_149841_7_, ForgeDirection face)
|
||||
{
|
||||
int j1 = p_149841_1_.getBlock(p_149841_2_, p_149841_3_, p_149841_4_).getFlammability(p_149841_1_, p_149841_2_, p_149841_3_, p_149841_4_, face);
|
||||
|
||||
if (p_149841_6_.nextInt(p_149841_5_) < j1)
|
||||
{
|
||||
boolean flag = p_149841_1_.getBlock(p_149841_2_, p_149841_3_, p_149841_4_) == Blocks.tnt;
|
||||
|
||||
p_149841_1_.setBlock(p_149841_2_, p_149841_3_, p_149841_4_, this, 15, 3);
|
||||
|
||||
if (flag)
|
||||
{
|
||||
Blocks.tnt.onBlockDestroyedByPlayer(p_149841_1_, p_149841_2_, p_149841_3_, p_149841_4_, 1);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private boolean canNeighborBurn(World p_149847_1_, int p_149847_2_, int p_149847_3_, int p_149847_4_)
|
||||
{
|
||||
return this.canCatchFire(p_149847_1_, p_149847_2_ + 1, p_149847_3_, p_149847_4_, WEST ) ||
|
||||
this.canCatchFire(p_149847_1_, p_149847_2_ - 1, p_149847_3_, p_149847_4_, EAST ) ||
|
||||
this.canCatchFire(p_149847_1_, p_149847_2_, p_149847_3_ - 1, p_149847_4_, UP ) ||
|
||||
this.canCatchFire(p_149847_1_, p_149847_2_, p_149847_3_ + 1, p_149847_4_, DOWN ) ||
|
||||
this.canCatchFire(p_149847_1_, p_149847_2_, p_149847_3_, p_149847_4_ - 1, SOUTH) ||
|
||||
this.canCatchFire(p_149847_1_, p_149847_2_, p_149847_3_, p_149847_4_ + 1, NORTH);
|
||||
}
|
||||
|
||||
private int getChanceOfNeighborsEncouragingFire(World p_149845_1_, int p_149845_2_, int p_149845_3_, int p_149845_4_)
|
||||
{
|
||||
byte b0 = 0;
|
||||
|
||||
if (!p_149845_1_.isAirBlock(p_149845_2_, p_149845_3_, p_149845_4_))
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
else
|
||||
{
|
||||
int l = b0;
|
||||
l = this.getChanceToEncourageFire(p_149845_1_, p_149845_2_ + 1, p_149845_3_, p_149845_4_, l, WEST );
|
||||
l = this.getChanceToEncourageFire(p_149845_1_, p_149845_2_ - 1, p_149845_3_, p_149845_4_, l, EAST );
|
||||
l = this.getChanceToEncourageFire(p_149845_1_, p_149845_2_, p_149845_3_ - 1, p_149845_4_, l, UP );
|
||||
l = this.getChanceToEncourageFire(p_149845_1_, p_149845_2_, p_149845_3_ + 1, p_149845_4_, l, DOWN );
|
||||
l = this.getChanceToEncourageFire(p_149845_1_, p_149845_2_, p_149845_3_, p_149845_4_ - 1, l, SOUTH);
|
||||
l = this.getChanceToEncourageFire(p_149845_1_, p_149845_2_, p_149845_3_, p_149845_4_ + 1, l, NORTH);
|
||||
return l;
|
||||
}
|
||||
}
|
||||
|
||||
public boolean canCatchFire(IBlockAccess world, int x, int y, int z, ForgeDirection face)
|
||||
{
|
||||
return world.getBlock(x, y, z).isFlammable(world, x, y, z, face);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onEntityCollidedWithBlock(World p_149670_1_, int p_149670_2_, int p_149670_3_, int p_149670_4_, Entity p_149670_5_)
|
||||
{
|
||||
p_149670_5_.setFire(10);
|
||||
|
||||
if(p_149670_5_ instanceof EntityLivingBase)
|
||||
((EntityLivingBase)p_149670_5_).addPotionEffect(new PotionEffect(HbmPotion.radiation.id, 5 * 20, 9));
|
||||
}
|
||||
@SideOnly(Side.CLIENT)
|
||||
public int colorMultiplier(IBlockAccess world, int x, int y, int z) {
|
||||
int meta = world.getBlockMetadata(x, y, z);
|
||||
return Color.HSBtoRGB(0F, 0F, 1F - meta / 30F);
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getRenderType() {
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
|
||||
@ -8,6 +8,6 @@ public class BlockC4 extends BlockTNTBase {
|
||||
|
||||
@Override
|
||||
public void explodeEntity(World world, double x, double y, double z, EntityTNTPrimedBase entity) {
|
||||
world.createExplosion(entity, x, y, z, 26F, true);
|
||||
world.createExplosion(entity, x, y, z, 15F, true);
|
||||
}
|
||||
}
|
||||
|
||||
@ -12,10 +12,13 @@ import java.util.Random;
|
||||
|
||||
import com.hbm.blocks.BlockContainerBase;
|
||||
import com.hbm.blocks.ITooltipProvider;
|
||||
import com.hbm.entity.item.EntityTNTPrimedBase;
|
||||
import com.hbm.interfaces.IBomb;
|
||||
import com.hbm.tileentity.bomb.TileEntityCharge;
|
||||
|
||||
import api.hbm.block.IFuckingExplode;
|
||||
import api.hbm.block.IToolable;
|
||||
import net.minecraft.util.MathHelper;
|
||||
import net.minecraft.block.Block;
|
||||
import net.minecraft.block.material.Material;
|
||||
import net.minecraft.entity.player.EntityPlayer;
|
||||
@ -29,7 +32,7 @@ import net.minecraft.world.IBlockAccess;
|
||||
import net.minecraft.world.World;
|
||||
import net.minecraftforge.common.util.ForgeDirection;
|
||||
|
||||
public abstract class BlockChargeBase extends BlockContainerBase implements IBomb, IToolable, ITooltipProvider {
|
||||
public abstract class BlockChargeBase extends BlockContainerBase implements IBomb, IToolable, ITooltipProvider, IFuckingExplode {
|
||||
|
||||
public static boolean safe = false;
|
||||
|
||||
@ -134,8 +137,18 @@ public abstract class BlockChargeBase extends BlockContainerBase implements IBom
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onBlockDestroyedByExplosion(World world, int x, int y, int z, Explosion p_149723_5_) {
|
||||
this.explode(world, x, y, z);
|
||||
public void onBlockDestroyedByExplosion(World world, int x, int y, int z, Explosion explosion) {
|
||||
if(!world.isRemote) {
|
||||
EntityTNTPrimedBase tntPrimed = new EntityTNTPrimedBase(world, x + 0.5D, y + 0.5D, z + 0.5D, explosion != null ? explosion.getExplosivePlacedBy() : null, this);
|
||||
tntPrimed.fuse = 0;
|
||||
tntPrimed.detonateOnCollision = false;
|
||||
world.spawnEntityInWorld(tntPrimed);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void explodeEntity(World world, double x, double y, double z, EntityTNTPrimedBase entity) {
|
||||
explode(world, MathHelper.floor_double(x), MathHelper.floor_double(y), MathHelper.floor_double(z));
|
||||
}
|
||||
|
||||
@Override
|
||||
|
||||
@ -5,6 +5,9 @@ import java.util.List;
|
||||
import com.hbm.explosion.vanillant.ExplosionVNT;
|
||||
import com.hbm.explosion.vanillant.standard.BlockAllocatorStandard;
|
||||
import com.hbm.explosion.vanillant.standard.BlockProcessorStandard;
|
||||
import com.hbm.explosion.vanillant.standard.EntityProcessorStandard;
|
||||
import com.hbm.explosion.vanillant.standard.PlayerProcessorStandard;
|
||||
import com.hbm.particle.helper.ExplosionCreator;
|
||||
|
||||
import cpw.mods.fml.client.registry.RenderingRegistry;
|
||||
import net.minecraft.entity.player.EntityPlayer;
|
||||
@ -22,10 +25,13 @@ public class BlockChargeC4 extends BlockChargeBase {
|
||||
world.setBlockToAir(x, y, z);
|
||||
safe = false;
|
||||
|
||||
ExplosionVNT xnt = new ExplosionVNT(world, x + 0.5, y + 0.5, z + 0.5, 15F).makeStandard();
|
||||
ExplosionVNT xnt = new ExplosionVNT(world, x + 0.5, y + 0.5, z + 0.5, 15F);
|
||||
xnt.setBlockAllocator(new BlockAllocatorStandard(32));
|
||||
xnt.setBlockProcessor(new BlockProcessorStandard().setNoDrop());
|
||||
xnt.setEntityProcessor(new EntityProcessorStandard());
|
||||
xnt.setPlayerProcessor(new PlayerProcessorStandard());
|
||||
xnt.explode();
|
||||
ExplosionCreator.composeEffectSmall(world, x + 0.5, y + 1, z + 0.5);
|
||||
|
||||
return BombReturnCode.DETONATED;
|
||||
}
|
||||
|
||||
@ -1,7 +1,7 @@
|
||||
package com.hbm.blocks.bomb;
|
||||
|
||||
import com.hbm.explosion.ExplosionLarge;
|
||||
import com.hbm.explosion.ExplosionNT;
|
||||
import com.hbm.particle.helper.ExplosionSmallCreator;
|
||||
|
||||
import cpw.mods.fml.client.registry.RenderingRegistry;
|
||||
import net.minecraft.world.World;
|
||||
@ -17,7 +17,7 @@ public class BlockChargeDynamite extends BlockChargeBase {
|
||||
safe = false;
|
||||
ExplosionNT exp = new ExplosionNT(world, null, x + 0.5, y + 0.5, z + 0.5, 4F);
|
||||
exp.explode();
|
||||
ExplosionLarge.spawnParticles(world, x + 0.5, y + 0.5, z + 0.5, 20);
|
||||
ExplosionSmallCreator.composeEffect(world, x + 0.5, y + 0.5, z + 0.5, 15, 3F, 1.25F);
|
||||
|
||||
return BombReturnCode.DETONATED;
|
||||
}
|
||||
|
||||
@ -2,9 +2,9 @@ package com.hbm.blocks.bomb;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
import com.hbm.explosion.ExplosionLarge;
|
||||
import com.hbm.explosion.ExplosionNT;
|
||||
import com.hbm.explosion.ExplosionNT.ExAttrib;
|
||||
import com.hbm.particle.helper.ExplosionSmallCreator;
|
||||
|
||||
import net.minecraft.entity.player.EntityPlayer;
|
||||
import net.minecraft.item.ItemStack;
|
||||
@ -23,7 +23,7 @@ public class BlockChargeMiner extends BlockChargeBase {
|
||||
ExplosionNT exp = new ExplosionNT(world, null, x + 0.5, y + 0.5, z + 0.5, 4F);
|
||||
exp.addAllAttrib(ExAttrib.NOHURT, ExAttrib.ALLDROP);
|
||||
exp.explode();
|
||||
ExplosionLarge.spawnParticles(world, x + 0.5, y + 0.5, z + 0.5, 20);
|
||||
ExplosionSmallCreator.composeEffect(world, x + 0.5, y + 0.5, z + 0.5, 15, 3F, 1.25F);
|
||||
|
||||
return BombReturnCode.DETONATED;
|
||||
}
|
||||
|
||||
@ -5,7 +5,7 @@ import java.util.List;
|
||||
import com.hbm.explosion.vanillant.ExplosionVNT;
|
||||
import com.hbm.explosion.vanillant.standard.BlockAllocatorStandard;
|
||||
import com.hbm.explosion.vanillant.standard.BlockProcessorStandard;
|
||||
import com.hbm.explosion.vanillant.standard.ExplosionEffectStandard;
|
||||
import com.hbm.particle.helper.ExplosionCreator;
|
||||
|
||||
import net.minecraft.entity.player.EntityPlayer;
|
||||
import net.minecraft.item.ItemStack;
|
||||
@ -27,8 +27,8 @@ public class BlockChargeSemtex extends BlockChargeBase {
|
||||
xnt.setBlockProcessor(new BlockProcessorStandard()
|
||||
.setAllDrop()
|
||||
.setFortune(3));
|
||||
xnt.setSFX(new ExplosionEffectStandard());
|
||||
xnt.explode();
|
||||
ExplosionCreator.composeEffectSmall(world, x + 0.5, y + 1, z + 0.5);
|
||||
|
||||
return BombReturnCode.DETONATED;
|
||||
}
|
||||
|
||||
@ -1,90 +0,0 @@
|
||||
package com.hbm.blocks.bomb;
|
||||
|
||||
import java.util.Random;
|
||||
|
||||
import com.hbm.blocks.ModBlocks;
|
||||
import com.hbm.items.ModItems;
|
||||
|
||||
import net.minecraft.block.Block;
|
||||
import net.minecraft.block.material.MapColor;
|
||||
import net.minecraft.block.material.Material;
|
||||
import net.minecraft.item.Item;
|
||||
import net.minecraft.util.AxisAlignedBB;
|
||||
import net.minecraft.world.World;
|
||||
|
||||
public class BlockCloudResidue extends Block {
|
||||
|
||||
public BlockCloudResidue(Material p_i45386_1_) {
|
||||
super(p_i45386_1_);
|
||||
}
|
||||
|
||||
public static int func_150032_b(int p_150032_0_)
|
||||
{
|
||||
return func_150031_c(p_150032_0_);
|
||||
}
|
||||
|
||||
public static int func_150031_c(int p_150031_0_)
|
||||
{
|
||||
return p_150031_0_ & 15;
|
||||
}
|
||||
|
||||
public MapColor getMapColor(int p_149728_1_)
|
||||
{
|
||||
return MapColor.redColor;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getRenderType(){
|
||||
return ModBlocks.taint.getRenderType();
|
||||
}
|
||||
|
||||
@Override
|
||||
public Item getItemDropped(int p_149650_1_, Random p_149650_2_, int p_149650_3_)
|
||||
{
|
||||
return p_149650_2_.nextInt(25) == 0 ? ModItems.powder_cloud : null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isOpaqueCube() {
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean renderAsNormalBlock() {
|
||||
return false;
|
||||
}
|
||||
|
||||
public void onNeighborBlockChange(World world, int x, int y, int z, Block b)
|
||||
{
|
||||
if(!hasPosNeightbour(world, x, y, z) && !world.isRemote)
|
||||
world.setBlockToAir(x, y, z);
|
||||
}
|
||||
|
||||
public static boolean hasPosNeightbour(World world, int x, int y, int z) {
|
||||
Block b0 = world.getBlock(x + 1, y, z);
|
||||
Block b1 = world.getBlock(x, y + 1, z);
|
||||
Block b2 = world.getBlock(x, y, z + 1);
|
||||
Block b3 = world.getBlock(x - 1, y, z);
|
||||
Block b4 = world.getBlock(x, y - 1, z);
|
||||
Block b5 = world.getBlock(x, y, z - 1);
|
||||
boolean b = (b0.renderAsNormalBlock() && b0.getMaterial().isOpaque()) ||
|
||||
(b1.renderAsNormalBlock() && b1.getMaterial().isOpaque()) ||
|
||||
(b2.renderAsNormalBlock() && b2.getMaterial().isOpaque()) ||
|
||||
(b3.renderAsNormalBlock() && b3.getMaterial().isOpaque()) ||
|
||||
(b4.renderAsNormalBlock() && b4.getMaterial().isOpaque()) ||
|
||||
(b5.renderAsNormalBlock() && b5.getMaterial().isOpaque());
|
||||
return b;
|
||||
}
|
||||
|
||||
@Override
|
||||
public AxisAlignedBB getCollisionBoundingBoxFromPool(World par1World, int par2, int par3, int par4)
|
||||
{
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public AxisAlignedBB getSelectedBoundingBoxFromPool(World par1World, int par2, int par3, int par4)
|
||||
{
|
||||
return AxisAlignedBB.getBoundingBox(par2, par3, par4, par2, par3, par4);
|
||||
}
|
||||
}
|
||||
@ -7,8 +7,8 @@ import com.hbm.config.BombConfig;
|
||||
import com.hbm.entity.logic.EntityBalefire;
|
||||
import com.hbm.interfaces.IBomb;
|
||||
import com.hbm.items.ModItems;
|
||||
import com.hbm.packet.AuxParticlePacketNT;
|
||||
import com.hbm.packet.PacketDispatcher;
|
||||
import com.hbm.packet.toclient.AuxParticlePacketNT;
|
||||
import com.hbm.tileentity.bomb.TileEntityCrashedBomb;
|
||||
|
||||
import cpw.mods.fml.common.network.NetworkRegistry.TargetPoint;
|
||||
@ -98,7 +98,7 @@ public class BlockCrashedBomb extends BlockContainer implements IBomb {
|
||||
if(!world.isRemote) {
|
||||
|
||||
world.setBlockToAir(x, y, z);
|
||||
EntityBalefire bf = new EntityBalefire(world).mute();
|
||||
EntityBalefire bf = new EntityBalefire(world);
|
||||
bf.posX = x;
|
||||
bf.posY = y;
|
||||
bf.posZ = z;
|
||||
|
||||
55
src/main/java/com/hbm/blocks/bomb/BlockDetonatable.java
Normal file
55
src/main/java/com/hbm/blocks/bomb/BlockDetonatable.java
Normal file
@ -0,0 +1,55 @@
|
||||
package com.hbm.blocks.bomb;
|
||||
|
||||
import com.hbm.blocks.generic.BlockFlammable;
|
||||
import com.hbm.entity.item.EntityTNTPrimedBase;
|
||||
|
||||
import api.hbm.block.IFuckingExplode;
|
||||
import net.minecraft.block.Block;
|
||||
import net.minecraft.block.material.Material;
|
||||
import net.minecraft.world.Explosion;
|
||||
import net.minecraft.world.World;
|
||||
|
||||
public abstract class BlockDetonatable extends BlockFlammable implements IFuckingExplode {
|
||||
|
||||
protected int popFuse; // A shorter fuse for when this explosive is dinked by another
|
||||
protected boolean detonateOnCollision;
|
||||
protected boolean detonateOnShot;
|
||||
|
||||
public BlockDetonatable(Material mat, int en, int flam, int popFuse, boolean detonateOnCollision, boolean detonateOnShot) {
|
||||
super(mat, en, flam);
|
||||
this.popFuse = popFuse;
|
||||
this.detonateOnCollision = detonateOnCollision;
|
||||
this.detonateOnShot = detonateOnShot;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onBlockDestroyedByExplosion(World world, int x, int y, int z, Explosion explosion) {
|
||||
if(!world.isRemote) {
|
||||
EntityTNTPrimedBase tntPrimed = new EntityTNTPrimedBase(world, x + 0.5D, y + 0.5D, z + 0.5D, explosion != null ? explosion.getExplosivePlacedBy() : null, this);
|
||||
tntPrimed.fuse = popFuse <= 0 ? 0 : world.rand.nextInt(popFuse) + popFuse / 2;
|
||||
tntPrimed.detonateOnCollision = detonateOnCollision;
|
||||
world.spawnEntityInWorld(tntPrimed);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean canDropFromExplosion(Explosion explosion) {
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onNeighborBlockChange(World world, int x, int y, int z, Block block) {
|
||||
if(!world.isRemote && shouldIgnite(world, x, y, z)) {
|
||||
world.setBlockToAir(x, y, z);
|
||||
onBlockDestroyedByExplosion(world, x, y, z, null);
|
||||
}
|
||||
}
|
||||
|
||||
public void onShot(World world, int x, int y, int z) {
|
||||
if (!detonateOnShot) return;
|
||||
|
||||
world.setBlockToAir(x, y, z);
|
||||
explodeEntity(world, x, y, z, null); // insta-explod
|
||||
}
|
||||
|
||||
}
|
||||
@ -1,7 +1,8 @@
|
||||
package com.hbm.blocks.bomb;
|
||||
|
||||
import com.hbm.explosion.ExplosionLarge;
|
||||
import com.hbm.explosion.ExplosionNT;
|
||||
import com.hbm.entity.item.EntityTNTPrimedBase;
|
||||
import com.hbm.explosion.vanillant.ExplosionVNT;
|
||||
import com.hbm.explosion.vanillant.standard.BlockProcessorStandard;
|
||||
import com.hbm.interfaces.IBomb;
|
||||
|
||||
import cpw.mods.fml.relauncher.Side;
|
||||
@ -13,17 +14,16 @@ import net.minecraft.entity.EntityLivingBase;
|
||||
import net.minecraft.item.ItemStack;
|
||||
import net.minecraft.util.IIcon;
|
||||
import net.minecraft.util.MathHelper;
|
||||
import net.minecraft.world.Explosion;
|
||||
import net.minecraft.world.World;
|
||||
import net.minecraftforge.common.util.ForgeDirection;
|
||||
|
||||
public class BlockPlasticExplosive extends Block implements IBomb {
|
||||
public class BlockPlasticExplosive extends BlockDetonatable implements IBomb {
|
||||
|
||||
@SideOnly(Side.CLIENT)
|
||||
private IIcon topIcon;
|
||||
|
||||
public BlockPlasticExplosive(Material mat) {
|
||||
super(mat);
|
||||
super(mat, 0, 0, 0, false, false);
|
||||
}
|
||||
|
||||
@SideOnly(Side.CLIENT)
|
||||
@ -68,12 +68,7 @@ public class BlockPlasticExplosive extends Block implements IBomb {
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onBlockDestroyedByExplosion(World world, int x, int y, int z, Explosion explosion) {
|
||||
this.explode(world, x, y, z);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onNeighborBlockChange(World world, int x, int y, int z, Block p_149695_5_) {
|
||||
public void onNeighborBlockChange(World world, int x, int y, int z, Block block) {
|
||||
if(world.isBlockIndirectlyGettingPowered(x, y, z)) {
|
||||
this.explode(world, x, y, z);
|
||||
}
|
||||
@ -83,10 +78,14 @@ public class BlockPlasticExplosive extends Block implements IBomb {
|
||||
public BombReturnCode explode(World world, int x, int y, int z) {
|
||||
|
||||
if(!world.isRemote) {
|
||||
new ExplosionNT(world, null, x + 0.5, y + 0.5, z + 0.5, 50).overrideResolution(64).explode();
|
||||
ExplosionLarge.spawnParticles(world, x, y, z, ExplosionLarge.cloudFunction(15));
|
||||
new ExplosionVNT(world, x + 0.5, y + 0.5, z + 0.5, 20).makeStandard().setBlockProcessor(new BlockProcessorStandard().setNoDrop()).explode();
|
||||
}
|
||||
|
||||
return BombReturnCode.DETONATED;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void explodeEntity(World world, double x, double y, double z, EntityTNTPrimedBase entity) {
|
||||
explode(world, MathHelper.floor_double(x), MathHelper.floor_double(y), MathHelper.floor_double(z));
|
||||
}
|
||||
}
|
||||
|
||||
@ -8,6 +8,6 @@ public class BlockSemtex extends BlockTNTBase {
|
||||
|
||||
@Override
|
||||
public void explodeEntity(World world, double x, double y, double z, EntityTNTPrimedBase entity) {
|
||||
world.createExplosion(entity, x, y, z, 20F, true);
|
||||
world.createExplosion(entity, x, y, z, 12F, true);
|
||||
}
|
||||
}
|
||||
|
||||
@ -8,6 +8,6 @@ public class BlockTNT extends BlockTNTBase {
|
||||
|
||||
@Override
|
||||
public void explodeEntity(World world, double x, double y, double z, EntityTNTPrimedBase entity) {
|
||||
world.createExplosion(entity, x, y, z, 12F, true);
|
||||
world.createExplosion(entity, x, y, z, 10F, true);
|
||||
}
|
||||
}
|
||||
|
||||
@ -2,7 +2,6 @@ package com.hbm.blocks.bomb;
|
||||
|
||||
import java.util.Random;
|
||||
|
||||
import com.hbm.blocks.generic.BlockFlammable;
|
||||
import com.hbm.entity.item.EntityTNTPrimedBase;
|
||||
import com.hbm.util.ChatBuilder;
|
||||
|
||||
@ -19,16 +18,15 @@ import net.minecraft.entity.projectile.EntityArrow;
|
||||
import net.minecraft.init.Items;
|
||||
import net.minecraft.util.EnumChatFormatting;
|
||||
import net.minecraft.util.IIcon;
|
||||
import net.minecraft.world.Explosion;
|
||||
import net.minecraft.world.World;
|
||||
|
||||
public abstract class BlockTNTBase extends BlockFlammable implements IToolable {
|
||||
public abstract class BlockTNTBase extends BlockDetonatable implements IToolable {
|
||||
|
||||
@SideOnly(Side.CLIENT) private IIcon topIcon;
|
||||
@SideOnly(Side.CLIENT) private IIcon bottomIcon;
|
||||
|
||||
public BlockTNTBase() {
|
||||
super(Material.tnt, 15, 100);
|
||||
super(Material.tnt, 15, 100, 20, false, false);
|
||||
}
|
||||
|
||||
@Override
|
||||
@ -44,6 +42,8 @@ public abstract class BlockTNTBase extends BlockFlammable implements IToolable {
|
||||
if(world.isBlockIndirectlyGettingPowered(x, y, z)) {
|
||||
this.onBlockDestroyedByPlayer(world, x, y, z, 1);
|
||||
world.setBlockToAir(x, y, z);
|
||||
} else {
|
||||
checkAndIgnite(world, x, y, z);
|
||||
}
|
||||
}
|
||||
|
||||
@ -52,6 +52,15 @@ public abstract class BlockTNTBase extends BlockFlammable implements IToolable {
|
||||
if(world.isBlockIndirectlyGettingPowered(x, y, z)) {
|
||||
this.onBlockDestroyedByPlayer(world, x, y, z, 1);
|
||||
world.setBlockToAir(x, y, z);
|
||||
} else {
|
||||
checkAndIgnite(world, x, y, z);
|
||||
}
|
||||
}
|
||||
|
||||
public void checkAndIgnite(World world, int x, int y, int z) {
|
||||
if (shouldIgnite(world, x, y, z)) {
|
||||
this.onBlockDestroyedByPlayer(world, x, y, z, 1);
|
||||
world.setBlockToAir(x, y, z);
|
||||
}
|
||||
}
|
||||
|
||||
@ -60,15 +69,6 @@ public abstract class BlockTNTBase extends BlockFlammable implements IToolable {
|
||||
return 1;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onBlockDestroyedByExplosion(World world, int x, int y, int z, Explosion explosion) {
|
||||
if(!world.isRemote) {
|
||||
EntityTNTPrimedBase entitytntprimed = new EntityTNTPrimedBase(world, x + 0.5D, y + 0.5D, z + 0.5D, explosion.getExplosivePlacedBy(), this);
|
||||
entitytntprimed.fuse = world.rand.nextInt(entitytntprimed.fuse / 4) + entitytntprimed.fuse / 8;
|
||||
world.spawnEntityInWorld(entitytntprimed);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onBlockDestroyedByPlayer(World world, int x, int y, int z, int meta) {
|
||||
this.prime(world, x, y, z, meta, (EntityLivingBase) null);
|
||||
@ -108,19 +108,12 @@ public abstract class BlockTNTBase extends BlockFlammable implements IToolable {
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean canDropFromExplosion(Explosion explosion) {
|
||||
return false;
|
||||
}
|
||||
|
||||
public abstract void explodeEntity(World world, double x, double y, double z, EntityTNTPrimedBase entity);
|
||||
|
||||
@Override
|
||||
@SideOnly(Side.CLIENT)
|
||||
public void registerBlockIcons(IIconRegister p_149651_1_) {
|
||||
this.blockIcon = p_149651_1_.registerIcon(this.getTextureName() + "_side");
|
||||
this.topIcon = p_149651_1_.registerIcon(this.getTextureName() + "_top");
|
||||
this.bottomIcon = p_149651_1_.registerIcon(this.getTextureName() + "_bottom");
|
||||
public void registerBlockIcons(IIconRegister iconRegister) {
|
||||
this.blockIcon = iconRegister.registerIcon(this.getTextureName() + "_side");
|
||||
this.topIcon = iconRegister.registerIcon(this.getTextureName() + "_top");
|
||||
this.bottomIcon = iconRegister.registerIcon(this.getTextureName() + "_bottom");
|
||||
}
|
||||
|
||||
@Override
|
||||
@ -128,8 +121,8 @@ public abstract class BlockTNTBase extends BlockFlammable implements IToolable {
|
||||
|
||||
if(tool == ToolType.DEFUSER) {
|
||||
if(!world.isRemote) {
|
||||
world.func_147480_a(x, y, z, true);
|
||||
this.dropBlockAsItem(world, x, y, z, world.getBlockMetadata(x, y, z), 0);
|
||||
world.func_147480_a(x, y, z, false);
|
||||
this.dropBlockAsItem(world, x, y, z, 0, 0);
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
@ -9,8 +9,8 @@ import com.hbm.blocks.ModBlocks;
|
||||
import com.hbm.entity.projectile.EntityShrapnel;
|
||||
import com.hbm.explosion.ExplosionNT;
|
||||
import com.hbm.explosion.ExplosionNT.ExAttrib;
|
||||
import com.hbm.packet.AuxParticlePacketNT;
|
||||
import com.hbm.packet.PacketDispatcher;
|
||||
import com.hbm.packet.toclient.AuxParticlePacketNT;
|
||||
|
||||
import cpw.mods.fml.common.network.NetworkRegistry.TargetPoint;
|
||||
import cpw.mods.fml.relauncher.Side;
|
||||
@ -81,8 +81,9 @@ public class BlockVolcano extends BlockContainer implements ITooltipProvider, IB
|
||||
}
|
||||
|
||||
public static class TileEntityVolcanoCore extends TileEntity {
|
||||
|
||||
|
||||
private static List<ExAttrib> volcanoExplosion = Arrays.asList(new ExAttrib[] {ExAttrib.NODROP, ExAttrib.LAVA_V, ExAttrib.NOSOUND, ExAttrib.ALLMOD, ExAttrib.NOHURT});
|
||||
private static List<ExAttrib> volcanoRadExplosion = Arrays.asList(new ExAttrib[] {ExAttrib.NODROP, ExAttrib.LAVA_R, ExAttrib.NOSOUND, ExAttrib.ALLMOD, ExAttrib.NOHURT});
|
||||
|
||||
public int volcanoTimer;
|
||||
|
||||
@ -118,15 +119,28 @@ public class BlockVolcano extends BlockContainer implements ITooltipProvider, IB
|
||||
|
||||
if(this.shouldGrow()) {
|
||||
worldObj.setBlock(xCoord, yCoord + 1, zCoord, this.getBlockType(), this.getBlockMetadata(), 3);
|
||||
worldObj.setBlock(xCoord, yCoord, zCoord, ModBlocks.volcanic_lava_block);
|
||||
worldObj.setBlock(xCoord, yCoord, zCoord, getLava());
|
||||
return;
|
||||
} else if(this.isExtinguishing()) {
|
||||
worldObj.setBlock(xCoord, yCoord, zCoord, ModBlocks.volcanic_lava_block);
|
||||
worldObj.setBlock(xCoord, yCoord, zCoord, getLava());
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public boolean isRadioacitve() {
|
||||
return this.getBlockType() == ModBlocks.volcano_rad_core;
|
||||
}
|
||||
|
||||
protected Block getLava() {
|
||||
if(isRadioacitve()) return ModBlocks.rad_lava_block;
|
||||
return ModBlocks.volcanic_lava_block;
|
||||
}
|
||||
|
||||
protected List<ExAttrib> getExpAttrb() {
|
||||
return this.isRadioacitve() ? this.volcanoRadExplosion : this.volcanoExplosion;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void readFromNBT(NBTTagCompound nbt) {
|
||||
@ -184,21 +198,12 @@ public class BlockVolcano extends BlockContainer implements ITooltipProvider, IB
|
||||
}
|
||||
}
|
||||
|
||||
/* TODO */
|
||||
private boolean doesPyroclastic() {
|
||||
return false;
|
||||
}
|
||||
|
||||
private double getPyroclasticRange() {
|
||||
return 0D;
|
||||
}
|
||||
|
||||
/** Causes two magma explosions, one from bedrock to the core and one from the core to 15 blocks above. */
|
||||
private void blastMagmaChannel() {
|
||||
ExplosionNT explosion = new ExplosionNT(worldObj, null, xCoord + 0.5, yCoord + worldObj.rand.nextInt(15) + 1.5, zCoord + 0.5, 7);
|
||||
explosion.addAllAttrib(volcanoExplosion).explode();
|
||||
explosion.addAllAttrib(getExpAttrb()).explode();
|
||||
ExplosionNT explosion2 = new ExplosionNT(worldObj, null, xCoord + 0.5 + worldObj.rand.nextGaussian() * 3, worldObj.rand.nextInt(yCoord + 1), zCoord + 0.5 + worldObj.rand.nextGaussian() * 3, 10);
|
||||
explosion2.addAllAttrib(volcanoExplosion).explode();
|
||||
explosion2.addAllAttrib(getExpAttrb()).explode();
|
||||
}
|
||||
|
||||
/** Causes two magma explosions at a random position around the core, one at normal and one at half range. */
|
||||
@ -207,7 +212,7 @@ public class BlockVolcano extends BlockContainer implements ITooltipProvider, IB
|
||||
for(int i = 0; i < 2; i++) {
|
||||
double dist = size / (double) (i + 1);
|
||||
ExplosionNT explosion = new ExplosionNT(worldObj, null, xCoord + 0.5 + worldObj.rand.nextGaussian() * dist, yCoord + 0.5 + worldObj.rand.nextGaussian() * dist, zCoord + 0.5 + worldObj.rand.nextGaussian() * dist, 7);
|
||||
explosion.addAllAttrib(volcanoExplosion).explode();
|
||||
explosion.addAllAttrib(getExpAttrb()).explode();
|
||||
}
|
||||
}
|
||||
|
||||
@ -224,7 +229,7 @@ public class BlockVolcano extends BlockContainer implements ITooltipProvider, IB
|
||||
|
||||
if(!b.isAir(worldObj, x, y, z) && b.getExplosionResistance(null) < Blocks.obsidian.getExplosionResistance(null)) {
|
||||
//turn into lava if solid block, otherwise just break
|
||||
worldObj.setBlock(x, y, z, b.isNormalCube() ? ModBlocks.volcanic_lava_block : Blocks.air);
|
||||
worldObj.setBlock(x, y, z, b.isNormalCube() ? this.getLava() : Blocks.air);
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -236,8 +241,8 @@ public class BlockVolcano extends BlockContainer implements ITooltipProvider, IB
|
||||
int rY = yCoord + worldObj.rand.nextInt(11);
|
||||
int rZ = zCoord - 10 + worldObj.rand.nextInt(21);
|
||||
|
||||
if(worldObj.getBlock(rX, rY, rZ) == Blocks.air && worldObj.getBlock(rX, rY - 1, rZ) == ModBlocks.volcanic_lava_block)
|
||||
worldObj.setBlock(rX, rY, rZ, ModBlocks.volcanic_lava_block);
|
||||
if(worldObj.getBlock(rX, rY, rZ) == Blocks.air && worldObj.getBlock(rX, rY - 1, rZ) == this.getLava())
|
||||
worldObj.setBlock(rX, rY, rZ, this.getLava());
|
||||
}
|
||||
|
||||
/** Creates a 3x3x3 lava sphere around the core. */
|
||||
@ -248,7 +253,7 @@ public class BlockVolcano extends BlockContainer implements ITooltipProvider, IB
|
||||
for(int k = -1; k <= 1; k++) {
|
||||
|
||||
if(i != 0 || j != 0 || k != 0) {
|
||||
worldObj.setBlock(xCoord + i, yCoord + j, zCoord + k, ModBlocks.volcanic_lava_block);
|
||||
worldObj.setBlock(xCoord + i, yCoord + j, zCoord + k, this.getLava());
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -264,7 +269,11 @@ public class BlockVolcano extends BlockContainer implements ITooltipProvider, IB
|
||||
frag.motionY = 1D + worldObj.rand.nextDouble();
|
||||
frag.motionX = worldObj.rand.nextGaussian() * 0.2D;
|
||||
frag.motionZ = worldObj.rand.nextGaussian() * 0.2D;
|
||||
frag.setVolcano(true);
|
||||
if(this.isRadioacitve()) {
|
||||
frag.setRadVolcano(true);
|
||||
} else {
|
||||
frag.setVolcano(true);
|
||||
}
|
||||
worldObj.spawnEntityInWorld(frag);
|
||||
}
|
||||
}
|
||||
|
||||
@ -123,7 +123,7 @@ public class CompactLauncher extends BlockContainer implements IMultiblock, IBom
|
||||
TileEntityCompactLauncher entity = (TileEntityCompactLauncher) world.getTileEntity(x, y, z);
|
||||
|
||||
if(entity.canLaunch()) {
|
||||
entity.launch();
|
||||
entity.launchFromDesignator();
|
||||
return BombReturnCode.LAUNCHED;
|
||||
}
|
||||
|
||||
|
||||
@ -1,16 +1,18 @@
|
||||
package com.hbm.blocks.bomb;
|
||||
|
||||
import com.hbm.entity.item.EntityTNTPrimedBase;
|
||||
|
||||
import net.minecraft.util.MathHelper;
|
||||
import cpw.mods.fml.client.registry.RenderingRegistry;
|
||||
import net.minecraft.block.Block;
|
||||
import net.minecraft.block.material.Material;
|
||||
import net.minecraft.init.Blocks;
|
||||
import net.minecraft.world.Explosion;
|
||||
import net.minecraft.world.World;
|
||||
|
||||
public class DetCord extends Block implements IDetConnectible {
|
||||
public class DetCord extends BlockDetonatable implements IDetConnectible {
|
||||
|
||||
public DetCord(Material p_i45394_1_) {
|
||||
super(p_i45394_1_);
|
||||
public DetCord(Material material) {
|
||||
super(material, 0, 0, 0, false, false);
|
||||
}
|
||||
|
||||
public static int renderID = RenderingRegistry.getNextAvailableRenderId();
|
||||
@ -30,16 +32,6 @@ public class DetCord extends Block implements IDetConnectible {
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onBlockDestroyedByExplosion(World world, int x, int y, int z, Explosion p_149723_5_) {
|
||||
this.explode(world, x, y, z);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean canDropFromExplosion(Explosion explosion) {
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onNeighborBlockChange(World world, int x, int y, int z, Block p_149695_5_) {
|
||||
if(world.isBlockIndirectlyGettingPowered(x, y, z)) {
|
||||
@ -48,10 +40,14 @@ public class DetCord extends Block implements IDetConnectible {
|
||||
}
|
||||
|
||||
public void explode(World world, int x, int y, int z) {
|
||||
|
||||
if(!world.isRemote) {
|
||||
world.setBlock(x, y, z, Blocks.air);
|
||||
world.createExplosion(null, x + 0.5, y + 0.5, z + 0.5, 1.5F, true);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void explodeEntity(World world, double x, double y, double z, EntityTNTPrimedBase entity) {
|
||||
explode(world, MathHelper.floor_double(x), MathHelper.floor_double(y), MathHelper.floor_double(z));
|
||||
}
|
||||
}
|
||||
|
||||
@ -3,18 +3,21 @@ package com.hbm.blocks.bomb;
|
||||
import java.util.Random;
|
||||
|
||||
import com.hbm.blocks.machine.BlockPillar;
|
||||
import com.hbm.entity.item.EntityTNTPrimedBase;
|
||||
import com.hbm.explosion.ExplosionLarge;
|
||||
import com.hbm.explosion.ExplosionNT;
|
||||
import com.hbm.explosion.ExplosionNT.ExAttrib;
|
||||
import com.hbm.interfaces.IBomb;
|
||||
|
||||
import api.hbm.block.IFuckingExplode;
|
||||
import net.minecraft.util.MathHelper;
|
||||
import net.minecraft.block.Block;
|
||||
import net.minecraft.block.material.Material;
|
||||
import net.minecraft.item.Item;
|
||||
import net.minecraft.world.Explosion;
|
||||
import net.minecraft.world.World;
|
||||
|
||||
public class DetMiner extends BlockPillar implements IBomb {
|
||||
public class DetMiner extends BlockPillar implements IBomb, IFuckingExplode {
|
||||
|
||||
public DetMiner(Material mat, String top) {
|
||||
super(mat, top);
|
||||
@ -44,8 +47,13 @@ public class DetMiner extends BlockPillar implements IBomb {
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onBlockDestroyedByExplosion(World world, int x, int y, int z, Explosion p_149723_5_) {
|
||||
this.explode(world, x, y, z);
|
||||
public void onBlockDestroyedByExplosion(World world, int x, int y, int z, Explosion explosion) {
|
||||
if(!world.isRemote) {
|
||||
EntityTNTPrimedBase tntPrimed = new EntityTNTPrimedBase(world, x + 0.5D, y + 0.5D, z + 0.5D, explosion != null ? explosion.getExplosivePlacedBy() : null, this);
|
||||
tntPrimed.fuse = 0;
|
||||
tntPrimed.detonateOnCollision = false;
|
||||
world.spawnEntityInWorld(tntPrimed);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
@ -54,4 +62,9 @@ public class DetMiner extends BlockPillar implements IBomb {
|
||||
this.explode(world, x, y, z);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void explodeEntity(World world, double x, double y, double z, EntityTNTPrimedBase entity) {
|
||||
explode(world, MathHelper.floor_double(x), MathHelper.floor_double(y), MathHelper.floor_double(z));
|
||||
}
|
||||
}
|
||||
|
||||
@ -2,13 +2,15 @@ package com.hbm.blocks.bomb;
|
||||
|
||||
import com.hbm.blocks.ModBlocks;
|
||||
import com.hbm.config.BombConfig;
|
||||
import com.hbm.entity.effect.EntityNukeCloudSmall;
|
||||
import com.hbm.entity.effect.EntityNukeTorex;
|
||||
import com.hbm.entity.item.EntityTNTPrimedBase;
|
||||
import com.hbm.entity.logic.EntityNukeExplosionMK5;
|
||||
import com.hbm.explosion.ExplosionLarge;
|
||||
import com.hbm.explosion.ExplosionNT;
|
||||
import com.hbm.interfaces.IBomb;
|
||||
import com.hbm.lib.RefStrings;
|
||||
import com.hbm.particle.helper.ExplosionCreator;
|
||||
|
||||
import net.minecraft.util.MathHelper;
|
||||
import cpw.mods.fml.relauncher.Side;
|
||||
import cpw.mods.fml.relauncher.SideOnly;
|
||||
import net.minecraft.block.Block;
|
||||
@ -16,16 +18,15 @@ import net.minecraft.block.material.Material;
|
||||
import net.minecraft.client.renderer.texture.IIconRegister;
|
||||
import net.minecraft.init.Blocks;
|
||||
import net.minecraft.util.IIcon;
|
||||
import net.minecraft.world.Explosion;
|
||||
import net.minecraft.world.World;
|
||||
|
||||
public class ExplosiveCharge extends Block implements IBomb, IDetConnectible {
|
||||
public class ExplosiveCharge extends BlockDetonatable implements IBomb, IDetConnectible {
|
||||
|
||||
@SideOnly(Side.CLIENT)
|
||||
private IIcon iconTop;
|
||||
|
||||
public ExplosiveCharge(Material p_i45394_1_) {
|
||||
super(p_i45394_1_);
|
||||
public ExplosiveCharge(Material material) {
|
||||
super(material, 0, 0, 0, false, false);
|
||||
}
|
||||
|
||||
@Override
|
||||
@ -47,16 +48,6 @@ public class ExplosiveCharge extends Block implements IBomb, IDetConnectible {
|
||||
return side == 1 ? this.iconTop : (side == 0 ? this.iconTop : this.blockIcon);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onBlockDestroyedByExplosion(World world, int x, int y, int z, Explosion p_149723_5_) {
|
||||
this.explode(world, x, y, z);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean canDropFromExplosion(Explosion explosion) {
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onNeighborBlockChange(World world, int x, int y, int z, Block p_149695_5_) {
|
||||
if(world.isBlockIndirectlyGettingPowered(x, y, z)) {
|
||||
@ -74,20 +65,20 @@ public class ExplosiveCharge extends Block implements IBomb, IDetConnectible {
|
||||
}
|
||||
if(this == ModBlocks.det_charge) {
|
||||
new ExplosionNT(world, null, x + 0.5, y + 0.5, z + 0.5, 15).overrideResolution(64).explode();
|
||||
ExplosionLarge.spawnParticles(world, x, y, z, ExplosionLarge.cloudFunction(15));
|
||||
ExplosionCreator.composeEffectStandard(world, x + 0.5, y + 1, z + 0.5);
|
||||
}
|
||||
if(this == ModBlocks.det_nuke) {
|
||||
world.spawnEntityInWorld(EntityNukeExplosionMK5.statFac(world, BombConfig.missileRadius, x + 0.5, y + 0.5, z + 0.5));
|
||||
|
||||
EntityNukeCloudSmall entity2 = new EntityNukeCloudSmall(world, 1000, BombConfig.missileRadius * 0.005F);
|
||||
entity2.posX = x;
|
||||
entity2.posY = y;
|
||||
entity2.posZ = z;
|
||||
world.spawnEntityInWorld(entity2);
|
||||
EntityNukeTorex.statFac(world, x + 0.5, y + 0.5, z + 0.5, BombConfig.missileRadius);
|
||||
}
|
||||
}
|
||||
|
||||
return BombReturnCode.DETONATED;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void explodeEntity(World world, double x, double y, double z, EntityTNTPrimedBase entity) {
|
||||
explode(world, MathHelper.floor_double(x), MathHelper.floor_double(y), MathHelper.floor_double(z));
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@ -5,6 +5,12 @@ import java.util.Random;
|
||||
import com.hbm.blocks.ModBlocks;
|
||||
import com.hbm.explosion.ExplosionLarge;
|
||||
import com.hbm.explosion.ExplosionNukeSmall;
|
||||
import com.hbm.explosion.vanillant.ExplosionVNT;
|
||||
import com.hbm.explosion.vanillant.standard.BlockAllocatorStandard;
|
||||
import com.hbm.explosion.vanillant.standard.BlockProcessorStandard;
|
||||
import com.hbm.explosion.vanillant.standard.EntityProcessorCrossSmooth;
|
||||
import com.hbm.explosion.vanillant.standard.ExplosionEffectWeapon;
|
||||
import com.hbm.explosion.vanillant.standard.PlayerProcessorStandard;
|
||||
import com.hbm.interfaces.IBomb;
|
||||
import com.hbm.items.ModItems;
|
||||
import com.hbm.tileentity.bomb.TileEntityLandmine;
|
||||
@ -26,8 +32,13 @@ public class Landmine extends BlockContainer implements IBomb {
|
||||
|
||||
public static boolean safeMode = false;
|
||||
|
||||
public Landmine(Material p_i45386_1_) {
|
||||
super(p_i45386_1_);
|
||||
public double range;
|
||||
public double height;
|
||||
|
||||
public Landmine(Material mat, double range, double height) {
|
||||
super(mat);
|
||||
this.range = range;
|
||||
this.height = height;
|
||||
}
|
||||
|
||||
@Override
|
||||
@ -35,20 +46,9 @@ public class Landmine extends BlockContainer implements IBomb {
|
||||
return new TileEntityLandmine();
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getRenderType() {
|
||||
return -1;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isOpaqueCube() {
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean renderAsNormalBlock() {
|
||||
return false;
|
||||
}
|
||||
@Override public int getRenderType() { return -1; }
|
||||
@Override public boolean isOpaqueCube() { return false; }
|
||||
@Override public boolean renderAsNormalBlock() { return false; }
|
||||
|
||||
@Override
|
||||
public Item getItemDropped(int i, Random rand, int j) {
|
||||
@ -56,29 +56,17 @@ public class Landmine extends BlockContainer implements IBomb {
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setBlockBoundsBasedOnState(IBlockAccess p_149719_1_, int p_149719_2_, int p_149719_3_, int p_149719_4_) {
|
||||
public void setBlockBoundsBasedOnState(IBlockAccess world, int x, int y, int z) {
|
||||
float f = 0.0625F;
|
||||
if(this == ModBlocks.mine_ap)
|
||||
this.setBlockBounds(6 * f, 0.0F, 6 * f, 10 * f, 2 * f, 10 * f);
|
||||
if(this == ModBlocks.mine_he)
|
||||
this.setBlockBounds(4 * f, 0.0F, 4 * f, 12 * f, 2 * f, 12 * f);
|
||||
if(this == ModBlocks.mine_shrap)
|
||||
this.setBlockBounds(4 * f, 0.0F, 4 * f, 12 * f, 2 * f, 12 * f);
|
||||
if(this == ModBlocks.mine_fat)
|
||||
this.setBlockBounds(5 * f, 0.0F, 4 * f, 11 * f, 6 * f, 12 * f);
|
||||
if(this == ModBlocks.mine_ap) this.setBlockBounds(5 * f, 0.0F, 5 * f, 11 * f, 1 * f, 11 * f);
|
||||
if(this == ModBlocks.mine_he) this.setBlockBounds(4 * f, 0.0F, 4 * f, 12 * f, 2 * f, 12 * f);
|
||||
if(this == ModBlocks.mine_shrap) this.setBlockBounds(5 * f, 0.0F, 5 * f, 11 * f, 1 * f, 11 * f);
|
||||
if(this == ModBlocks.mine_fat) this.setBlockBounds(5 * f, 0.0F, 4 * f, 11 * f, 6 * f, 12 * f);
|
||||
}
|
||||
|
||||
@Override
|
||||
public AxisAlignedBB getCollisionBoundingBoxFromPool(World world, int x, int y, int z) {
|
||||
float f = 0.0625F;
|
||||
if(this == ModBlocks.mine_ap)
|
||||
this.setBlockBounds(6 * f, 0.0F, 6 * f, 10 * f, 2 * f, 10 * f);
|
||||
if(this == ModBlocks.mine_he)
|
||||
this.setBlockBounds(4 * f, 0.0F, 4 * f, 12 * f, 2 * f, 12 * f);
|
||||
if(this == ModBlocks.mine_shrap)
|
||||
this.setBlockBounds(4 * f, 0.0F, 4 * f, 12 * f, 2 * f, 12 * f);
|
||||
if(this == ModBlocks.mine_fat)
|
||||
this.setBlockBounds(5 * f, 0.0F, 4 * f, 11 * f, 6 * f, 12 * f);
|
||||
setBlockBoundsBasedOnState(world, x, y, z);
|
||||
return AxisAlignedBB.getBoundingBox(x + this.minX, y + this.minY, z + this.minZ, x + this.maxX, y + this.maxY, z + this.maxZ);
|
||||
}
|
||||
|
||||
@ -92,14 +80,7 @@ public class Landmine extends BlockContainer implements IBomb {
|
||||
explode(world, x, y, z);
|
||||
}
|
||||
|
||||
boolean flag = false;
|
||||
|
||||
if(!World.doesBlockHaveSolidTopSurface(world, x, y - 1, z) && !BlockFence.func_149825_a(world.getBlock(x, y - 1, z))) {
|
||||
flag = true;
|
||||
}
|
||||
|
||||
if(flag) {
|
||||
|
||||
if(!safeMode) {
|
||||
explode(world, x, y, z);
|
||||
} else {
|
||||
@ -156,24 +137,33 @@ public class Landmine extends BlockContainer implements IBomb {
|
||||
Landmine.safeMode = false;
|
||||
|
||||
if(this == ModBlocks.mine_ap) {
|
||||
world.newExplosion(null, x + 0.5, y + 0.5, z + 0.5, 2.5F, false, false);
|
||||
}
|
||||
if(this == ModBlocks.mine_he) {
|
||||
ExplosionLarge.explode(world, x + 0.5, y + 0.5, z + 0.5, 3F, true, false, false);
|
||||
world.newExplosion(null, x + 0.5, y + 2, z + 0.5, 15F, false, false);
|
||||
}
|
||||
if(this == ModBlocks.mine_shrap) {
|
||||
ExplosionLarge.explode(world, x + 0.5, y + 0.5, z + 0.5, 1, true, false, false);
|
||||
ExplosionVNT vnt = new ExplosionVNT(world, x + 0.5, y + 0.5, z + 0.5, 3F);
|
||||
vnt.setEntityProcessor(new EntityProcessorCrossSmooth(0.5, 10F).setupPiercing(5F, 0.2F));
|
||||
vnt.setPlayerProcessor(new PlayerProcessorStandard());
|
||||
vnt.setSFX(new ExplosionEffectWeapon(5, 1F, 0.5F));
|
||||
vnt.explode();
|
||||
} else if(this == ModBlocks.mine_he) {
|
||||
ExplosionVNT vnt = new ExplosionVNT(world, x + 0.5, y + 0.5, z + 0.5, 4F);
|
||||
vnt.setBlockAllocator(new BlockAllocatorStandard());
|
||||
vnt.setBlockProcessor(new BlockProcessorStandard());
|
||||
vnt.setEntityProcessor(new EntityProcessorCrossSmooth(1, 35).setupPiercing(15F, 0.2F));
|
||||
vnt.setPlayerProcessor(new PlayerProcessorStandard());
|
||||
vnt.setSFX(new ExplosionEffectWeapon(15, 3.5F, 1.25F));
|
||||
vnt.explode();
|
||||
} else if(this == ModBlocks.mine_shrap) {
|
||||
ExplosionVNT vnt = new ExplosionVNT(world, x + 0.5, y + 0.5, z + 0.5, 3F);
|
||||
vnt.setEntityProcessor(new EntityProcessorCrossSmooth(0.5, 7.5F));
|
||||
vnt.setPlayerProcessor(new PlayerProcessorStandard());
|
||||
vnt.setSFX(new ExplosionEffectWeapon(5, 1F, 0.5F));
|
||||
vnt.explode();
|
||||
|
||||
ExplosionLarge.spawnShrapnelShower(world, x + 0.5, y + 0.5, z + 0.5, 0, 1D, 0, 45, 0.2D);
|
||||
ExplosionLarge.spawnShrapnels(world, x + 0.5, y + 0.5, z + 0.5, 5);
|
||||
}
|
||||
if(this == ModBlocks.mine_fat) {
|
||||
|
||||
} else if(this == ModBlocks.mine_fat) {
|
||||
ExplosionNukeSmall.explode(world, x + 0.5, y + 0.5, z + 0.5, ExplosionNukeSmall.PARAMS_MEDIUM);
|
||||
}
|
||||
}
|
||||
|
||||
return BombReturnCode.DETONATED;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@ -1,317 +1,97 @@
|
||||
package com.hbm.blocks.bomb;
|
||||
|
||||
import java.util.Random;
|
||||
|
||||
import org.apache.logging.log4j.Level;
|
||||
|
||||
import com.hbm.blocks.ModBlocks;
|
||||
import com.hbm.config.GeneralConfig;
|
||||
import com.hbm.entity.missile.*;
|
||||
import com.hbm.blocks.BlockDummyable;
|
||||
import com.hbm.interfaces.IBomb;
|
||||
import com.hbm.interfaces.Spaghetti;
|
||||
import com.hbm.items.ModItems;
|
||||
import com.hbm.main.MainRegistry;
|
||||
import com.hbm.tileentity.TileEntityProxyCombo;
|
||||
import com.hbm.tileentity.bomb.TileEntityLaunchPad;
|
||||
|
||||
import api.hbm.item.IDesignatorItem;
|
||||
import cpw.mods.fml.common.network.internal.FMLNetworkHandler;
|
||||
import cpw.mods.fml.relauncher.Side;
|
||||
import cpw.mods.fml.relauncher.SideOnly;
|
||||
import net.minecraft.block.Block;
|
||||
import net.minecraft.block.BlockContainer;
|
||||
import net.minecraft.block.material.Material;
|
||||
import net.minecraft.entity.Entity;
|
||||
import net.minecraft.entity.EntityLivingBase;
|
||||
import net.minecraft.entity.item.EntityItem;
|
||||
import net.minecraft.entity.player.EntityPlayer;
|
||||
import net.minecraft.item.Item;
|
||||
import net.minecraft.item.ItemStack;
|
||||
import net.minecraft.nbt.NBTTagCompound;
|
||||
import net.minecraft.tileentity.TileEntity;
|
||||
import net.minecraft.util.MathHelper;
|
||||
import net.minecraft.util.AxisAlignedBB;
|
||||
import net.minecraft.world.World;
|
||||
import net.minecraftforge.common.util.ForgeDirection;
|
||||
|
||||
public class LaunchPad extends BlockContainer implements IBomb {
|
||||
public class LaunchPad extends BlockDummyable implements IBomb {
|
||||
|
||||
public TileEntityLaunchPad tetn = new TileEntityLaunchPad();
|
||||
public static boolean keepInventory = false;
|
||||
private final static Random field_149933_a = new Random();
|
||||
|
||||
public LaunchPad(Material p_i45386_1_) {
|
||||
super(p_i45386_1_);
|
||||
public LaunchPad(Material mat) {
|
||||
super(mat);
|
||||
this.bounding.add(AxisAlignedBB.getBoundingBox(-1.5D, 0D, -1.5D, -0.5D, 1D, -0.5D));
|
||||
this.bounding.add(AxisAlignedBB.getBoundingBox(0.5D, 0D, -1.5D, 1.5D, 1D, -0.5D));
|
||||
this.bounding.add(AxisAlignedBB.getBoundingBox(-1.5D, 0D, 0.5D, -0.5D, 1D, 1.5D));
|
||||
this.bounding.add(AxisAlignedBB.getBoundingBox(0.5D, 0D, 0.5D, 1.5D, 1D, 1.5D));
|
||||
this.bounding.add(AxisAlignedBB.getBoundingBox(-0.5D, 0.5D, -1.5D, 0.5D, 1D, 1.5D));
|
||||
this.bounding.add(AxisAlignedBB.getBoundingBox(-1.5D, 0.5D, -0.5D, 1.5D, 1D, 0.5D));
|
||||
}
|
||||
|
||||
@Override
|
||||
public TileEntity createNewTileEntity(World p_149915_1_, int p_149915_2_) {
|
||||
return new TileEntityLaunchPad();
|
||||
public TileEntity createNewTileEntity(World world, int meta) {
|
||||
if(meta >= 12) return new TileEntityLaunchPad();
|
||||
if(meta >= 6) return new TileEntityProxyCombo().inventory().power().fluid();
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Item getItemDropped(int p_149650_1_, Random p_149650_2_, int p_149650_3_) {
|
||||
return Item.getItemFromBlock(ModBlocks.launch_pad);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void breakBlock(World p_149749_1_, int p_149749_2_, int p_149749_3_, int p_149749_4_, Block p_149749_5_, int p_149749_6_) {
|
||||
if(!keepInventory) {
|
||||
TileEntityLaunchPad tileentityfurnace = (TileEntityLaunchPad) p_149749_1_.getTileEntity(p_149749_2_, p_149749_3_, p_149749_4_);
|
||||
|
||||
if(tileentityfurnace != null) {
|
||||
for(int i1 = 0; i1 < tileentityfurnace.getSizeInventory(); ++i1) {
|
||||
ItemStack itemstack = tileentityfurnace.getStackInSlot(i1);
|
||||
|
||||
if(itemstack != null) {
|
||||
float f = LaunchPad.field_149933_a.nextFloat() * 0.8F + 0.1F;
|
||||
float f1 = LaunchPad.field_149933_a.nextFloat() * 0.8F + 0.1F;
|
||||
float f2 = LaunchPad.field_149933_a.nextFloat() * 0.8F + 0.1F;
|
||||
|
||||
while(itemstack.stackSize > 0) {
|
||||
int j1 = LaunchPad.field_149933_a.nextInt(21) + 10;
|
||||
|
||||
if(j1 > itemstack.stackSize) {
|
||||
j1 = itemstack.stackSize;
|
||||
}
|
||||
|
||||
itemstack.stackSize -= j1;
|
||||
EntityItem entityitem = new EntityItem(p_149749_1_, p_149749_2_ + f, p_149749_3_ + f1, p_149749_4_ + f2, new ItemStack(itemstack.getItem(), j1, itemstack.getItemDamage()));
|
||||
|
||||
if(itemstack.hasTagCompound()) {
|
||||
entityitem.getEntityItem().setTagCompound((NBTTagCompound) itemstack.getTagCompound().copy());
|
||||
}
|
||||
|
||||
float f3 = 0.05F;
|
||||
entityitem.motionX = (float) LaunchPad.field_149933_a.nextGaussian() * f3;
|
||||
entityitem.motionY = (float) LaunchPad.field_149933_a.nextGaussian() * f3 + 0.2F;
|
||||
entityitem.motionZ = (float) LaunchPad.field_149933_a.nextGaussian() * f3;
|
||||
p_149749_1_.spawnEntityInWorld(entityitem);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
p_149749_1_.func_147453_f(p_149749_2_, p_149749_3_, p_149749_4_, p_149749_5_);
|
||||
}
|
||||
}
|
||||
|
||||
super.breakBlock(p_149749_1_, p_149749_2_, p_149749_3_, p_149749_4_, p_149749_5_, p_149749_6_);
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public boolean onBlockActivated(World world, int x, int y, int z, EntityPlayer player, int side, float hitX, float hitY, float hitZ) {
|
||||
if(world.isRemote) {
|
||||
return true;
|
||||
} else if(!player.isSneaking()) {
|
||||
TileEntityLaunchPad entity = (TileEntityLaunchPad) world.getTileEntity(x, y, z);
|
||||
if(entity != null) {
|
||||
FMLNetworkHandler.openGui(player, MainRegistry.instance, 0, world, x, y, z);
|
||||
}
|
||||
return true;
|
||||
} else {
|
||||
return false;
|
||||
}
|
||||
return this.standardOpenBehavior(world, x, y, z, player, 0);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onNeighborBlockChange(World p_149695_1_, int x, int y, int z, Block p_149695_5_) {
|
||||
if(p_149695_1_.isBlockIndirectlyGettingPowered(x, y, z) && !p_149695_1_.isRemote) {
|
||||
this.explode(p_149695_1_, x, y, z);
|
||||
}
|
||||
public int[] getDimensions() {
|
||||
return new int[] {0, 0, 1, 1, 1, 1};
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getRenderType() {
|
||||
return -1;
|
||||
public int getOffset() {
|
||||
return 1;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isOpaqueCube() {
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean renderAsNormalBlock() {
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onBlockPlacedBy(World world, int x, int y, int z, EntityLivingBase player, ItemStack itemStack) {
|
||||
int i = MathHelper.floor_double(player.rotationYaw * 4.0F / 360.0F + 0.5D) & 3;
|
||||
|
||||
if(i == 0) {
|
||||
world.setBlockMetadataWithNotify(x, y, z, 5, 2);
|
||||
}
|
||||
if(i == 1) {
|
||||
world.setBlockMetadataWithNotify(x, y, z, 3, 2);
|
||||
}
|
||||
if(i == 2) {
|
||||
world.setBlockMetadataWithNotify(x, y, z, 4, 2);
|
||||
}
|
||||
if(i == 3) {
|
||||
world.setBlockMetadataWithNotify(x, y, z, 2, 2);
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* @Override public void setBlockBoundsBasedOnState(IBlockAccess
|
||||
* p_149719_1_, int p_149719_2_, int p_149719_3_, int p_149719_4_) { float f
|
||||
* = 0.0625F; this.setBlockBounds(0.0F, 0.0F, 0.0F, 1.0F, 0.5F, 1.0F); }
|
||||
*
|
||||
* @Override public AxisAlignedBB getCollisionBoundingBoxFromPool(World
|
||||
* world, int x, int y, int z) { float f = 0.0625F;
|
||||
* this.setBlockBounds(0.0F, 0.0F, 0.0F, 1.0F, 8*f, 1.0F); return
|
||||
* AxisAlignedBB.getBoundingBox(x + this.minX, y + this.minY, z + this.minZ,
|
||||
* x + this.maxX, y + this.maxY, z + this.maxZ); }
|
||||
*/
|
||||
|
||||
@Override
|
||||
@SideOnly(Side.CLIENT)
|
||||
public Item getItem(World p_149694_1_, int p_149694_2_, int p_149694_3_, int p_149694_4_) {
|
||||
return Item.getItemFromBlock(ModBlocks.launch_pad);
|
||||
}
|
||||
|
||||
@Spaghetti("AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA *takes breath* AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA")
|
||||
@Override
|
||||
public BombReturnCode explode(World world, int x, int y, int z) {
|
||||
|
||||
TileEntityLaunchPad entity = (TileEntityLaunchPad) world.getTileEntity(x, y, z);
|
||||
|
||||
if(entity.slots[0] == null || world.isRemote)
|
||||
return BombReturnCode.ERROR_MISSING_COMPONENT;
|
||||
if(!world.isRemote) {
|
||||
|
||||
int[] corePos = findCore(world, x, y, z);
|
||||
if(corePos != null){
|
||||
TileEntity core = world.getTileEntity(corePos[0], corePos[1], corePos[2]);
|
||||
if(core instanceof TileEntityLaunchPad){
|
||||
TileEntityLaunchPad entity = (TileEntityLaunchPad)core;
|
||||
return entity.launchFromDesignator();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if(entity.slots[1] != null && entity.slots[1].getItem() instanceof IDesignatorItem && entity.power >= 75000) {
|
||||
|
||||
if(!((IDesignatorItem)entity.slots[1].getItem()).isReady(world, entity.slots[1], x, y, z))
|
||||
return BombReturnCode.ERROR_MISSING_COMPONENT;
|
||||
|
||||
int xCoord = entity.slots[1].stackTagCompound.getInteger("xCoord");
|
||||
int zCoord = entity.slots[1].stackTagCompound.getInteger("zCoord");
|
||||
|
||||
if(xCoord == entity.xCoord && zCoord == entity.zCoord) {
|
||||
xCoord += 1;
|
||||
}
|
||||
|
||||
Entity missile = null;
|
||||
|
||||
if(entity.slots[0].getItem() == ModItems.missile_generic) {
|
||||
missile = new EntityMissileGeneric(world, x + 0.5F, y + 2F, z + 0.5F, xCoord, zCoord);
|
||||
}
|
||||
if(entity.slots[0].getItem() == ModItems.missile_incendiary) {
|
||||
missile = new EntityMissileIncendiary(world, x + 0.5F, y + 2F, z + 0.5F, xCoord, zCoord);
|
||||
}
|
||||
if(entity.slots[0].getItem() == ModItems.missile_cluster) {
|
||||
missile = new EntityMissileCluster(world, x + 0.5F, y + 2F, z + 0.5F, xCoord, zCoord);
|
||||
}
|
||||
if(entity.slots[0].getItem() == ModItems.missile_buster) {
|
||||
missile = new EntityMissileBunkerBuster(world, x + 0.5F, y + 2F, z + 0.5F, xCoord, zCoord);
|
||||
}
|
||||
if(entity.slots[0].getItem() == ModItems.missile_strong) {
|
||||
missile = new EntityMissileStrong(world, x + 0.5F, y + 2F, z + 0.5F, xCoord, zCoord);
|
||||
}
|
||||
if(entity.slots[0].getItem() == ModItems.missile_incendiary_strong) {
|
||||
missile = new EntityMissileIncendiaryStrong(world, x + 0.5F, y + 2F, z + 0.5F, xCoord, zCoord);
|
||||
}
|
||||
if(entity.slots[0].getItem() == ModItems.missile_cluster_strong) {
|
||||
missile = new EntityMissileClusterStrong(world, x + 0.5F, y + 2F, z + 0.5F, xCoord, zCoord);
|
||||
}
|
||||
if(entity.slots[0].getItem() == ModItems.missile_buster_strong) {
|
||||
missile = new EntityMissileBusterStrong(world, x + 0.5F, y + 2F, z + 0.5F, xCoord, zCoord);
|
||||
}
|
||||
if(entity.slots[0].getItem() == ModItems.missile_burst) {
|
||||
missile = new EntityMissileBurst(world, x + 0.5F, y + 2F, z + 0.5F, xCoord, zCoord);
|
||||
}
|
||||
if(entity.slots[0].getItem() == ModItems.missile_inferno) {
|
||||
missile = new EntityMissileInferno(world, x + 0.5F, y + 2F, z + 0.5F, xCoord, zCoord);
|
||||
}
|
||||
if(entity.slots[0].getItem() == ModItems.missile_rain) {
|
||||
missile = new EntityMissileRain(world, x + 0.5F, y + 2F, z + 0.5F, xCoord, zCoord);
|
||||
}
|
||||
if(entity.slots[0].getItem() == ModItems.missile_drill) {
|
||||
missile = new EntityMissileDrill(world, x + 0.5F, y + 2F, z + 0.5F, xCoord, zCoord);
|
||||
}
|
||||
if(entity.slots[0].getItem() == ModItems.missile_nuclear) {
|
||||
missile = new EntityMissileNuclear(world, x + 0.5F, y + 2F, z + 0.5F, xCoord, zCoord);
|
||||
}
|
||||
if(entity.slots[0].getItem() == ModItems.missile_endo) {
|
||||
missile = new EntityMissileEndo(world, x + 0.5F, y + 2F, z + 0.5F, xCoord, zCoord);
|
||||
}
|
||||
if(entity.slots[0].getItem() == ModItems.missile_exo) {
|
||||
missile = new EntityMissileExo(world, x + 0.5F, y + 2F, z + 0.5F, xCoord, zCoord);
|
||||
}
|
||||
if(entity.slots[0].getItem() == ModItems.missile_nuclear_cluster) {
|
||||
missile = new EntityMissileMirv(world, x + 0.5F, y + 2F, z + 0.5F, xCoord, zCoord);
|
||||
}
|
||||
if(entity.slots[0].getItem() == ModItems.missile_doomsday) {
|
||||
missile = new EntityMissileDoomsday(world, x + 0.5F, y + 2F, z + 0.5F, xCoord, zCoord);
|
||||
}
|
||||
if(entity.slots[0].getItem() == ModItems.missile_taint) {
|
||||
missile = new EntityMissileTaint(world, x + 0.5F, y + 2F, z + 0.5F, xCoord, zCoord);
|
||||
}
|
||||
if(entity.slots[0].getItem() == ModItems.missile_micro) {
|
||||
missile = new EntityMissileMicro(world, x + 0.5F, y + 2F, z + 0.5F, xCoord, zCoord);
|
||||
}
|
||||
if(entity.slots[0].getItem() == ModItems.missile_bhole) {
|
||||
missile = new EntityMissileBHole(world, x + 0.5F, y + 2F, z + 0.5F, xCoord, zCoord);
|
||||
}
|
||||
if(entity.slots[0].getItem() == ModItems.missile_schrabidium) {
|
||||
missile = new EntityMissileSchrabidium(world, x + 0.5F, y + 2F, z + 0.5F, xCoord, zCoord);
|
||||
}
|
||||
if(entity.slots[0].getItem() == ModItems.missile_emp) {
|
||||
missile = new EntityMissileEMP(world, x + 0.5F, y + 2F, z + 0.5F, xCoord, zCoord);
|
||||
}
|
||||
if(entity.slots[0].getItem() == ModItems.missile_emp_strong) {
|
||||
missile = new EntityMissileEMPStrong(world, x + 0.5F, y + 2F, z + 0.5F, xCoord, zCoord);
|
||||
}
|
||||
if(entity.slots[0].getItem() == ModItems.missile_volcano) {
|
||||
missile = new EntityMissileVolcano(world, x + 0.5F, y + 2F, z + 0.5F, xCoord, zCoord);
|
||||
}
|
||||
if(entity.slots[0].getItem() == ModItems.missile_shuttle) {
|
||||
missile = new EntityMissileShuttle(world, x + 0.5F, y + 2F, z + 0.5F, xCoord, zCoord);
|
||||
}
|
||||
|
||||
if(missile != null) {
|
||||
world.spawnEntityInWorld(missile);
|
||||
world.playSoundEffect(x, y, z, "hbm:weapon.missileTakeOff", 2.0F, 1.0F);
|
||||
entity.power -= 75000;
|
||||
entity.slots[0] = null;
|
||||
return BombReturnCode.UNDEFINED;
|
||||
}
|
||||
|
||||
if(GeneralConfig.enableExtendedLogging)
|
||||
MainRegistry.logger.log(Level.INFO, "[MISSILE] Tried to launch missile at " + x + " / " + y + " / " + z + " to " + xCoord + " / " + zCoord + "!");
|
||||
return BombReturnCode.LAUNCHED;
|
||||
@Override
|
||||
public void onNeighborBlockChange(World world, int x, int y, int z, Block blockIn){
|
||||
|
||||
if(!world.isRemote){
|
||||
|
||||
int[] corePos = findCore(world, x, y, z);
|
||||
if(corePos != null){
|
||||
TileEntity core = world.getTileEntity(corePos[0], corePos[1], corePos[2]);
|
||||
if(core instanceof TileEntityLaunchPad){
|
||||
TileEntityLaunchPad launchpad = (TileEntityLaunchPad)core;
|
||||
launchpad.updateRedstonePower(x, y, z);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if(entity.slots[0] != null && entity.slots[0].getItem() == ModItems.missile_carrier && entity.power >= 75000) {
|
||||
EntityCarrier missile = new EntityCarrier(world);
|
||||
missile.posX = x + 0.5F;
|
||||
missile.posY = y + 1F;
|
||||
missile.posZ = z + 0.5F;
|
||||
|
||||
if(entity.slots[1] != null)
|
||||
missile.setPayload(entity.slots[1]);
|
||||
|
||||
world.spawnEntityInWorld(missile);
|
||||
entity.power -= 75000;
|
||||
|
||||
entity.slots[0] = null;
|
||||
entity.slots[1] = null;
|
||||
world.playSoundEffect(x, y, z, "hbm:entity.rocketTakeoff", 100.0F, 1.0F);
|
||||
return BombReturnCode.LAUNCHED;
|
||||
}
|
||||
|
||||
if(entity.slots[0] != null && entity.slots[0].getItem() == ModItems.missile_anti_ballistic && entity.power >= 75000) {
|
||||
EntityMissileAntiBallistic missile = new EntityMissileAntiBallistic(world);
|
||||
missile.posX = x + 0.5F;
|
||||
missile.posY = y + 0.5F;
|
||||
missile.posZ = z + 0.5F;
|
||||
|
||||
world.spawnEntityInWorld(missile);
|
||||
entity.power -= 75000;
|
||||
|
||||
entity.slots[0] = null;
|
||||
world.playSoundEffect(x, y, z, "hbm:weapon.missileTakeOff", 2.0F, 1.0F);
|
||||
return BombReturnCode.LAUNCHED;
|
||||
}
|
||||
|
||||
return BombReturnCode.ERROR_MISSING_COMPONENT;
|
||||
super.onNeighborBlockChange( world, x, y, z, blockIn);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void fillSpace(World world, int x, int y, int z, ForgeDirection dir, int o) {
|
||||
super.fillSpace(world, x, y, z, dir, o);
|
||||
|
||||
x += dir.offsetX * o;
|
||||
z += dir.offsetZ * o;
|
||||
|
||||
this.makeExtra(world, x + 1, y, z + 1);
|
||||
this.makeExtra(world, x + 1, y, z - 1);
|
||||
this.makeExtra(world, x - 1, y, z + 1);
|
||||
this.makeExtra(world, x - 1, y, z - 1);
|
||||
}
|
||||
}
|
||||
|
||||
98
src/main/java/com/hbm/blocks/bomb/LaunchPadLarge.java
Normal file
98
src/main/java/com/hbm/blocks/bomb/LaunchPadLarge.java
Normal file
@ -0,0 +1,98 @@
|
||||
package com.hbm.blocks.bomb;
|
||||
|
||||
import com.hbm.blocks.BlockDummyable;
|
||||
import com.hbm.interfaces.IBomb;
|
||||
import com.hbm.tileentity.TileEntityProxyCombo;
|
||||
import com.hbm.tileentity.bomb.TileEntityLaunchPadLarge;
|
||||
|
||||
import net.minecraft.block.Block;
|
||||
import net.minecraft.block.material.Material;
|
||||
import net.minecraft.entity.player.EntityPlayer;
|
||||
import net.minecraft.tileentity.TileEntity;
|
||||
import net.minecraft.util.AxisAlignedBB;
|
||||
import net.minecraft.world.World;
|
||||
import net.minecraftforge.common.util.ForgeDirection;
|
||||
|
||||
public class LaunchPadLarge extends BlockDummyable implements IBomb {
|
||||
|
||||
public LaunchPadLarge(Material mat) {
|
||||
super(mat);
|
||||
this.bounding.add(AxisAlignedBB.getBoundingBox(-4.5D, 0D, -4.5D, 4.5D, 1D, -0.5D));
|
||||
this.bounding.add(AxisAlignedBB.getBoundingBox(-4.5D, 0D, 0.5D, 4.5D, 1D, 4.5D));
|
||||
this.bounding.add(AxisAlignedBB.getBoundingBox(-4.5D, 0.875D, -0.5D, 4.5D, 1D, 0.5D));
|
||||
}
|
||||
|
||||
@Override
|
||||
public TileEntity createNewTileEntity(World world, int meta) {
|
||||
if(meta >= 12) return new TileEntityLaunchPadLarge();
|
||||
if(meta >= 6) return new TileEntityProxyCombo().inventory().power().fluid();
|
||||
return new TileEntityProxyCombo().inventory();
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean onBlockActivated(World world, int x, int y, int z, EntityPlayer player, int side, float hitX, float hitY, float hitZ) {
|
||||
return this.standardOpenBehavior(world, x, y, z, player, 0);
|
||||
}
|
||||
|
||||
@Override
|
||||
public int[] getDimensions() {
|
||||
return new int[] {0, 0, 4, 4, 4, 4};
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getOffset() {
|
||||
return 4;
|
||||
}
|
||||
|
||||
@Override
|
||||
public BombReturnCode explode(World world, int x, int y, int z) {
|
||||
|
||||
if(!world.isRemote) {
|
||||
|
||||
int[] corePos = findCore(world, x, y, z);
|
||||
if(corePos != null){
|
||||
TileEntity core = world.getTileEntity(corePos[0], corePos[1], corePos[2]);
|
||||
if(core instanceof TileEntityLaunchPadLarge){
|
||||
TileEntityLaunchPadLarge entity = (TileEntityLaunchPadLarge)core;
|
||||
return entity.launchFromDesignator();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return BombReturnCode.UNDEFINED;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onNeighborBlockChange(World world, int x, int y, int z, Block blockIn){
|
||||
|
||||
if(!world.isRemote){
|
||||
|
||||
int[] corePos = findCore(world, x, y, z);
|
||||
if(corePos != null){
|
||||
TileEntity core = world.getTileEntity(corePos[0], corePos[1], corePos[2]);
|
||||
if(core instanceof TileEntityLaunchPadLarge){
|
||||
TileEntityLaunchPadLarge launchpad = (TileEntityLaunchPadLarge)core;
|
||||
launchpad.updateRedstonePower(x, y, z);
|
||||
}
|
||||
}
|
||||
}
|
||||
super.onNeighborBlockChange( world, x, y, z, blockIn);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void fillSpace(World world, int x, int y, int z, ForgeDirection dir, int o) {
|
||||
super.fillSpace(world, x, y, z, dir, o);
|
||||
|
||||
x += dir.offsetX * o;
|
||||
z += dir.offsetZ * o;
|
||||
|
||||
this.makeExtra(world, x + 4, y, z + 2);
|
||||
this.makeExtra(world, x + 4, y, z - 2);
|
||||
this.makeExtra(world, x - 4, y, z + 2);
|
||||
this.makeExtra(world, x - 4, y, z - 2);
|
||||
this.makeExtra(world, x + 2, y, z + 4);
|
||||
this.makeExtra(world, x - 2, y, z + 4);
|
||||
this.makeExtra(world, x + 2, y, z - 4);
|
||||
this.makeExtra(world, x - 2, y, z - 4);
|
||||
}
|
||||
}
|
||||
89
src/main/java/com/hbm/blocks/bomb/LaunchPadRusted.java
Normal file
89
src/main/java/com/hbm/blocks/bomb/LaunchPadRusted.java
Normal file
@ -0,0 +1,89 @@
|
||||
package com.hbm.blocks.bomb;
|
||||
|
||||
import java.util.Random;
|
||||
|
||||
import com.hbm.blocks.BlockDummyable;
|
||||
import com.hbm.interfaces.IBomb;
|
||||
import com.hbm.tileentity.bomb.TileEntityLaunchPadRusted;
|
||||
|
||||
import net.minecraft.block.Block;
|
||||
import net.minecraft.block.material.Material;
|
||||
import net.minecraft.entity.player.EntityPlayer;
|
||||
import net.minecraft.item.Item;
|
||||
import net.minecraft.tileentity.TileEntity;
|
||||
import net.minecraft.util.AxisAlignedBB;
|
||||
import net.minecraft.world.World;
|
||||
|
||||
public class LaunchPadRusted extends BlockDummyable implements IBomb {
|
||||
|
||||
public LaunchPadRusted(Material mat) {
|
||||
super(mat);
|
||||
this.bounding.add(AxisAlignedBB.getBoundingBox(-1.5D, 0D, -1.5D, -0.5D, 1D, -0.5D));
|
||||
this.bounding.add(AxisAlignedBB.getBoundingBox(0.5D, 0D, -1.5D, 1.5D, 1D, -0.5D));
|
||||
this.bounding.add(AxisAlignedBB.getBoundingBox(-1.5D, 0D, 0.5D, -0.5D, 1D, 1.5D));
|
||||
this.bounding.add(AxisAlignedBB.getBoundingBox(0.5D, 0D, 0.5D, 1.5D, 1D, 1.5D));
|
||||
this.bounding.add(AxisAlignedBB.getBoundingBox(-0.5D, 0.5D, -1.5D, 0.5D, 1D, 1.5D));
|
||||
this.bounding.add(AxisAlignedBB.getBoundingBox(-1.5D, 0.5D, -0.5D, 1.5D, 1D, 0.5D));
|
||||
}
|
||||
|
||||
@Override
|
||||
public TileEntity createNewTileEntity(World world, int meta) {
|
||||
if(meta >= 12) return new TileEntityLaunchPadRusted();
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Item getItemDropped(int i, Random rand, int j) {
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean onBlockActivated(World world, int x, int y, int z, EntityPlayer player, int side, float hitX, float hitY, float hitZ) {
|
||||
return this.standardOpenBehavior(world, x, y, z, player, 0);
|
||||
}
|
||||
|
||||
@Override
|
||||
public int[] getDimensions() {
|
||||
return new int[] {0, 0, 1, 1, 1, 1};
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getOffset() {
|
||||
return 1;
|
||||
}
|
||||
|
||||
@Override
|
||||
public BombReturnCode explode(World world, int x, int y, int z) {
|
||||
|
||||
if(!world.isRemote) {
|
||||
|
||||
int[] corePos = findCore(world, x, y, z);
|
||||
if(corePos != null){
|
||||
TileEntity core = world.getTileEntity(corePos[0], corePos[1], corePos[2]);
|
||||
if(core instanceof TileEntityLaunchPadRusted){
|
||||
TileEntityLaunchPadRusted entity = (TileEntityLaunchPadRusted)core;
|
||||
return entity.launch();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return BombReturnCode.UNDEFINED;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onNeighborBlockChange(World world, int x, int y, int z, Block blockIn){
|
||||
|
||||
if(!world.isRemote){
|
||||
|
||||
int[] corePos = findCore(world, x, y, z);
|
||||
if(corePos != null){
|
||||
TileEntity core = world.getTileEntity(corePos[0], corePos[1], corePos[2]);
|
||||
if(core instanceof TileEntityLaunchPadRusted){
|
||||
TileEntityLaunchPadRusted launchpad = (TileEntityLaunchPadRusted)core;
|
||||
launchpad.updateRedstonePower(x, y, z);
|
||||
}
|
||||
}
|
||||
}
|
||||
super.onNeighborBlockChange( world, x, y, z, blockIn);
|
||||
}
|
||||
}
|
||||
@ -163,7 +163,7 @@ public class LaunchTable extends BlockContainer implements IMultiblock, IBomb {
|
||||
TileEntityLaunchTable entity = (TileEntityLaunchTable) world.getTileEntity(x, y, z);
|
||||
|
||||
if(entity.canLaunch()) {
|
||||
entity.launch();
|
||||
entity.launchFromDesignator();
|
||||
return BombReturnCode.LAUNCHED;
|
||||
}
|
||||
|
||||
|
||||
@ -4,11 +4,12 @@ import java.util.Random;
|
||||
|
||||
import com.hbm.blocks.ModBlocks;
|
||||
import com.hbm.config.BombConfig;
|
||||
import com.hbm.entity.effect.EntityNukeCloudSmall;
|
||||
import com.hbm.entity.effect.EntityNukeTorex;
|
||||
import com.hbm.entity.logic.EntityNukeExplosionMK5;
|
||||
import com.hbm.interfaces.IBomb;
|
||||
import com.hbm.main.MainRegistry;
|
||||
import com.hbm.tileentity.bomb.TileEntityNukeBoy;
|
||||
import com.hbm.util.TrackerUtil;
|
||||
|
||||
import cpw.mods.fml.common.network.internal.FMLNetworkHandler;
|
||||
import net.minecraft.block.Block;
|
||||
@ -124,7 +125,13 @@ public class NukeBoy extends BlockContainer implements IBomb {
|
||||
world.playSoundEffect(x, y, z, "random.explode", 1.0f, world.rand.nextFloat() * 0.1F + 0.9F);
|
||||
|
||||
world.spawnEntityInWorld(EntityNukeExplosionMK5.statFac(world, BombConfig.boyRadius, x + 0.5, y + 0.5, z + 0.5));
|
||||
world.spawnEntityInWorld(EntityNukeCloudSmall.statFac(world, x, y, z, BombConfig.boyRadius));
|
||||
//world.spawnEntityInWorld(EntityNukeCloudSmall.statFac(world, x, y, z, BombConfig.boyRadius));
|
||||
|
||||
EntityNukeTorex torex = new EntityNukeTorex(world);
|
||||
torex.setPositionAndRotation(x + 0.5, y + 1, z + 0.5, 0, 0);
|
||||
torex.getDataWatcher().updateObject(10, 1.5F);
|
||||
world.spawnEntityInWorld(torex);
|
||||
TrackerUtil.setTrackingRange(world, torex, 1000);
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
@ -4,7 +4,7 @@ import java.util.Random;
|
||||
|
||||
import com.hbm.blocks.ModBlocks;
|
||||
import com.hbm.entity.effect.EntityCloudFleija;
|
||||
import com.hbm.entity.effect.EntityNukeCloudSmall;
|
||||
import com.hbm.entity.effect.EntityNukeTorex;
|
||||
import com.hbm.entity.grenade.EntityGrenadeZOMG;
|
||||
import com.hbm.entity.logic.EntityBalefire;
|
||||
import com.hbm.entity.logic.EntityNukeExplosionMK3;
|
||||
@ -169,7 +169,7 @@ public class NukeCustom extends BlockContainer implements IBomb {
|
||||
bf.setPosition(xCoord + 0.5, yCoord + 0.5, zCoord + 0.5);
|
||||
bf.destructionRange = (int) amat;
|
||||
worldObj.spawnEntityInWorld(bf);
|
||||
worldObj.spawnEntityInWorld(EntityNukeCloudSmall.statFacBale(worldObj, xCoord + 0.5, yCoord + 5, zCoord + 0.5, amat * 1.5F, 1000));
|
||||
EntityNukeTorex.statFacBale(worldObj, xCoord + 0.5, yCoord + 5, zCoord + 0.5, amat);
|
||||
|
||||
/// HYDROGEN ///
|
||||
} else if(hydro > 0) {
|
||||
@ -179,7 +179,7 @@ public class NukeCustom extends BlockContainer implements IBomb {
|
||||
dirty *= 0.25F;
|
||||
|
||||
worldObj.spawnEntityInWorld(EntityNukeExplosionMK5.statFac(worldObj, (int)hydro, xCoord + 0.5, yCoord + 0.5, zCoord + 0.5).moreFallout((int)dirty));
|
||||
worldObj.spawnEntityInWorld(EntityNukeCloudSmall.statFac(worldObj, xCoord + 0.5, yCoord + 5, zCoord + 0.5, hydro));
|
||||
EntityNukeTorex.statFac(worldObj, xCoord + 0.5, yCoord + 5, zCoord + 0.5, hydro);
|
||||
|
||||
/// NUCLEAR ///
|
||||
} else if(nuke > 0) {
|
||||
@ -188,7 +188,7 @@ public class NukeCustom extends BlockContainer implements IBomb {
|
||||
nuke = Math.min(nuke, maxNuke);
|
||||
|
||||
worldObj.spawnEntityInWorld(EntityNukeExplosionMK5.statFac(worldObj, (int)nuke, xCoord + 0.5, yCoord + 5, zCoord + 0.5).moreFallout((int)dirty));
|
||||
worldObj.spawnEntityInWorld(EntityNukeCloudSmall.statFac(worldObj, xCoord + 0.5, yCoord + 5, zCoord + 0.5, nuke));
|
||||
EntityNukeTorex.statFac(worldObj, xCoord + 0.5, yCoord + 5, zCoord + 0.5, nuke);
|
||||
|
||||
/// NON-NUCLEAR ///
|
||||
} else if(tnt >= 75) {
|
||||
@ -196,7 +196,7 @@ public class NukeCustom extends BlockContainer implements IBomb {
|
||||
tnt = Math.min(tnt, maxTnt);
|
||||
|
||||
worldObj.spawnEntityInWorld(EntityNukeExplosionMK5.statFacNoRad(worldObj, (int)tnt, xCoord + 0.5, yCoord + 0.5, zCoord + 0.5));
|
||||
worldObj.spawnEntityInWorld(EntityNukeCloudSmall.statFac(worldObj, xCoord + 0.5, yCoord + 5, zCoord + 0.5, tnt));
|
||||
EntityNukeTorex.statFac(worldObj, xCoord + 0.5, yCoord + 5, zCoord + 0.5, tnt);
|
||||
} else if(tnt > 0) {
|
||||
|
||||
ExplosionLarge.explode(worldObj, xCoord + 0.5, yCoord + 0.5, zCoord + 0.5, tnt, true, true, true);
|
||||
|
||||
@ -4,7 +4,7 @@ import java.util.Random;
|
||||
|
||||
import com.hbm.blocks.ModBlocks;
|
||||
import com.hbm.config.BombConfig;
|
||||
import com.hbm.entity.effect.EntityNukeCloudSmall;
|
||||
import com.hbm.entity.effect.EntityNukeTorex;
|
||||
import com.hbm.entity.logic.EntityNukeExplosionMK5;
|
||||
import com.hbm.interfaces.IBomb;
|
||||
import com.hbm.main.MainRegistry;
|
||||
@ -130,13 +130,8 @@ public class NukeGadget extends BlockContainer implements IBomb {
|
||||
tetn.clearSlots();
|
||||
world.playSoundEffect(x, y, z, "random.explode", 1.0f, world.rand.nextFloat() * 0.1F + 0.9F);
|
||||
|
||||
world.spawnEntityInWorld(EntityNukeExplosionMK5.statFac(world, BombConfig.gadgetRadius, x + 0.5, y + 0.5, z + 0.5));
|
||||
|
||||
EntityNukeCloudSmall entity2 = new EntityNukeCloudSmall(world, 1000, BombConfig.gadgetRadius * 0.005F);
|
||||
entity2.posX = x;
|
||||
entity2.posY = y;
|
||||
entity2.posZ = z;
|
||||
world.spawnEntityInWorld(entity2);
|
||||
world.spawnEntityInWorld(EntityNukeExplosionMK5.statFac(world, BombConfig.gadgetRadius, x + 0.5, y + 0.5, z + 0.5));
|
||||
EntityNukeTorex.statFac(world, x + 0.5, y + 0.5, z + 0.5, BombConfig.gadgetRadius);
|
||||
}
|
||||
|
||||
return false;
|
||||
|
||||
@ -4,7 +4,7 @@ import java.util.Random;
|
||||
|
||||
import com.hbm.blocks.ModBlocks;
|
||||
import com.hbm.config.BombConfig;
|
||||
import com.hbm.entity.effect.EntityNukeCloudSmall;
|
||||
import com.hbm.entity.effect.EntityNukeTorex;
|
||||
import com.hbm.entity.logic.EntityNukeExplosionMK5;
|
||||
import com.hbm.interfaces.IBomb;
|
||||
import com.hbm.main.MainRegistry;
|
||||
@ -124,12 +124,7 @@ public class NukeMan extends BlockContainer implements IBomb {
|
||||
world.playSoundEffect(x, y, z, "random.explode", 1.0f, world.rand.nextFloat() * 0.1F + 0.9F);
|
||||
|
||||
world.spawnEntityInWorld(EntityNukeExplosionMK5.statFac(world, BombConfig.manRadius, x + 0.5, y + 0.5, z + 0.5));
|
||||
|
||||
EntityNukeCloudSmall entity2 = new EntityNukeCloudSmall(world, 1000, BombConfig.manRadius * 0.005F);
|
||||
entity2.posX = x;
|
||||
entity2.posY = y;
|
||||
entity2.posZ = z;
|
||||
world.spawnEntityInWorld(entity2);
|
||||
EntityNukeTorex.statFac(world, x + 0.5, y + 0.5, z + 0.5, BombConfig.manRadius);
|
||||
}
|
||||
|
||||
return false;
|
||||
|
||||
@ -4,7 +4,7 @@ import java.util.Random;
|
||||
|
||||
import com.hbm.blocks.ModBlocks;
|
||||
import com.hbm.config.BombConfig;
|
||||
import com.hbm.entity.effect.EntityNukeCloudSmall;
|
||||
import com.hbm.entity.effect.EntityNukeTorex;
|
||||
import com.hbm.entity.logic.EntityNukeExplosionMK5;
|
||||
import com.hbm.interfaces.IBomb;
|
||||
import com.hbm.main.MainRegistry;
|
||||
@ -131,12 +131,7 @@ public class NukeMike extends BlockContainer implements IBomb {
|
||||
world.playSoundEffect(x, y, z, "random.explode", 1.0f, world.rand.nextFloat() * 0.1F + 0.9F);
|
||||
|
||||
world.spawnEntityInWorld(EntityNukeExplosionMK5.statFac(world, BombConfig.mikeRadius, x + 0.5, y + 0.5, z + 0.5));
|
||||
|
||||
EntityNukeCloudSmall entity2 = new EntityNukeCloudSmall(world, 1000, r * 0.005F);
|
||||
entity2.posX = x;
|
||||
entity2.posY = y;
|
||||
entity2.posZ = z;
|
||||
world.spawnEntityInWorld(entity2);
|
||||
EntityNukeTorex.statFac(world, x + 0.5, y + 0.5, z + 0.5, BombConfig.mikeRadius);
|
||||
}
|
||||
|
||||
return false;
|
||||
|
||||
@ -4,7 +4,7 @@ import java.util.Random;
|
||||
|
||||
import com.hbm.blocks.ModBlocks;
|
||||
import com.hbm.config.BombConfig;
|
||||
import com.hbm.entity.effect.EntityNukeCloudSmall;
|
||||
import com.hbm.entity.effect.EntityNukeTorex;
|
||||
import com.hbm.entity.logic.EntityNukeExplosionMK5;
|
||||
import com.hbm.interfaces.IBomb;
|
||||
import com.hbm.main.MainRegistry;
|
||||
@ -120,12 +120,7 @@ public class NukeN2 extends BlockContainer implements IBomb {
|
||||
world.playSoundEffect(x, y, z, "random.explode", 1.0f, world.rand.nextFloat() * 0.1F + 0.9F);
|
||||
|
||||
world.spawnEntityInWorld(EntityNukeExplosionMK5.statFacNoRad(world, r, x + 0.5, y + 0.5, z + 0.5));
|
||||
|
||||
EntityNukeCloudSmall entity2 = new EntityNukeCloudSmall(world, 1000, r * 0.005F);
|
||||
entity2.posX = x;
|
||||
entity2.posY = y;
|
||||
entity2.posZ = z;
|
||||
world.spawnEntityInWorld(entity2);
|
||||
EntityNukeTorex.statFac(world, x + 0.5, y + 0.5, z + 0.5, r);
|
||||
}
|
||||
|
||||
return false;
|
||||
|
||||
@ -1,137 +0,0 @@
|
||||
package com.hbm.blocks.bomb;
|
||||
|
||||
import java.util.Random;
|
||||
|
||||
import com.hbm.blocks.ModBlocks;
|
||||
import com.hbm.interfaces.IBomb;
|
||||
import com.hbm.main.MainRegistry;
|
||||
import com.hbm.tileentity.bomb.TileEntityNukeN45;
|
||||
|
||||
import cpw.mods.fml.common.network.internal.FMLNetworkHandler;
|
||||
import net.minecraft.block.Block;
|
||||
import net.minecraft.block.BlockContainer;
|
||||
import net.minecraft.block.material.Material;
|
||||
import net.minecraft.entity.item.EntityItem;
|
||||
import net.minecraft.entity.player.EntityPlayer;
|
||||
import net.minecraft.inventory.ISidedInventory;
|
||||
import net.minecraft.item.Item;
|
||||
import net.minecraft.item.ItemStack;
|
||||
import net.minecraft.nbt.NBTTagCompound;
|
||||
import net.minecraft.tileentity.TileEntity;
|
||||
import net.minecraft.world.World;
|
||||
|
||||
public class NukeN45 extends BlockContainer implements IBomb {
|
||||
|
||||
private final Random field_149933_a = new Random();
|
||||
private static boolean keepInventory = false;
|
||||
|
||||
public NukeN45(Material p_i45386_1_) {
|
||||
super(p_i45386_1_);
|
||||
}
|
||||
|
||||
@Override
|
||||
public TileEntity createNewTileEntity(World p_149915_1_, int p_149915_2_) {
|
||||
return new TileEntityNukeN45();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void breakBlock(World p_149749_1_, int p_149749_2_, int p_149749_3_, int p_149749_4_, Block p_149749_5_, int p_149749_6_) {
|
||||
if(!keepInventory) {
|
||||
ISidedInventory tileentityfurnace = (ISidedInventory) p_149749_1_.getTileEntity(p_149749_2_, p_149749_3_, p_149749_4_);
|
||||
|
||||
if(tileentityfurnace != null) {
|
||||
for(int i1 = 0; i1 < tileentityfurnace.getSizeInventory(); ++i1) {
|
||||
ItemStack itemstack = tileentityfurnace.getStackInSlot(i1);
|
||||
|
||||
if(itemstack != null) {
|
||||
float f = this.field_149933_a.nextFloat() * 0.8F + 0.1F;
|
||||
float f1 = this.field_149933_a.nextFloat() * 0.8F + 0.1F;
|
||||
float f2 = this.field_149933_a.nextFloat() * 0.8F + 0.1F;
|
||||
|
||||
while(itemstack.stackSize > 0) {
|
||||
int j1 = this.field_149933_a.nextInt(21) + 10;
|
||||
|
||||
if(j1 > itemstack.stackSize) {
|
||||
j1 = itemstack.stackSize;
|
||||
}
|
||||
|
||||
itemstack.stackSize -= j1;
|
||||
EntityItem entityitem = new EntityItem(p_149749_1_, p_149749_2_ + f, p_149749_3_ + f1, p_149749_4_ + f2, new ItemStack(itemstack.getItem(), j1, itemstack.getItemDamage()));
|
||||
|
||||
if(itemstack.hasTagCompound()) {
|
||||
entityitem.getEntityItem().setTagCompound((NBTTagCompound) itemstack.getTagCompound().copy());
|
||||
}
|
||||
|
||||
float f3 = 0.05F;
|
||||
entityitem.motionX = (float) this.field_149933_a.nextGaussian() * f3;
|
||||
entityitem.motionY = (float) this.field_149933_a.nextGaussian() * f3 + 0.2F;
|
||||
entityitem.motionZ = (float) this.field_149933_a.nextGaussian() * f3;
|
||||
p_149749_1_.spawnEntityInWorld(entityitem);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
p_149749_1_.func_147453_f(p_149749_2_, p_149749_3_, p_149749_4_, p_149749_5_);
|
||||
}
|
||||
}
|
||||
|
||||
super.breakBlock(p_149749_1_, p_149749_2_, p_149749_3_, p_149749_4_, p_149749_5_, p_149749_6_);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean onBlockActivated(World world, int x, int y, int z, EntityPlayer player, int side, float hitX, float hitY, float hitZ) {
|
||||
if(world.isRemote) {
|
||||
return true;
|
||||
} else if(!player.isSneaking()) {
|
||||
TileEntityNukeN45 entity = (TileEntityNukeN45) world.getTileEntity(x, y, z);
|
||||
if(entity != null) {
|
||||
FMLNetworkHandler.openGui(player, MainRegistry.instance, 0, world, x, y, z);
|
||||
}
|
||||
return true;
|
||||
} else {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public Item getItemDropped(int p_149650_1_, Random p_149650_2_, int p_149650_3_) {
|
||||
return Item.getItemFromBlock(ModBlocks.nuke_n45);
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getRenderType() {
|
||||
return -1;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isOpaqueCube() {
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean renderAsNormalBlock() {
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public BombReturnCode explode(World world, int x, int y, int z) {
|
||||
|
||||
if(!world.isRemote) {
|
||||
TileEntityNukeN45 entity = (TileEntityNukeN45) world.getTileEntity(x, y, z);
|
||||
|
||||
if(entity.getType() == 100) {
|
||||
entity.primed = true;
|
||||
return BombReturnCode.TRIGGERED;
|
||||
} else if(!entity.primed && entity.getType() > 0) {
|
||||
int t = entity.getType();
|
||||
entity.clearSlots();
|
||||
entity.explode(world, x, y, z, t);
|
||||
return BombReturnCode.DETONATED;
|
||||
}
|
||||
|
||||
return BombReturnCode.ERROR_MISSING_COMPONENT;
|
||||
}
|
||||
|
||||
return BombReturnCode.UNDEFINED;
|
||||
}
|
||||
}
|
||||
@ -4,7 +4,7 @@ import java.util.Random;
|
||||
|
||||
import com.hbm.blocks.ModBlocks;
|
||||
import com.hbm.config.BombConfig;
|
||||
import com.hbm.entity.effect.EntityNukeCloudSmall;
|
||||
import com.hbm.entity.effect.EntityNukeTorex;
|
||||
import com.hbm.entity.logic.EntityNukeExplosionMK5;
|
||||
import com.hbm.interfaces.IBomb;
|
||||
import com.hbm.main.MainRegistry;
|
||||
@ -127,18 +127,9 @@ public class NukeTsar extends BlockContainer implements IBomb {
|
||||
public boolean igniteTestBomb(World world, int x, int y, int z, int r) {
|
||||
if(!world.isRemote) {
|
||||
tetn.clearSlots();
|
||||
// world.spawnParticle("hugeexplosion", x, y, z, 0, 0, 0);
|
||||
world.playSoundEffect(x, y, z, "random.explode", 1.0f, world.rand.nextFloat() * 0.1F + 0.9F);
|
||||
|
||||
world.spawnEntityInWorld(EntityNukeExplosionMK5.statFac(world, r, x + 0.5, y + 0.5, z + 0.5));
|
||||
|
||||
EntityNukeCloudSmall entity2 = new EntityNukeCloudSmall(world, 1000, r * 0.005F);
|
||||
entity2.posX = x;
|
||||
entity2.posY = y;
|
||||
entity2.posZ = z;
|
||||
world.spawnEntityInWorld(entity2);
|
||||
|
||||
// ExplosionNukeAdvanced.mush(world, x, y, z);
|
||||
EntityNukeTorex.statFac(world, x + 0.5, y + 0.5, z + 0.5, r);
|
||||
}
|
||||
|
||||
return false;
|
||||
|
||||
@ -62,7 +62,7 @@ public class CoriumBlock extends BlockFluidClassic {
|
||||
return true;
|
||||
Random rand = new Random();
|
||||
|
||||
return b.getMaterial().isLiquid() || rand.nextInt((int) res) == 0;
|
||||
return b.getMaterial().isLiquid() || rand.nextInt((int) (res * res)) == 0;
|
||||
}
|
||||
|
||||
@Override
|
||||
|
||||
84
src/main/java/com/hbm/blocks/fluid/CoriumFinite.java
Normal file
84
src/main/java/com/hbm/blocks/fluid/CoriumFinite.java
Normal file
@ -0,0 +1,84 @@
|
||||
package com.hbm.blocks.fluid;
|
||||
|
||||
import java.util.Random;
|
||||
|
||||
import com.hbm.blocks.ModBlocks;
|
||||
import com.hbm.lib.ModDamageSource;
|
||||
import com.hbm.util.ContaminationUtil;
|
||||
import com.hbm.util.ContaminationUtil.ContaminationType;
|
||||
import com.hbm.util.ContaminationUtil.HazardType;
|
||||
|
||||
import cpw.mods.fml.relauncher.Side;
|
||||
import cpw.mods.fml.relauncher.SideOnly;
|
||||
import net.minecraft.block.Block;
|
||||
import net.minecraft.block.material.Material;
|
||||
import net.minecraft.entity.Entity;
|
||||
import net.minecraft.entity.EntityLivingBase;
|
||||
import net.minecraft.world.IBlockAccess;
|
||||
import net.minecraft.world.World;
|
||||
import net.minecraftforge.fluids.Fluid;
|
||||
|
||||
public class CoriumFinite extends GenericFiniteFluid {
|
||||
|
||||
public CoriumFinite(Fluid fluid, Material material) {
|
||||
super(fluid, material, "corium_still", "corium_flowing");
|
||||
setQuantaPerBlock(5);
|
||||
this.tickRate = 30;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean canDisplace(IBlockAccess world, int x, int y, int z) {
|
||||
Block b = world.getBlock(x, y, z);
|
||||
float res = (float) (Math.sqrt(b.getExplosionResistance(null)) * 3);
|
||||
|
||||
if(res < 1)
|
||||
return true;
|
||||
Random rand = new Random();
|
||||
|
||||
return b.getMaterial().isLiquid() || rand.nextInt((int) res) == 0;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean displaceIfPossible(World world, int x, int y, int z) {
|
||||
|
||||
if(world.getBlock(x, y, z).getMaterial().isLiquid()) {
|
||||
return false;
|
||||
}
|
||||
return canDisplace(world, x, y, z);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onEntityCollidedWithBlock(World world, int x, int y, int z, Entity entity) {
|
||||
entity.setInWeb();
|
||||
entity.setFire(3);
|
||||
entity.attackEntityFrom(ModDamageSource.radiation, 2F);
|
||||
|
||||
if(entity instanceof EntityLivingBase)
|
||||
ContaminationUtil.contaminate((EntityLivingBase)entity, HazardType.RADIATION, ContaminationType.CREATIVE, 1F);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void updateTick(World world, int x, int y, int z, Random rand) {
|
||||
|
||||
super.updateTick(world, x, y, z, rand);
|
||||
|
||||
if(!world.isRemote && rand.nextInt(10) == 0 && world.getBlock(x, y - 1, z) != this) {
|
||||
|
||||
if(rand.nextInt(3) == 0)
|
||||
world.setBlock(x, y, z, ModBlocks.block_corium);
|
||||
else
|
||||
world.setBlock(x, y, z, ModBlocks.block_corium_cobble);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
@SideOnly(Side.CLIENT)
|
||||
public int getRenderBlockPass() {
|
||||
return 0;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isReplaceable(IBlockAccess world, int x, int y, int z) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
81
src/main/java/com/hbm/blocks/fluid/RadBlock.java
Normal file
81
src/main/java/com/hbm/blocks/fluid/RadBlock.java
Normal file
@ -0,0 +1,81 @@
|
||||
package com.hbm.blocks.fluid;
|
||||
|
||||
import java.util.Random;
|
||||
|
||||
import com.hbm.blocks.ModBlocks;
|
||||
import com.hbm.lib.RefStrings;
|
||||
import com.hbm.util.ContaminationUtil;
|
||||
import com.hbm.util.ContaminationUtil.ContaminationType;
|
||||
import com.hbm.util.ContaminationUtil.HazardType;
|
||||
|
||||
import cpw.mods.fml.relauncher.Side;
|
||||
import cpw.mods.fml.relauncher.SideOnly;
|
||||
import net.minecraft.block.Block;
|
||||
import net.minecraft.block.material.Material;
|
||||
import net.minecraft.client.renderer.texture.IIconRegister;
|
||||
import net.minecraft.entity.Entity;
|
||||
import net.minecraft.entity.EntityLivingBase;
|
||||
import net.minecraft.init.Blocks;
|
||||
import net.minecraft.util.IIcon;
|
||||
import net.minecraft.world.World;
|
||||
import net.minecraftforge.fluids.Fluid;
|
||||
|
||||
public class RadBlock extends VolcanicBlock {
|
||||
|
||||
@SideOnly(Side.CLIENT) public static IIcon stillIconRad;
|
||||
@SideOnly(Side.CLIENT) public static IIcon flowingIconRad;
|
||||
|
||||
public RadBlock(Fluid fluid, Material material) {
|
||||
super(fluid, material);
|
||||
}
|
||||
|
||||
@Override
|
||||
@SideOnly(Side.CLIENT)
|
||||
public void registerBlockIcons(IIconRegister register) {
|
||||
stillIconRad = register.registerIcon(RefStrings.MODID + ":rad_lava_still");
|
||||
flowingIconRad = register.registerIcon(RefStrings.MODID + ":rad_lava_flowing");
|
||||
}
|
||||
|
||||
@Override
|
||||
@SideOnly(Side.CLIENT)
|
||||
public IIcon getIcon(int side, int meta) {
|
||||
return (side == 0 || side == 1) ? stillIconRad : flowingIconRad;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onEntityCollidedWithBlock(World world, int x, int y, int z, Entity entity) {
|
||||
if(entity instanceof EntityLivingBase) ContaminationUtil.contaminate((EntityLivingBase) entity, HazardType.RADIATION, ContaminationType.CREATIVE, 5F);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onSolidify(World world, int x, int y, int z, int lavaCount, int basaltCount, Random rand) {
|
||||
int r = rand.nextInt(400);
|
||||
|
||||
Block above = world.getBlock(x, y + 10, z);
|
||||
boolean canMakeGem = lavaCount + basaltCount == 6 && lavaCount < 3 && (above == ModBlocks.sellafield_slaked || above == ModBlocks.rad_lava_block);
|
||||
int meta = 5 + rand.nextInt(3);
|
||||
|
||||
if(r < 2) world.setBlock(x, y, z, ModBlocks.ore_sellafield_diamond, meta, 3);
|
||||
else if(r == 2) world.setBlock(x, y, z, ModBlocks.ore_sellafield_emerald, meta, 3);
|
||||
else if(r < 20 && canMakeGem) world.setBlock(x, y, z, ModBlocks.ore_sellafield_radgem, meta, 3);
|
||||
else world.setBlock(x, y, z, ModBlocks.sellafield_slaked, meta, 3);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Block getBasaltForCheck() {
|
||||
return ModBlocks.sellafield_slaked;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Block getReaction(World world, int x, int y, int z) {
|
||||
|
||||
Block b = world.getBlock(x, y, z);
|
||||
if(b.getMaterial() == Material.water) return Blocks.stone;
|
||||
if(b == Blocks.log || b == Blocks.log2) return ModBlocks.waste_log;
|
||||
if(b == Blocks.planks) return ModBlocks.waste_planks;
|
||||
if(b == Blocks.leaves || b == Blocks.leaves2) return Blocks.fire;
|
||||
if(b == Blocks.diamond_ore) return ModBlocks.ore_sellafield_radgem;
|
||||
if(b == ModBlocks.ore_uranium || b == ModBlocks.ore_gneiss_uranium) return world.rand.nextInt(5) == 0 ? ModBlocks.ore_sellafield_schrabidium : ModBlocks.ore_sellafield_uranium_scorched;
|
||||
return null;
|
||||
}
|
||||
}
|
||||
31
src/main/java/com/hbm/blocks/fluid/RadFluid.java
Normal file
31
src/main/java/com/hbm/blocks/fluid/RadFluid.java
Normal file
@ -0,0 +1,31 @@
|
||||
package com.hbm.blocks.fluid;
|
||||
|
||||
import cpw.mods.fml.relauncher.Side;
|
||||
import cpw.mods.fml.relauncher.SideOnly;
|
||||
import net.minecraft.util.IIcon;
|
||||
import net.minecraftforge.fluids.Fluid;
|
||||
|
||||
public class RadFluid extends Fluid {
|
||||
|
||||
public RadFluid() {
|
||||
super("rad_lava_fluid");
|
||||
}
|
||||
|
||||
@Override
|
||||
@SideOnly(Side.CLIENT)
|
||||
public IIcon getIcon() {
|
||||
return getStillIcon();
|
||||
}
|
||||
|
||||
@Override
|
||||
@SideOnly(Side.CLIENT)
|
||||
public IIcon getStillIcon() {
|
||||
return RadBlock.stillIconRad;
|
||||
}
|
||||
|
||||
@Override
|
||||
@SideOnly(Side.CLIENT)
|
||||
public IIcon getFlowingIcon() {
|
||||
return RadBlock.flowingIconRad;
|
||||
}
|
||||
}
|
||||
@ -51,26 +51,18 @@ public class VolcanicBlock extends BlockFluidClassic {
|
||||
for(ForgeDirection dir : ForgeDirection.VALID_DIRECTIONS) {
|
||||
Block b = getReaction(world, x + dir.offsetX, y + dir.offsetY, z + dir.offsetZ);
|
||||
|
||||
if(b != null)
|
||||
world.setBlock(x + dir.offsetX, y + dir.offsetY, z + dir.offsetZ, b);
|
||||
if(b != null) world.setBlock(x + dir.offsetX, y + dir.offsetY, z + dir.offsetZ, b, b == ModBlocks.ore_basalt ? 3 : 0, 3);
|
||||
}
|
||||
}
|
||||
|
||||
public Block getReaction(World world, int x, int y, int z) {
|
||||
|
||||
Block b = world.getBlock(x, y, z);
|
||||
if(b.getMaterial() == Material.water) {
|
||||
return Blocks.stone;
|
||||
}
|
||||
if(b == Blocks.log || b == Blocks.log2) {
|
||||
return ModBlocks.waste_log;
|
||||
}
|
||||
if(b == Blocks.planks) {
|
||||
return ModBlocks.waste_planks;
|
||||
}
|
||||
if(b == Blocks.leaves || b == Blocks.leaves2) {
|
||||
return Blocks.fire;
|
||||
}
|
||||
if(b.getMaterial() == Material.water) return Blocks.stone;
|
||||
if(b == Blocks.log || b == Blocks.log2) return ModBlocks.waste_log;
|
||||
if(b == Blocks.planks) return ModBlocks.waste_planks;
|
||||
if(b == Blocks.leaves || b == Blocks.leaves2) return Blocks.fire;
|
||||
if(b == Blocks.diamond_ore) return ModBlocks.ore_basalt;
|
||||
return null;
|
||||
}
|
||||
|
||||
@ -87,30 +79,33 @@ public class VolcanicBlock extends BlockFluidClassic {
|
||||
|
||||
if(b == this)
|
||||
lavaCount++;
|
||||
if(b == ModBlocks.basalt) {
|
||||
if(b == getBasaltForCheck()) {
|
||||
basaltCount++;
|
||||
}
|
||||
}
|
||||
|
||||
if(!world.isRemote && ((!this.isSourceBlock(world, x, y, z) && lavaCount < 2) || (rand.nextInt(5) == 0) && lavaCount < 5) && world.getBlock(x, y - 1, z) != this) {
|
||||
|
||||
int r = rand.nextInt(200);
|
||||
|
||||
Block above = world.getBlock(x, y + 10, z);
|
||||
boolean canMakeGem = lavaCount + basaltCount == 6 && lavaCount < 3 && (above == ModBlocks.basalt || above == ModBlocks.volcanic_lava_block);
|
||||
|
||||
if(r < 2)
|
||||
world.setBlock(x, y, z, ModBlocks.basalt_sulfur);
|
||||
else if(r == 2)
|
||||
world.setBlock(x, y, z, ModBlocks.basalt_asbestos);
|
||||
else if(r == 3)
|
||||
world.setBlock(x, y, z, ModBlocks.basalt_fluorite);
|
||||
else if(r < 14 && canMakeGem)
|
||||
world.setBlock(x, y, z, ModBlocks.basalt_gem);
|
||||
else
|
||||
world.setBlock(x, y, z, ModBlocks.basalt);
|
||||
this.onSolidify(world, x, y, z, lavaCount, basaltCount, rand);
|
||||
}
|
||||
}
|
||||
|
||||
public Block getBasaltForCheck() {
|
||||
return ModBlocks.basalt;
|
||||
}
|
||||
|
||||
public void onSolidify(World world, int x, int y, int z, int lavaCount, int basaltCount, Random rand) {
|
||||
int r = rand.nextInt(200);
|
||||
|
||||
Block above = world.getBlock(x, y + 10, z);
|
||||
boolean canMakeGem = lavaCount + basaltCount == 6 && lavaCount < 3 && (above == ModBlocks.basalt || above == ModBlocks.volcanic_lava_block);
|
||||
|
||||
if(r < 2) world.setBlock(x, y, z, ModBlocks.ore_basalt, 0, 3);
|
||||
else if(r == 2) world.setBlock(x, y, z, ModBlocks.ore_basalt, 1, 3);
|
||||
else if(r == 3) world.setBlock(x, y, z, ModBlocks.ore_basalt, 2, 3);
|
||||
else if(r == 4) world.setBlock(x, y, z, ModBlocks.ore_basalt, 4, 3);
|
||||
else if(r < 15 && canMakeGem) world.setBlock(x, y, z, ModBlocks.ore_basalt, 3, 3);
|
||||
else world.setBlock(x, y, z, ModBlocks.basalt);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean canDisplace(IBlockAccess world, int x, int y, int z) {
|
||||
|
||||
@ -40,7 +40,7 @@ public class BlockGasClorine extends BlockGasBase {
|
||||
|
||||
EntityLivingBase entityLiving = (EntityLivingBase) entity;
|
||||
|
||||
if(ArmorRegistry.hasAllProtection(entityLiving, 3, HazardClass.GAS_CHLORINE)) {
|
||||
if(ArmorRegistry.hasAllProtection(entityLiving, 3, HazardClass.GAS_LUNG)) {
|
||||
ArmorUtil.damageGasMaskFilter(entityLiving, 1);
|
||||
|
||||
} else {
|
||||
|
||||
@ -3,8 +3,8 @@ package com.hbm.blocks.generic;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Random;
|
||||
|
||||
import com.hbm.items.ItemAmmoEnums.*;
|
||||
import com.hbm.items.ModItems;
|
||||
import com.hbm.items.weapon.sedna.factory.GunFactory.EnumAmmo;
|
||||
import com.hbm.lib.RefStrings;
|
||||
|
||||
import cpw.mods.fml.relauncher.Side;
|
||||
@ -12,6 +12,7 @@ import cpw.mods.fml.relauncher.SideOnly;
|
||||
import net.minecraft.block.Block;
|
||||
import net.minecraft.block.material.Material;
|
||||
import net.minecraft.client.renderer.texture.IIconRegister;
|
||||
import net.minecraft.entity.player.EntityPlayer;
|
||||
import net.minecraft.item.ItemStack;
|
||||
import net.minecraft.util.IIcon;
|
||||
import net.minecraft.world.World;
|
||||
@ -38,37 +39,52 @@ public class BlockAmmoCrate extends Block {
|
||||
public IIcon getIcon(int side, int metadata) {
|
||||
return side == 0 ? this.iconBottom : (side == 1 ? this.iconTop : this.blockIcon);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean onBlockActivated(World world, int x, int y, int z, EntityPlayer player, int p_149727_6_, float p_149727_7_, float p_149727_8_, float p_149727_9_) {
|
||||
if(player.getHeldItem() != null && player.getHeldItem().getItem().equals(ModItems.crowbar)) {
|
||||
if(!world.isRemote) {
|
||||
dropContents(world, x, y, z);
|
||||
world.setBlockToAir(x, y, z);
|
||||
world.playSoundEffect(x, y, z, "hbm:block.crateBreak", 0.5F, 1.0F);
|
||||
}
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
Random rand = new Random();
|
||||
|
||||
@Override
|
||||
public ArrayList<ItemStack> getDrops(World world, int x, int y, int z, int metadata, int fortune) {
|
||||
public void dropContents(World world, int x, int y, int z) {
|
||||
ArrayList<ItemStack> items = getContents(world, x, y, z);
|
||||
|
||||
for(ItemStack item : items) {
|
||||
this.dropBlockAsItem(world, x, y, z, item);
|
||||
}
|
||||
}
|
||||
|
||||
public ArrayList<ItemStack> getContents(World world, int x, int y, int z) {
|
||||
|
||||
ArrayList<ItemStack> ret = new ArrayList<ItemStack>();
|
||||
|
||||
ret.add(new ItemStack(ModItems.cap_nuka, 12 + rand.nextInt(21)));
|
||||
ret.add(new ItemStack(ModItems.syringe_metal_stimpak, 1 + rand.nextInt(3)));
|
||||
|
||||
if(rand.nextBoolean()) ret.add(new ItemStack(ModItems.ammo_standard, 16 + rand.nextInt(17), EnumAmmo.P9_SP.ordinal()));
|
||||
if(rand.nextBoolean()) ret.add(new ItemStack(ModItems.ammo_standard, 16 + rand.nextInt(17), EnumAmmo.P9_FMJ.ordinal()));
|
||||
if(rand.nextBoolean()) ret.add(new ItemStack(ModItems.ammo_standard, 16 + rand.nextInt(17), EnumAmmo.M357_SP.ordinal()));
|
||||
if(rand.nextBoolean()) ret.add(new ItemStack(ModItems.ammo_standard, 16 + rand.nextInt(17), EnumAmmo.M357_FMJ.ordinal()));
|
||||
if(rand.nextBoolean()) ret.add(new ItemStack(ModItems.ammo_standard, 16 + rand.nextInt(17), EnumAmmo.M44_SP.ordinal()));
|
||||
if(rand.nextBoolean()) ret.add(new ItemStack(ModItems.ammo_standard, 16 + rand.nextInt(17), EnumAmmo.M44_FMJ.ordinal()));
|
||||
if(rand.nextBoolean()) ret.add(new ItemStack(ModItems.ammo_standard, 16 + rand.nextInt(17), EnumAmmo.R556_SP.ordinal()));
|
||||
if(rand.nextBoolean()) ret.add(new ItemStack(ModItems.ammo_standard, 16 + rand.nextInt(17), EnumAmmo.R556_FMJ.ordinal()));
|
||||
if(rand.nextBoolean()) ret.add(new ItemStack(ModItems.ammo_standard, 16 + rand.nextInt(17), EnumAmmo.R762_SP.ordinal()));
|
||||
if(rand.nextBoolean()) ret.add(new ItemStack(ModItems.ammo_standard, 16 + rand.nextInt(17), EnumAmmo.R762_FMJ.ordinal()));
|
||||
if(rand.nextBoolean()) ret.add(new ItemStack(ModItems.ammo_standard, 16 + rand.nextInt(17), EnumAmmo.G12.ordinal()));
|
||||
if(rand.nextBoolean()) ret.add(new ItemStack(ModItems.ammo_standard, 16 + rand.nextInt(17), EnumAmmo.G12_SLUG.ordinal()));
|
||||
if(rand.nextBoolean()) ret.add(new ItemStack(ModItems.ammo_standard, 2 + rand.nextInt(3), EnumAmmo.G40_HE.ordinal()));
|
||||
if(rand.nextBoolean()) ret.add(new ItemStack(ModItems.ammo_standard, 2 + rand.nextInt(3), EnumAmmo.ROCKET_HE.ordinal()));
|
||||
|
||||
if(rand.nextBoolean()) ret.add(new ItemStack(ModItems.ammo_22lr, 16 + rand.nextInt(17)));
|
||||
if(rand.nextBoolean()) ret.add(new ItemStack(ModItems.ammo_9mm, 6 + rand.nextInt(13)));
|
||||
if(rand.nextBoolean()) ret.add(new ItemStack(ModItems.ammo_12gauge, 6 + rand.nextInt(4)));
|
||||
if(rand.nextBoolean()) ret.add(new ItemStack(ModItems.ammo_20gauge, 3 + rand.nextInt(4)));
|
||||
if(rand.nextBoolean()) ret.add(new ItemStack(ModItems.ammo_357, 10 + rand.nextInt(11)));
|
||||
if(rand.nextBoolean()) ret.add(new ItemStack(ModItems.ammo_357, 12 + rand.nextInt(15), Ammo357Magnum.IRON.ordinal()));
|
||||
if(rand.nextBoolean()) ret.add(new ItemStack(ModItems.ammo_50bmg, 2 + rand.nextInt(7)));
|
||||
if(rand.nextBoolean()) ret.add(new ItemStack(ModItems.ammo_rocket, 1));
|
||||
if(rand.nextBoolean()) ret.add(new ItemStack(ModItems.ammo_grenade, 1 + rand.nextInt(2)));
|
||||
|
||||
if(rand.nextInt(10) == 0) ret.add(new ItemStack(ModItems.ammo_12gauge, 3, Ammo12Gauge.INCENDIARY.ordinal()));
|
||||
if(rand.nextInt(10) == 0) ret.add(new ItemStack(ModItems.ammo_20gauge, 3, Ammo20Gauge.INCENDIARY.ordinal()));
|
||||
if(rand.nextInt(10) == 0) ret.add(new ItemStack(ModItems.ammo_20gauge, 3, Ammo20Gauge.CAUSTIC.ordinal()));
|
||||
if(rand.nextInt(10) == 0) ret.add(new ItemStack(ModItems.ammo_20gauge, 3, Ammo20Gauge.FLECHETTE.ordinal()));
|
||||
if(rand.nextInt(10) == 0) ret.add(new ItemStack(ModItems.ammo_9mm, 7, Ammo9mm.AP.ordinal()));
|
||||
if(rand.nextInt(10) == 0) ret.add(new ItemStack(ModItems.ammo_rocket, 1, AmmoRocket.INCENDIARY.ordinal()));
|
||||
if(rand.nextInt(10) == 0) ret.add(new ItemStack(ModItems.ammo_rocket, 1, AmmoRocket.SLEEK.ordinal()));
|
||||
if(rand.nextInt(10) == 0) ret.add(new ItemStack(ModItems.ammo_grenade, 1, AmmoGrenade.HE.ordinal()));
|
||||
if(rand.nextInt(10) == 0) ret.add(new ItemStack(ModItems.ammo_grenade, 1, AmmoGrenade.INCENDIARY.ordinal()));
|
||||
if(rand.nextInt(10) == 0) ret.add(new ItemStack(ModItems.ammo_grenade, 1, AmmoGrenade.SLEEK.ordinal()));
|
||||
if(rand.nextInt(10) == 0) ret.add(new ItemStack(ModItems.syringe_metal_super, 2));
|
||||
|
||||
return ret;
|
||||
|
||||
@ -1,51 +0,0 @@
|
||||
package com.hbm.blocks.generic;
|
||||
|
||||
import com.hbm.blocks.ModBlocks;
|
||||
import com.hbm.items.ModItems;
|
||||
|
||||
import api.hbm.block.IDrillInteraction;
|
||||
import api.hbm.block.IMiningDrill;
|
||||
import net.minecraft.block.Block;
|
||||
import net.minecraft.block.material.Material;
|
||||
import net.minecraft.item.Item;
|
||||
import net.minecraft.item.ItemStack;
|
||||
import net.minecraft.world.World;
|
||||
|
||||
public class BlockBedrockOre extends Block implements IDrillInteraction {
|
||||
|
||||
public BlockBedrockOre() {
|
||||
super(Material.rock);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean canBreak(World world, int x, int y, int z, int meta, IMiningDrill drill) {
|
||||
return drill.getDrillRating() > 70;
|
||||
}
|
||||
|
||||
@Override
|
||||
public ItemStack extractResource(World world, int x, int y, int z, int meta, IMiningDrill drill) {
|
||||
|
||||
if(drill.getDrillRating() > 70)
|
||||
return null;
|
||||
|
||||
Item drop = this.getDrop();
|
||||
|
||||
if(drop == null)
|
||||
return null;
|
||||
|
||||
return world.rand.nextInt(50) == 0 ? new ItemStack(drop) : null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public float getRelativeHardness(World world, int x, int y, int z, int meta, IMiningDrill drill) {
|
||||
return 30;
|
||||
}
|
||||
|
||||
private Item getDrop() {
|
||||
|
||||
if(this == ModBlocks.ore_bedrock_coltan)
|
||||
return ModItems.fragment_coltan;
|
||||
|
||||
return null;
|
||||
}
|
||||
}
|
||||
Some files were not shown because too many files have changed in this diff Show More
Loading…
x
Reference in New Issue
Block a user