Compare commits
4
Commits
536e567348
..
main
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
af0afcb98f | ||
|
|
28b1841c2a | ||
|
|
ecde802cdb | ||
|
|
870e5d13eb |
No files matched your search
@@ -35,3 +35,4 @@ addon.local.gradle.kts
|
|||||||
addon.late.local.gradle
|
addon.late.local.gradle
|
||||||
addon.late.local.gradle.kts
|
addon.late.local.gradle.kts
|
||||||
layout.json
|
layout.json
|
||||||
|
/libs/
|
||||||
@@ -1,3 +0,0 @@
|
|||||||
# Any Github changes require admin approval
|
|
||||||
/.github/** @GTNewHorizons/admin
|
|
||||||
|
|
||||||
@@ -1,21 +0,0 @@
|
|||||||
MIT License
|
|
||||||
|
|
||||||
Copyright (c) <year> <copyright holders>
|
|
||||||
|
|
||||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
||||||
of this software and associated documentation files (the "Software"), to deal
|
|
||||||
in the Software without restriction, including without limitation the rights
|
|
||||||
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
||||||
copies of the Software, and to permit persons to whom the Software is
|
|
||||||
furnished to do so, subject to the following conditions:
|
|
||||||
|
|
||||||
The above copyright notice and this permission notice shall be included in all
|
|
||||||
copies or substantial portions of the Software.
|
|
||||||
|
|
||||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
||||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
||||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
||||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
||||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
||||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
||||||
SOFTWARE.
|
|
||||||
@@ -0,0 +1,38 @@
|
|||||||
|
# CE-modern
|
||||||
|
|
||||||
|
mod「CE」を Minecraft 1.7.10 (Forge 10.13.4.1614) 向けに移植したものです。
|
||||||
|
|
||||||
|
## 追加要素
|
||||||
|
|
||||||
|
### EMC Builder
|
||||||
|
|
||||||
|
BuildCraft の Builder を拡張し、建築に必要な資材を EMC で支払えるようにしたブロックです。
|
||||||
|
|
||||||
|
- 内部インベントリや液体タンクにある資材が先に使われ、足りない分を EMC で補います(EMC 値 1:1)。
|
||||||
|
- EMC はワールドごと・プレイヤーごとに保存され、同じプレイヤーが所有する EMC Builder はすべて同じ残高を共有します。
|
||||||
|
- GUI の EMC スロットにアイテムを入れると、Transmutation Table と同様に EMC に変換されます。
|
||||||
|
- レシピ: Builder + Transmutation Table(不定形)
|
||||||
|
|
||||||
|
## 必要な Mod
|
||||||
|
|
||||||
|
- BuildCraft 7.1.x(Builders)
|
||||||
|
- ProjectE
|
||||||
|
|
||||||
|
## ビルド
|
||||||
|
|
||||||
|
開発用の依存 jar(`libs/` に配置、リポジトリには含まない):
|
||||||
|
|
||||||
|
- `buildcraft-7.1.27-dev.jar`(BuildCraft で `gradlew deobfJar`)
|
||||||
|
- `FMProjectE-*-dev.jar`(FMProjectE で `gradlew jar`)
|
||||||
|
|
||||||
|
```bash
|
||||||
|
./gradlew build
|
||||||
|
```
|
||||||
|
|
||||||
|
## 作者
|
||||||
|
|
||||||
|
agomizi1cm
|
||||||
|
|
||||||
|
## ライセンス
|
||||||
|
|
||||||
|
MIT
|
||||||
+5
-1
@@ -34,5 +34,9 @@
|
|||||||
* For more details, see https://docs.gradle.org/8.0.1/userguide/java_library_plugin.html#sec:java_library_configurations_graph
|
* For more details, see https://docs.gradle.org/8.0.1/userguide/java_library_plugin.html#sec:java_library_configurations_graph
|
||||||
*/
|
*/
|
||||||
dependencies {
|
dependencies {
|
||||||
//runtimeOnlyNonPublishable("com.github.GTNewHorizons:NotEnoughItems:2.7.69-GTNH:dev")
|
// Local deobfuscated (MCP-named) dev jars placed in libs/:
|
||||||
|
// - BuildCraft 7.1.27 (gradlew deobfJar -> buildcraft-7.1.27-dev.jar)
|
||||||
|
// - FMProjectE (gradlew jar -> FMProjectE-*-dev.jar)
|
||||||
|
devOnlyNonPublishable(files("libs/buildcraft-7.1.27-dev.jar"))
|
||||||
|
devOnlyNonPublishable(fileTree("libs") { include("FMProjectE-*-dev.jar") })
|
||||||
}
|
}
|
||||||
+4
-4
@@ -3,15 +3,15 @@
|
|||||||
gtnh.settings.blowdryerTag = 0.2.2
|
gtnh.settings.blowdryerTag = 0.2.2
|
||||||
|
|
||||||
# Human-readable mod name, available for mcmod.info population.
|
# Human-readable mod name, available for mcmod.info population.
|
||||||
modName = EMCBuilder
|
modName = CE-modern
|
||||||
|
|
||||||
# Case-sensitive identifier string, available for mcmod.info population and used for automatic mixin JSON generation.
|
# Case-sensitive identifier string, available for mcmod.info population and used for automatic mixin JSON generation.
|
||||||
# Conventionally lowercase.
|
# Conventionally lowercase.
|
||||||
modId = emcbuilder
|
modId = cemodern
|
||||||
|
|
||||||
# Root package of the mod, used to find various classes in other properties,
|
# Root package of the mod, used to find various classes in other properties,
|
||||||
# mcmod.info substitution, enabling assertions in run tasks, etc.
|
# mcmod.info substitution, enabling assertions in run tasks, etc.
|
||||||
modGroup = net.kanawo.emcbuilder
|
modGroup = net.kanawo.cemodern
|
||||||
|
|
||||||
# Whether to use modGroup as the maven publishing group.
|
# Whether to use modGroup as the maven publishing group.
|
||||||
# When false, com.github.GTNewHorizons is used.
|
# When false, com.github.GTNewHorizons is used.
|
||||||
@@ -74,7 +74,7 @@ enableGenericInjection = true
|
|||||||
# Generate a class with a String field for the mod version named as defined below.
|
# Generate a class with a String field for the mod version named as defined below.
|
||||||
# If generateGradleTokenClass is empty or not missing, no such class will be generated.
|
# If generateGradleTokenClass is empty or not missing, no such class will be generated.
|
||||||
# If gradleTokenVersion is empty or missing, the field will not be present in the class.
|
# If gradleTokenVersion is empty or missing, the field will not be present in the class.
|
||||||
generateGradleTokenClass = net.kanawo.emcbuilder.Tags
|
generateGradleTokenClass = net.kanawo.cemodern.Tags
|
||||||
|
|
||||||
# Name of the token containing the project's current version to generate/replace.
|
# Name of the token containing the project's current version to generate/replace.
|
||||||
gradleTokenVersion = VERSION
|
gradleTokenVersion = VERSION
|
||||||
|
|||||||
@@ -0,0 +1,37 @@
|
|||||||
|
package net.kanawo.cemodern;
|
||||||
|
|
||||||
|
import org.apache.logging.log4j.LogManager;
|
||||||
|
import org.apache.logging.log4j.Logger;
|
||||||
|
|
||||||
|
import cpw.mods.fml.common.Mod;
|
||||||
|
import cpw.mods.fml.common.SidedProxy;
|
||||||
|
import cpw.mods.fml.common.event.FMLInitializationEvent;
|
||||||
|
import cpw.mods.fml.common.event.FMLPreInitializationEvent;
|
||||||
|
|
||||||
|
@Mod(
|
||||||
|
modid = CEModern.MODID,
|
||||||
|
version = Tags.VERSION,
|
||||||
|
name = "CE-modern",
|
||||||
|
acceptedMinecraftVersions = "[1.7.10]",
|
||||||
|
dependencies = "required-after:BuildCraft|Builders;required-after:ProjectE")
|
||||||
|
public class CEModern {
|
||||||
|
|
||||||
|
public static final String MODID = "cemodern";
|
||||||
|
public static final Logger LOG = LogManager.getLogger(MODID);
|
||||||
|
|
||||||
|
@Mod.Instance(MODID)
|
||||||
|
public static CEModern instance;
|
||||||
|
|
||||||
|
@SidedProxy(clientSide = "net.kanawo.cemodern.ClientProxy", serverSide = "net.kanawo.cemodern.CommonProxy")
|
||||||
|
public static CommonProxy proxy;
|
||||||
|
|
||||||
|
@Mod.EventHandler
|
||||||
|
public void preInit(FMLPreInitializationEvent event) {
|
||||||
|
proxy.preInit(event);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Mod.EventHandler
|
||||||
|
public void init(FMLInitializationEvent event) {
|
||||||
|
proxy.init(event);
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,19 @@
|
|||||||
|
package net.kanawo.cemodern;
|
||||||
|
|
||||||
|
import net.kanawo.cemodern.tile.TileEMCBuilder;
|
||||||
|
|
||||||
|
import buildcraft.core.render.RenderBuilder;
|
||||||
|
import cpw.mods.fml.client.registry.ClientRegistry;
|
||||||
|
import cpw.mods.fml.common.event.FMLInitializationEvent;
|
||||||
|
|
||||||
|
public class ClientProxy extends CommonProxy {
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void init(FMLInitializationEvent event) {
|
||||||
|
super.init(event);
|
||||||
|
|
||||||
|
// The Builder's own renderer (RenderBuilderTile) also draws BuildCraft's lit top while building. Its base
|
||||||
|
// renderer draws only the area box, path lasers and flying items.
|
||||||
|
ClientRegistry.bindTileEntitySpecialRenderer(TileEMCBuilder.class, new RenderBuilder());
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,37 @@
|
|||||||
|
package net.kanawo.cemodern;
|
||||||
|
|
||||||
|
import net.kanawo.cemodern.block.BlockEMCBuilder;
|
||||||
|
import net.kanawo.cemodern.block.SchematicEMCBuilder;
|
||||||
|
import net.kanawo.cemodern.gui.GuiHandler;
|
||||||
|
import net.kanawo.cemodern.tile.TileEMCBuilder;
|
||||||
|
import net.minecraft.item.ItemStack;
|
||||||
|
|
||||||
|
import buildcraft.BuildCraftBuilders;
|
||||||
|
import buildcraft.api.blueprints.BuilderAPI;
|
||||||
|
import cpw.mods.fml.common.event.FMLInitializationEvent;
|
||||||
|
import cpw.mods.fml.common.event.FMLPreInitializationEvent;
|
||||||
|
import cpw.mods.fml.common.network.NetworkRegistry;
|
||||||
|
import cpw.mods.fml.common.registry.GameRegistry;
|
||||||
|
import moze_intel.projecte.gameObjs.ObjHandler;
|
||||||
|
|
||||||
|
public class CommonProxy {
|
||||||
|
|
||||||
|
public static BlockEMCBuilder emcBuilderBlock;
|
||||||
|
|
||||||
|
public void preInit(FMLPreInitializationEvent event) {
|
||||||
|
emcBuilderBlock = new BlockEMCBuilder();
|
||||||
|
GameRegistry.registerBlock(emcBuilderBlock, "emcBuilder");
|
||||||
|
GameRegistry.registerTileEntity(TileEMCBuilder.class, CEModern.MODID + ":EMCBuilder");
|
||||||
|
}
|
||||||
|
|
||||||
|
public void init(FMLInitializationEvent event) {
|
||||||
|
NetworkRegistry.INSTANCE.registerGuiHandler(CEModern.instance, new GuiHandler());
|
||||||
|
|
||||||
|
BuilderAPI.schematicRegistry.registerSchematicBlock(emcBuilderBlock, SchematicEMCBuilder.class);
|
||||||
|
|
||||||
|
GameRegistry.addShapelessRecipe(
|
||||||
|
new ItemStack(emcBuilderBlock),
|
||||||
|
BuildCraftBuilders.builderBlock,
|
||||||
|
ObjHandler.transmuteStone);
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,96 @@
|
|||||||
|
package net.kanawo.cemodern.block;
|
||||||
|
|
||||||
|
import net.kanawo.cemodern.CEModern;
|
||||||
|
import net.kanawo.cemodern.gui.GuiHandler;
|
||||||
|
import net.kanawo.cemodern.tile.TileEMCBuilder;
|
||||||
|
import net.minecraft.client.renderer.texture.IIconRegister;
|
||||||
|
import net.minecraft.entity.player.EntityPlayer;
|
||||||
|
import net.minecraft.item.Item;
|
||||||
|
import net.minecraft.tileentity.TileEntity;
|
||||||
|
import net.minecraft.world.World;
|
||||||
|
import net.minecraftforge.common.util.ForgeDirection;
|
||||||
|
|
||||||
|
import buildcraft.api.events.BlockInteractionEvent;
|
||||||
|
import buildcraft.builders.BlockBuilder;
|
||||||
|
import buildcraft.builders.ItemConstructionMarker;
|
||||||
|
import buildcraft.core.lib.fluids.TankUtils;
|
||||||
|
import buildcraft.core.lib.utils.ResourceUtils;
|
||||||
|
import cpw.mods.fml.common.FMLCommonHandler;
|
||||||
|
import cpw.mods.fml.relauncher.Side;
|
||||||
|
import cpw.mods.fml.relauncher.SideOnly;
|
||||||
|
|
||||||
|
public class BlockEMCBuilder extends BlockBuilder {
|
||||||
|
|
||||||
|
private static final String TEXTURE_PREFIX = CEModern.MODID + ":emcbuilderBlock";
|
||||||
|
|
||||||
|
public BlockEMCBuilder() {
|
||||||
|
super();
|
||||||
|
setBlockName("emcBuilder");
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public TileEntity createNewTileEntity(World world, int metadata) {
|
||||||
|
return new TileEMCBuilder();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Same as BlockBuilder, but opens the EMC Builder GUI. BlockBuilder's version cannot be called because it opens
|
||||||
|
* BuildCraft's own Builder GUI.
|
||||||
|
*/
|
||||||
|
@Override
|
||||||
|
public boolean onBlockActivated(World world, int x, int y, int z, EntityPlayer player, int side, float hitX,
|
||||||
|
float hitY, float hitZ) {
|
||||||
|
BlockInteractionEvent event = new BlockInteractionEvent(player, this);
|
||||||
|
FMLCommonHandler.instance()
|
||||||
|
.bus()
|
||||||
|
.post(event);
|
||||||
|
if (event.isCanceled()) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (player.isSneaking()) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
TileEntity tile = world.getTileEntity(x, y, z);
|
||||||
|
TileEMCBuilder builder = tile instanceof TileEMCBuilder ? (TileEMCBuilder) tile : null;
|
||||||
|
|
||||||
|
Item equipped = player.getCurrentEquippedItem() != null ? player.getCurrentEquippedItem()
|
||||||
|
.getItem() : null;
|
||||||
|
if (equipped instanceof ItemConstructionMarker) {
|
||||||
|
if (ItemConstructionMarker.linkStarted(player.getCurrentEquippedItem())) {
|
||||||
|
ItemConstructionMarker.link(player.getCurrentEquippedItem(), world, x, y, z);
|
||||||
|
}
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
boolean filledTank = builder != null
|
||||||
|
&& TankUtils.handleRightClick(builder, ForgeDirection.UNKNOWN, player, true, false);
|
||||||
|
if (!filledTank && !world.isRemote) {
|
||||||
|
player.openGui(CEModern.instance, GuiHandler.EMC_BUILDER, world, x, y, z);
|
||||||
|
}
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
/** Textures are looked up as textures/blocks/emcbuilderBlock/{top,bottom,front,side,...}.png. */
|
||||||
|
@Override
|
||||||
|
@SideOnly(Side.CLIENT)
|
||||||
|
public String[] getIconBlockNames() {
|
||||||
|
return new String[] { TEXTURE_PREFIX };
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
@SideOnly(Side.CLIENT)
|
||||||
|
public void registerBlockIcons(IIconRegister register) {
|
||||||
|
super.registerBlockIcons(register);
|
||||||
|
|
||||||
|
// Without bottom.png BlockBuildCraft would fall back to a missing "default" texture. Use the left face
|
||||||
|
// (index 4), which resolves to side.png, instead.
|
||||||
|
String bottom = TEXTURE_PREFIX + "/bottom";
|
||||||
|
if (!ResourceUtils.resourceExists(ResourceUtils.iconToResourcePath(register, bottom))) {
|
||||||
|
icons[0][0] = icons[0][4];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,22 @@
|
|||||||
|
package net.kanawo.cemodern.block;
|
||||||
|
|
||||||
|
import net.kanawo.cemodern.tile.TileEMCBuilder;
|
||||||
|
|
||||||
|
import buildcraft.builders.schematics.SchematicBuilderLike;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Blueprint schematic that, like the Builder's, drops the build state, and also drops the owner, so a copy built by
|
||||||
|
* someone else does not draw on the original owner's EMC.
|
||||||
|
*/
|
||||||
|
public class SchematicEMCBuilder extends SchematicBuilderLike {
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onNBTLoaded() {
|
||||||
|
super.onNBTLoaded();
|
||||||
|
|
||||||
|
if (tileNBT != null) {
|
||||||
|
tileNBT.removeTag(TileEMCBuilder.OWNER_MOST);
|
||||||
|
tileNBT.removeTag(TileEMCBuilder.OWNER_LEAST);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,107 @@
|
|||||||
|
package net.kanawo.cemodern.gui;
|
||||||
|
|
||||||
|
import net.kanawo.cemodern.tile.TileEMCBuilder;
|
||||||
|
import net.minecraft.entity.player.EntityPlayer;
|
||||||
|
import net.minecraft.entity.player.InventoryPlayer;
|
||||||
|
import net.minecraft.inventory.IInventory;
|
||||||
|
import net.minecraft.inventory.Slot;
|
||||||
|
import net.minecraft.item.ItemStack;
|
||||||
|
|
||||||
|
import buildcraft.builders.gui.ContainerBuilder;
|
||||||
|
import buildcraft.core.lib.gui.widgets.ScrollbarWidget;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The Builder container plus an EMC consume slot. Extending {@link ContainerBuilder} keeps BuildCraft's requirement
|
||||||
|
* tooltips and GUI watcher handling.
|
||||||
|
*/
|
||||||
|
public class ContainerEMCBuilder extends ContainerBuilder {
|
||||||
|
|
||||||
|
/** Matches the slot frame at (132, 26) in emcbuilder.png. */
|
||||||
|
public static final int CONSUME_SLOT_X = 133;
|
||||||
|
public static final int CONSUME_SLOT_Y = 27;
|
||||||
|
|
||||||
|
private static final int PLAYER_SLOTS = 9 * 4;
|
||||||
|
|
||||||
|
/** Index of the consume slot; the builder and player slots are all before it. */
|
||||||
|
private final int consumeSlot;
|
||||||
|
|
||||||
|
public ContainerEMCBuilder(IInventory playerInventory, TileEMCBuilder builder) {
|
||||||
|
super(playerInventory, builder);
|
||||||
|
|
||||||
|
// A builder made from a blueprint has no owner yet; whoever opens it first takes it.
|
||||||
|
if (!builder.getWorldObj().isRemote && playerInventory instanceof InventoryPlayer) {
|
||||||
|
builder.claimOwner(((InventoryPlayer) playerInventory).player);
|
||||||
|
}
|
||||||
|
|
||||||
|
consumeSlot = inventorySlots.size();
|
||||||
|
addSlotToContainer(new SlotEMCConsume(builder, CONSUME_SLOT_X, CONSUME_SLOT_Y));
|
||||||
|
}
|
||||||
|
|
||||||
|
public ScrollbarWidget getScrollbar() {
|
||||||
|
return scrollbarWidget;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Same behaviour as BuildCraftContainer, which assumes the player inventory is the last 36 slots; the consume slot
|
||||||
|
* comes after it here. Shift-clicking never moves items into the consume slot.
|
||||||
|
*/
|
||||||
|
@Override
|
||||||
|
public ItemStack transferStackInSlot(EntityPlayer player, int slotIndex) {
|
||||||
|
if (slotIndex == consumeSlot) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
Slot slot = (Slot) inventorySlots.get(slotIndex);
|
||||||
|
|
||||||
|
if (slot == null || !slot.getHasStack()) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
int playerStart = consumeSlot - PLAYER_SLOTS;
|
||||||
|
int hotbarStart = consumeSlot - 9;
|
||||||
|
ItemStack stack = slot.getStack();
|
||||||
|
ItemStack original = stack.copy();
|
||||||
|
|
||||||
|
if (slotIndex >= playerStart) {
|
||||||
|
if (!shiftIntoBuilder(stack, playerStart)) {
|
||||||
|
boolean fromHotbar = slotIndex >= hotbarStart;
|
||||||
|
|
||||||
|
if (!shiftItemStack(
|
||||||
|
stack,
|
||||||
|
fromHotbar ? playerStart : hotbarStart,
|
||||||
|
fromHotbar ? hotbarStart : consumeSlot)) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} else if (!shiftItemStack(stack, playerStart, consumeSlot)) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
slot.onSlotChange(stack, original);
|
||||||
|
|
||||||
|
if (stack.stackSize <= 0) {
|
||||||
|
slot.putStack(null);
|
||||||
|
} else {
|
||||||
|
slot.onSlotChanged();
|
||||||
|
}
|
||||||
|
|
||||||
|
if (stack.stackSize == original.stackSize) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
slot.onPickupFromSlot(player, stack);
|
||||||
|
return original;
|
||||||
|
}
|
||||||
|
|
||||||
|
private boolean shiftIntoBuilder(ItemStack stack, int builderSlots) {
|
||||||
|
for (int i = 0; i < builderSlots; i++) {
|
||||||
|
Slot slot = (Slot) inventorySlots.get(i);
|
||||||
|
|
||||||
|
if (slot.isItemValid(stack) && shiftItemStack(stack, i, i + 1)) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,252 @@
|
|||||||
|
package net.kanawo.cemodern.gui;
|
||||||
|
|
||||||
|
import java.util.ArrayList;
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
import net.kanawo.cemodern.CEModern;
|
||||||
|
import net.kanawo.cemodern.tile.TileEMCBuilder;
|
||||||
|
import net.minecraft.client.Minecraft;
|
||||||
|
import net.minecraft.client.gui.GuiButton;
|
||||||
|
import net.minecraft.inventory.IInventory;
|
||||||
|
import net.minecraft.util.EnumChatFormatting;
|
||||||
|
import net.minecraft.util.ResourceLocation;
|
||||||
|
import net.minecraft.util.StatCollector;
|
||||||
|
|
||||||
|
import org.lwjgl.opengl.GL11;
|
||||||
|
|
||||||
|
import buildcraft.BuildCraftCore;
|
||||||
|
import buildcraft.builders.gui.SlotBuilderRequirement;
|
||||||
|
import buildcraft.core.blueprints.RequirementItemStack;
|
||||||
|
import buildcraft.core.lib.fluids.Tank;
|
||||||
|
import buildcraft.core.lib.gui.AdvancedSlot;
|
||||||
|
import buildcraft.core.lib.gui.GuiAdvancedInterface;
|
||||||
|
import buildcraft.core.lib.network.command.CommandWriter;
|
||||||
|
import buildcraft.core.lib.network.command.PacketCommand;
|
||||||
|
import buildcraft.core.lib.utils.StringUtils;
|
||||||
|
import io.netty.buffer.ByteBuf;
|
||||||
|
import moze_intel.projecte.utils.Constants;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* BuildCraft's GuiBuilder with the EMC consume slot and the stored EMC added. GuiBuilder cannot be extended because it
|
||||||
|
* creates its own ContainerBuilder.
|
||||||
|
*/
|
||||||
|
public class GuiEMCBuilder extends GuiAdvancedInterface {
|
||||||
|
|
||||||
|
/** BuildCraft's builder.png with the EMC consume slot added. */
|
||||||
|
private static final ResourceLocation REGULAR_TEXTURE = new ResourceLocation(
|
||||||
|
CEModern.MODID,
|
||||||
|
"textures/gui/emcbuilder.png");
|
||||||
|
private static final ResourceLocation BLUEPRINT_TEXTURE = new ResourceLocation(
|
||||||
|
"buildcraftbuilders:textures/gui/builder_blueprint.png");
|
||||||
|
|
||||||
|
private final TileEMCBuilder builder;
|
||||||
|
private GuiButton selectedButton;
|
||||||
|
|
||||||
|
public GuiEMCBuilder(IInventory playerInventory, TileEMCBuilder builder) {
|
||||||
|
super(new ContainerEMCBuilder(playerInventory, builder), builder, BLUEPRINT_TEXTURE);
|
||||||
|
this.builder = builder;
|
||||||
|
xSize = 256;
|
||||||
|
ySize = 225;
|
||||||
|
|
||||||
|
resetNullSlots(6 * 4);
|
||||||
|
|
||||||
|
for (int i = 0; i < 6; ++i) {
|
||||||
|
for (int j = 0; j < 4; ++j) {
|
||||||
|
slots.set(i * 4 + j, new SlotBuilderRequirement(this, 179 + j * 18, 18 + i * 18));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private ContainerEMCBuilder getContainerBuilder() {
|
||||||
|
return (ContainerEMCBuilder) getContainer();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected void drawGuiContainerForegroundLayer(int par1, int par2) {
|
||||||
|
super.drawGuiContainerForegroundLayer(par1, par2);
|
||||||
|
|
||||||
|
drawCenteredString(StringUtils.localize("tile.emcBuilder.name"), 178 / 2, 16, 0x404040);
|
||||||
|
|
||||||
|
drawCenteredString(
|
||||||
|
StatCollector.translateToLocalFormatted(
|
||||||
|
"gui.cemodern.stored",
|
||||||
|
Constants.EMC_FORMATTER.format(builder.getStoredEmc())),
|
||||||
|
178 / 2,
|
||||||
|
51,
|
||||||
|
0x404040);
|
||||||
|
|
||||||
|
if (builder.getStackInSlot(0) != null) {
|
||||||
|
fontRendererObj.drawString(StringUtils.localize("gui.building.resources"), 8, 60, 0x404040);
|
||||||
|
fontRendererObj.drawString(StringUtils.localize("gui.inventory"), 8, ySize - 97, 0x404040);
|
||||||
|
fontRendererObj.drawString(StringUtils.localize("gui.needed"), 178, 7, 0x404040);
|
||||||
|
fontRendererObj.drawString(StringUtils.localize("gui.building.fluids"), 178, 133, 0x404040);
|
||||||
|
}
|
||||||
|
|
||||||
|
drawTooltips(par1, par2);
|
||||||
|
}
|
||||||
|
|
||||||
|
private void drawTooltips(int par1, int par2) {
|
||||||
|
int top = guiTop + 145;
|
||||||
|
for (int i = 0; i < builder.fluidTanks.length; i++) {
|
||||||
|
int left = guiLeft + 179 + 18 * i;
|
||||||
|
if (par1 >= left && par2 >= top && par1 < (left + 16) && par2 < (left + 47)) {
|
||||||
|
List<String> fluidTip = new ArrayList<>();
|
||||||
|
Tank tank = builder.fluidTanks[i];
|
||||||
|
if (tank.getFluid() != null && tank.getFluid().amount > 0) {
|
||||||
|
fluidTip.add(
|
||||||
|
tank.getFluid()
|
||||||
|
.getLocalizedName());
|
||||||
|
if (!BuildCraftCore.hideFluidNumbers) {
|
||||||
|
fluidTip.add(
|
||||||
|
EnumChatFormatting.GRAY + "" + EnumChatFormatting.ITALIC + tank.getFluid().amount + " mB");
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
fluidTip.add(StatCollector.translateToLocal("gui.fluidtank.empty"));
|
||||||
|
}
|
||||||
|
drawHoveringText(fluidTip, par1 - guiLeft, par2 - guiTop, fontRendererObj);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
drawTooltipForSlotAt(par1, par2);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
@SuppressWarnings("unchecked")
|
||||||
|
protected void drawGuiContainerBackgroundLayer(float f, int x, int y) {
|
||||||
|
// Like GuiBuilder, super is not called because the GUI is resized dynamically.
|
||||||
|
GL11.glColor4f(1.0F, 1.0F, 1.0F, 1.0F);
|
||||||
|
boolean isBlueprint = builder.getStackInSlot(0) != null;
|
||||||
|
|
||||||
|
mc.renderEngine.bindTexture(REGULAR_TEXTURE);
|
||||||
|
drawTexturedModalRect(guiLeft, guiTop, 0, 0, 176, ySize);
|
||||||
|
mc.renderEngine.bindTexture(BLUEPRINT_TEXTURE);
|
||||||
|
if (isBlueprint) {
|
||||||
|
drawTexturedModalRect(guiLeft + 169, guiTop, 169, 0, 256 - 169, ySize);
|
||||||
|
}
|
||||||
|
|
||||||
|
List<RequirementItemStack> needs = builder.getNeededItems();
|
||||||
|
|
||||||
|
if (needs != null) {
|
||||||
|
if (needs.size() > slots.size()) {
|
||||||
|
getContainerBuilder().getScrollbar().hidden = false;
|
||||||
|
getContainerBuilder().getScrollbar()
|
||||||
|
.setLength((needs.size() - slots.size() + 3) / 4);
|
||||||
|
} else {
|
||||||
|
getContainerBuilder().getScrollbar().hidden = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
int offset = getContainerBuilder().getScrollbar()
|
||||||
|
.getPosition() * 4;
|
||||||
|
for (int s = 0; s < slots.size(); s++) {
|
||||||
|
int ts = offset + s;
|
||||||
|
if (ts >= needs.size()) {
|
||||||
|
((SlotBuilderRequirement) slots.get(s)).stack = null;
|
||||||
|
} else {
|
||||||
|
((SlotBuilderRequirement) slots.get(s)).stack = needs.get(ts);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
for (GuiButton b : (List<GuiButton>) buttonList) {
|
||||||
|
b.visible = true;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
getContainerBuilder().getScrollbar().hidden = true;
|
||||||
|
for (AdvancedSlot slot : slots) {
|
||||||
|
((SlotBuilderRequirement) slot).stack = null;
|
||||||
|
}
|
||||||
|
for (GuiButton b : (List<GuiButton>) buttonList) {
|
||||||
|
b.visible = false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
drawWidgets(x, y);
|
||||||
|
|
||||||
|
if (isBlueprint) {
|
||||||
|
drawBackgroundSlots(x, y);
|
||||||
|
|
||||||
|
for (int i = 0; i < builder.fluidTanks.length; i++) {
|
||||||
|
Tank tank = builder.fluidTanks[i];
|
||||||
|
if (tank.getFluid() != null && tank.getFluid().amount > 0) {
|
||||||
|
drawFluid(tank.getFluid(), guiLeft + 179 + 18 * i, guiTop + 145, 16, 47, tank.getCapacity());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
mc.renderEngine.bindTexture(BLUEPRINT_TEXTURE);
|
||||||
|
|
||||||
|
for (int i = 0; i < builder.fluidTanks.length; i++) {
|
||||||
|
Tank tank = builder.fluidTanks[i];
|
||||||
|
if (tank.getFluid() != null && tank.getFluid().amount > 0) {
|
||||||
|
drawTexturedModalRect(guiLeft + 179 + 18 * i, guiTop + 145, 0, 54, 16, 47);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
@SuppressWarnings("unchecked")
|
||||||
|
public void initGui() {
|
||||||
|
super.initGui();
|
||||||
|
for (int i = 0; i < 4; i++) {
|
||||||
|
buttonList.add(new EraseTankButton(i, guiLeft + 178 + 18 * i, guiTop + 197, 18, 18));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected void mouseMovedOrUp(int mouseX, int mouseY, int eventType) {
|
||||||
|
super.mouseMovedOrUp(mouseX, mouseY, eventType);
|
||||||
|
if (this.selectedButton != null && eventType == 0) {
|
||||||
|
this.selectedButton.mouseReleased(mouseX, mouseY);
|
||||||
|
this.selectedButton = null;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/** Empties one of the builder's fluid tanks; same as GuiBuilder's erase button. */
|
||||||
|
private class EraseTankButton extends GuiButton {
|
||||||
|
|
||||||
|
private boolean clicked;
|
||||||
|
|
||||||
|
public EraseTankButton(int id, int x, int y, int width, int height) {
|
||||||
|
super(id, x, y, width, height, null);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean mousePressed(Minecraft mc, int x, int y) {
|
||||||
|
if (super.mousePressed(mc, x, y)) {
|
||||||
|
selectedButton = this;
|
||||||
|
clicked = true;
|
||||||
|
BuildCraftCore.instance.sendToServer(new PacketCommand(builder, "eraseFluidTank", new CommandWriter() {
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void write(ByteBuf data) {
|
||||||
|
data.writeInt(id);
|
||||||
|
}
|
||||||
|
}));
|
||||||
|
return true;
|
||||||
|
} else {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void mouseReleased(int x, int y) {
|
||||||
|
super.mouseReleased(x, y);
|
||||||
|
clicked = false;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void drawButton(Minecraft mc, int x, int y) {
|
||||||
|
if (!visible) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
// hovered
|
||||||
|
this.field_146123_n = x >= this.xPosition && y >= this.yPosition
|
||||||
|
&& x < this.xPosition + this.width
|
||||||
|
&& y < this.yPosition + this.height;
|
||||||
|
|
||||||
|
mc.renderEngine.bindTexture(BLUEPRINT_TEXTURE);
|
||||||
|
drawTexturedModalRect(xPosition, yPosition, 0, (clicked ? 1 : this.field_146123_n ? 2 : 0) * 18, 18, 18);
|
||||||
|
mouseDragged(mc, x, y);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,34 @@
|
|||||||
|
package net.kanawo.cemodern.gui;
|
||||||
|
|
||||||
|
import net.kanawo.cemodern.tile.TileEMCBuilder;
|
||||||
|
import net.minecraft.entity.player.EntityPlayer;
|
||||||
|
import net.minecraft.tileentity.TileEntity;
|
||||||
|
import net.minecraft.world.World;
|
||||||
|
|
||||||
|
import cpw.mods.fml.common.network.IGuiHandler;
|
||||||
|
|
||||||
|
public class GuiHandler implements IGuiHandler {
|
||||||
|
|
||||||
|
public static final int EMC_BUILDER = 0;
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Object getServerGuiElement(int id, EntityPlayer player, World world, int x, int y, int z) {
|
||||||
|
TileEMCBuilder builder = getBuilder(id, world, x, y, z);
|
||||||
|
return builder == null ? null : new ContainerEMCBuilder(player.inventory, builder);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Object getClientGuiElement(int id, EntityPlayer player, World world, int x, int y, int z) {
|
||||||
|
TileEMCBuilder builder = getBuilder(id, world, x, y, z);
|
||||||
|
return builder == null ? null : new GuiEMCBuilder(player.inventory, builder);
|
||||||
|
}
|
||||||
|
|
||||||
|
private static TileEMCBuilder getBuilder(int id, World world, int x, int y, int z) {
|
||||||
|
if (id != EMC_BUILDER || !world.blockExists(x, y, z)) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
TileEntity tile = world.getTileEntity(x, y, z);
|
||||||
|
return tile instanceof TileEMCBuilder ? (TileEMCBuilder) tile : null;
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,41 @@
|
|||||||
|
package net.kanawo.cemodern.gui;
|
||||||
|
|
||||||
|
import net.kanawo.cemodern.tile.TileEMCBuilder;
|
||||||
|
import net.minecraft.inventory.InventoryBasic;
|
||||||
|
import net.minecraft.inventory.Slot;
|
||||||
|
import net.minecraft.item.ItemStack;
|
||||||
|
|
||||||
|
import moze_intel.projecte.utils.EMCHelper;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Converts any item with an EMC value into EMC stored in the builder, like the Transmutation Table's consume slot.
|
||||||
|
* The slot never holds anything itself.
|
||||||
|
*/
|
||||||
|
public class SlotEMCConsume extends Slot {
|
||||||
|
|
||||||
|
private final TileEMCBuilder builder;
|
||||||
|
|
||||||
|
public SlotEMCConsume(TileEMCBuilder builder, int x, int y) {
|
||||||
|
super(new InventoryBasic("EMC", false, 1), 0, x, y);
|
||||||
|
this.builder = builder;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean isItemValid(ItemStack stack) {
|
||||||
|
return stack != null && EMCHelper.doesItemHaveEmc(stack);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void putStack(ItemStack stack) {
|
||||||
|
if (stack == null) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// The client discards the stack too, so it does not show an item the server never stored.
|
||||||
|
if (!builder.getWorldObj().isRemote) {
|
||||||
|
builder.consumeForEmc(stack);
|
||||||
|
}
|
||||||
|
|
||||||
|
onSlotChanged();
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,93 @@
|
|||||||
|
package net.kanawo.cemodern.tile;
|
||||||
|
|
||||||
|
import java.util.HashMap;
|
||||||
|
import java.util.Map;
|
||||||
|
import java.util.UUID;
|
||||||
|
|
||||||
|
import net.minecraft.nbt.NBTTagCompound;
|
||||||
|
import net.minecraft.nbt.NBTTagList;
|
||||||
|
import net.minecraft.world.World;
|
||||||
|
import net.minecraft.world.WorldSavedData;
|
||||||
|
import net.minecraft.world.storage.MapStorage;
|
||||||
|
import net.minecraftforge.common.util.Constants;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* EMC stored for EMC Builders, one balance per player, saved with the world (data/cemodern_emc.dat). All
|
||||||
|
* dimensions of a world share the same storage, so every EMC Builder a player owns in the world draws from the same
|
||||||
|
* balance. Server side only.
|
||||||
|
*/
|
||||||
|
public class EmcPool extends WorldSavedData {
|
||||||
|
|
||||||
|
private static final String NAME = "cemodern_emc";
|
||||||
|
private static final double MAX_EMC = moze_intel.projecte.utils.Constants.TILE_MAX_EMC;
|
||||||
|
|
||||||
|
private final Map<UUID, Double> balances = new HashMap<>();
|
||||||
|
|
||||||
|
public EmcPool(String name) {
|
||||||
|
super(name);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static EmcPool get(World world) {
|
||||||
|
MapStorage storage = world.mapStorage;
|
||||||
|
EmcPool pool = (EmcPool) storage.loadData(EmcPool.class, NAME);
|
||||||
|
|
||||||
|
if (pool == null) {
|
||||||
|
pool = new EmcPool(NAME);
|
||||||
|
storage.setData(NAME, pool);
|
||||||
|
}
|
||||||
|
|
||||||
|
return pool;
|
||||||
|
}
|
||||||
|
|
||||||
|
public double get(UUID player) {
|
||||||
|
Double emc = balances.get(player);
|
||||||
|
return emc == null ? 0 : emc;
|
||||||
|
}
|
||||||
|
|
||||||
|
/** Adds (or, with a negative amount, removes) EMC, keeping the balance between 0 and the maximum. */
|
||||||
|
public void add(UUID player, double amount) {
|
||||||
|
double emc = Math.min(MAX_EMC, Math.max(0, get(player) + amount));
|
||||||
|
|
||||||
|
if (emc == 0) {
|
||||||
|
balances.remove(player);
|
||||||
|
} else {
|
||||||
|
balances.put(player, emc);
|
||||||
|
}
|
||||||
|
|
||||||
|
markDirty();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void readFromNBT(NBTTagCompound nbt) {
|
||||||
|
balances.clear();
|
||||||
|
NBTTagList list = nbt.getTagList("Players", Constants.NBT.TAG_COMPOUND);
|
||||||
|
|
||||||
|
for (int i = 0; i < list.tagCount(); i++) {
|
||||||
|
NBTTagCompound entry = list.getCompoundTagAt(i);
|
||||||
|
balances.put(
|
||||||
|
new UUID(entry.getLong("UUIDMost"), entry.getLong("UUIDLeast")),
|
||||||
|
Math.min(MAX_EMC, Math.max(0, entry.getDouble("EMC"))));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void writeToNBT(NBTTagCompound nbt) {
|
||||||
|
NBTTagList list = new NBTTagList();
|
||||||
|
|
||||||
|
for (Map.Entry<UUID, Double> balance : balances.entrySet()) {
|
||||||
|
NBTTagCompound entry = new NBTTagCompound();
|
||||||
|
entry.setLong(
|
||||||
|
"UUIDMost",
|
||||||
|
balance.getKey()
|
||||||
|
.getMostSignificantBits());
|
||||||
|
entry.setLong(
|
||||||
|
"UUIDLeast",
|
||||||
|
balance.getKey()
|
||||||
|
.getLeastSignificantBits());
|
||||||
|
entry.setDouble("EMC", balance.getValue());
|
||||||
|
list.appendTag(entry);
|
||||||
|
}
|
||||||
|
|
||||||
|
nbt.setTag("Players", list);
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,294 @@
|
|||||||
|
package net.kanawo.cemodern.tile;
|
||||||
|
|
||||||
|
import java.util.ArrayList;
|
||||||
|
import java.util.List;
|
||||||
|
import java.util.UUID;
|
||||||
|
|
||||||
|
import net.minecraft.entity.EntityLivingBase;
|
||||||
|
import net.minecraft.entity.player.EntityPlayer;
|
||||||
|
import net.minecraft.item.ItemStack;
|
||||||
|
import net.minecraft.nbt.NBTTagCompound;
|
||||||
|
|
||||||
|
import buildcraft.builders.TileBuilder;
|
||||||
|
import buildcraft.core.blueprints.BptBuilderBase;
|
||||||
|
import buildcraft.core.blueprints.BptBuilderBlueprint;
|
||||||
|
import buildcraft.core.blueprints.RequirementItemStack;
|
||||||
|
import io.netty.buffer.ByteBuf;
|
||||||
|
import moze_intel.projecte.utils.EMCHelper;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* A Builder that pays for building materials with EMC.
|
||||||
|
* <p>
|
||||||
|
* The EMC is not stored in the tile but in its owner's balance in {@link EmcPool}, so all EMC Builders a player owns
|
||||||
|
* in a world share it. The owner is the player who placed the builder, or for one built from a blueprint, the first
|
||||||
|
* player who opens it.
|
||||||
|
* <p>
|
||||||
|
* BuildCraft only builds blocks whose materials are present in the builder's inventory, and consumes them by
|
||||||
|
* shrinking the stacks it finds there. While {@link #build()} runs, this tile therefore appends virtual slots after
|
||||||
|
* the real inventory, one per needed item that has an EMC value, sized to what the stored EMC can afford. After the
|
||||||
|
* build step the amount taken from each virtual slot is charged at 1 EMC per EMC value. Real items in the material
|
||||||
|
* slots come first in the inventory, so they are used before EMC.
|
||||||
|
* <p>
|
||||||
|
* Outside {@link #build()} the virtual slots are hidden, so GUIs, hoppers, pipes and robots only ever see the real
|
||||||
|
* inventory.
|
||||||
|
*/
|
||||||
|
public class TileEMCBuilder extends TileBuilder {
|
||||||
|
|
||||||
|
/** NBT keys of the owner's UUID; SchematicEMCBuilder removes them from blueprints. */
|
||||||
|
public static final String OWNER_MOST = "OwnerUUIDMost";
|
||||||
|
public static final String OWNER_LEAST = "OwnerUUIDLeast";
|
||||||
|
|
||||||
|
private static final int EMC_SYNC_INTERVAL = 10;
|
||||||
|
|
||||||
|
private UUID owner;
|
||||||
|
|
||||||
|
/** Owner's balance as last received from the server. Client side only. */
|
||||||
|
private double clientEmc;
|
||||||
|
/** Owner's balance as last sent to clients. Server side only. */
|
||||||
|
private double sentEmc = -1;
|
||||||
|
private int ticksSinceEmcSync;
|
||||||
|
|
||||||
|
private final List<EmcSlot> emcSlots = new ArrayList<>();
|
||||||
|
private boolean emcSlotsExposed;
|
||||||
|
|
||||||
|
/** A virtual material slot backed by stored EMC. */
|
||||||
|
private static final class EmcSlot {
|
||||||
|
|
||||||
|
final long emcPerItem;
|
||||||
|
final int initialSize;
|
||||||
|
ItemStack stack;
|
||||||
|
|
||||||
|
EmcSlot(ItemStack stack, long emcPerItem) {
|
||||||
|
this.stack = stack;
|
||||||
|
this.emcPerItem = emcPerItem;
|
||||||
|
this.initialSize = stack.stackSize;
|
||||||
|
}
|
||||||
|
|
||||||
|
int consumed() {
|
||||||
|
return stack == null ? initialSize : initialSize - stack.stackSize;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/** The owner's EMC balance; on the client, as last synced. */
|
||||||
|
public double getStoredEmc() {
|
||||||
|
if (worldObj.isRemote) {
|
||||||
|
return clientEmc;
|
||||||
|
}
|
||||||
|
|
||||||
|
return owner == null ? 0
|
||||||
|
: EmcPool.get(worldObj)
|
||||||
|
.get(owner);
|
||||||
|
}
|
||||||
|
|
||||||
|
/** Makes the player the owner if the builder has none yet. Server side only. */
|
||||||
|
public void claimOwner(EntityPlayer player) {
|
||||||
|
if (owner == null) {
|
||||||
|
owner = player.getUniqueID();
|
||||||
|
markDirty();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onBlockPlacedBy(EntityLivingBase entity, ItemStack stack) {
|
||||||
|
super.onBlockPlacedBy(entity, stack);
|
||||||
|
|
||||||
|
if (entity instanceof EntityPlayer) {
|
||||||
|
owner = entity.getUniqueID();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/** Converts the whole stack into EMC for the owner. Server side only. */
|
||||||
|
public void consumeForEmc(ItemStack stack) {
|
||||||
|
long value = EMCHelper.getEmcValue(stack);
|
||||||
|
|
||||||
|
if (owner == null || value <= 0 || stack.stackSize <= 0) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
EmcPool.get(worldObj)
|
||||||
|
.add(owner, (double) value * stack.stackSize);
|
||||||
|
stack.stackSize = 0;
|
||||||
|
sendNetworkUpdate();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void updateEntity() {
|
||||||
|
super.updateEntity();
|
||||||
|
|
||||||
|
if (worldObj.isRemote) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// The balance can also change through the owner's other EMC Builders, so poll it.
|
||||||
|
if (++ticksSinceEmcSync >= EMC_SYNC_INTERVAL) {
|
||||||
|
ticksSinceEmcSync = 0;
|
||||||
|
|
||||||
|
if (getStoredEmc() != sentEmc) {
|
||||||
|
sendNetworkUpdate();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void build() {
|
||||||
|
BptBuilderBase bpt = getBlueprint();
|
||||||
|
double emc = getStoredEmc();
|
||||||
|
|
||||||
|
if (!(bpt instanceof BptBuilderBlueprint) || emc <= 0) {
|
||||||
|
super.build();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// The needed item list is only filled once the builder has been initialized.
|
||||||
|
bpt.initialize();
|
||||||
|
prepareEmcSlots(((BptBuilderBlueprint) bpt).getNeededItems(), emc);
|
||||||
|
|
||||||
|
emcSlotsExposed = true;
|
||||||
|
|
||||||
|
try {
|
||||||
|
super.build();
|
||||||
|
} finally {
|
||||||
|
emcSlotsExposed = false;
|
||||||
|
chargeEmcSlots();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private void prepareEmcSlots(List<RequirementItemStack> needs, double emc) {
|
||||||
|
emcSlots.clear();
|
||||||
|
|
||||||
|
if (needs == null) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
for (RequirementItemStack need : needs) {
|
||||||
|
if (need.stack == null || need.stack.getItem() == null || need.size <= 0) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
long value = EMCHelper.getEmcValue(need.stack);
|
||||||
|
|
||||||
|
if (value <= 0) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
int affordable = (int) Math.min(Integer.MAX_VALUE, Math.floor(emc / value));
|
||||||
|
int size = Math.min(Math.min(need.stack.getMaxStackSize(), need.size), affordable);
|
||||||
|
|
||||||
|
if (size <= 0) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
ItemStack stack = need.stack.copy();
|
||||||
|
stack.stackSize = size;
|
||||||
|
emcSlots.add(new EmcSlot(stack, value));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private void chargeEmcSlots() {
|
||||||
|
double cost = 0;
|
||||||
|
|
||||||
|
for (EmcSlot slot : emcSlots) {
|
||||||
|
cost += (double) slot.consumed() * slot.emcPerItem;
|
||||||
|
}
|
||||||
|
|
||||||
|
emcSlots.clear();
|
||||||
|
|
||||||
|
if (cost > 0) {
|
||||||
|
EmcPool.get(worldObj)
|
||||||
|
.add(owner, -cost);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private int realSize() {
|
||||||
|
return super.getSizeInventory();
|
||||||
|
}
|
||||||
|
|
||||||
|
private EmcSlot emcSlot(int i) {
|
||||||
|
return emcSlotsExposed && i >= realSize() ? emcSlots.get(i - realSize()) : null;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public int getSizeInventory() {
|
||||||
|
return emcSlotsExposed ? realSize() + emcSlots.size() : realSize();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public ItemStack getStackInSlot(int i) {
|
||||||
|
EmcSlot slot = emcSlot(i);
|
||||||
|
return slot != null ? slot.stack : super.getStackInSlot(i);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public ItemStack decrStackSize(int i, int amount) {
|
||||||
|
EmcSlot slot = emcSlot(i);
|
||||||
|
|
||||||
|
if (slot == null) {
|
||||||
|
return super.decrStackSize(i, amount);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (slot.stack == null) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
ItemStack taken = slot.stack.splitStack(Math.min(amount, slot.stack.stackSize));
|
||||||
|
|
||||||
|
if (slot.stack.stackSize <= 0) {
|
||||||
|
slot.stack = null;
|
||||||
|
}
|
||||||
|
|
||||||
|
return taken;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void setInventorySlotContents(int i, ItemStack stack) {
|
||||||
|
EmcSlot slot = emcSlot(i);
|
||||||
|
|
||||||
|
if (slot == null) {
|
||||||
|
super.setInventorySlotContents(i, stack);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Schematic.useItem only writes to a slot once its stack is used up (possibly leaving a container item
|
||||||
|
// behind). Either way the whole virtual stack has been consumed; container items are not kept.
|
||||||
|
slot.stack = null;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public ItemStack getStackInSlotOnClosing(int i) {
|
||||||
|
return emcSlot(i) != null ? null : super.getStackInSlotOnClosing(i);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean isItemValidForSlot(int i, ItemStack stack) {
|
||||||
|
return emcSlot(i) == null && super.isItemValidForSlot(i, stack);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void readFromNBT(NBTTagCompound nbt) {
|
||||||
|
super.readFromNBT(nbt);
|
||||||
|
owner = nbt.hasKey(OWNER_MOST) ? new UUID(nbt.getLong(OWNER_MOST), nbt.getLong(OWNER_LEAST)) : null;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void writeToNBT(NBTTagCompound nbt) {
|
||||||
|
super.writeToNBT(nbt);
|
||||||
|
|
||||||
|
if (owner != null) {
|
||||||
|
nbt.setLong(OWNER_MOST, owner.getMostSignificantBits());
|
||||||
|
nbt.setLong(OWNER_LEAST, owner.getLeastSignificantBits());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void writeData(ByteBuf stream) {
|
||||||
|
super.writeData(stream);
|
||||||
|
sentEmc = getStoredEmc();
|
||||||
|
stream.writeDouble(sentEmc);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void readData(ByteBuf stream) {
|
||||||
|
super.readData(stream);
|
||||||
|
clientEmc = stream.readDouble();
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -1,8 +0,0 @@
|
|||||||
package net.kanawo.emcbuilder;
|
|
||||||
|
|
||||||
public class ClientProxy extends CommonProxy {
|
|
||||||
|
|
||||||
// Override CommonProxy methods here, if you want a different behaviour on the client (e.g. registering renders).
|
|
||||||
// Don't forget to call the super methods as well.
|
|
||||||
|
|
||||||
}
|
|
||||||
@@ -1,27 +0,0 @@
|
|||||||
package net.kanawo.emcbuilder;
|
|
||||||
|
|
||||||
import cpw.mods.fml.common.event.FMLInitializationEvent;
|
|
||||||
import cpw.mods.fml.common.event.FMLPostInitializationEvent;
|
|
||||||
import cpw.mods.fml.common.event.FMLPreInitializationEvent;
|
|
||||||
import cpw.mods.fml.common.event.FMLServerStartingEvent;
|
|
||||||
|
|
||||||
public class CommonProxy {
|
|
||||||
|
|
||||||
// preInit "Run before anything else. Read your config, create blocks, items, etc, and register them with the
|
|
||||||
// GameRegistry." (Remove if not needed)
|
|
||||||
public void preInit(FMLPreInitializationEvent event) {
|
|
||||||
Config.synchronizeConfiguration(event.getSuggestedConfigurationFile());
|
|
||||||
|
|
||||||
EMCBuilder.LOG.info(Config.greeting);
|
|
||||||
EMCBuilder.LOG.info("I am EMCBuilder at version " + Tags.VERSION);
|
|
||||||
}
|
|
||||||
|
|
||||||
// load "Do your mod setup. Build whatever data structures you care about. Register recipes." (Remove if not needed)
|
|
||||||
public void init(FMLInitializationEvent event) {}
|
|
||||||
|
|
||||||
// postInit "Handle interaction with other mods, complete your setup based on this." (Remove if not needed)
|
|
||||||
public void postInit(FMLPostInitializationEvent event) {}
|
|
||||||
|
|
||||||
// register server commands in this event handler (Remove if not needed)
|
|
||||||
public void serverStarting(FMLServerStartingEvent event) {}
|
|
||||||
}
|
|
||||||
@@ -1,20 +0,0 @@
|
|||||||
package net.kanawo.emcbuilder;
|
|
||||||
|
|
||||||
import java.io.File;
|
|
||||||
|
|
||||||
import net.minecraftforge.common.config.Configuration;
|
|
||||||
|
|
||||||
public class Config {
|
|
||||||
|
|
||||||
public static String greeting = "Hello World";
|
|
||||||
|
|
||||||
public static void synchronizeConfiguration(File configFile) {
|
|
||||||
Configuration configuration = new Configuration(configFile);
|
|
||||||
|
|
||||||
greeting = configuration.getString("greeting", Configuration.CATEGORY_GENERAL, greeting, "How shall I greet?");
|
|
||||||
|
|
||||||
if (configuration.hasChanged()) {
|
|
||||||
configuration.save();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,46 +0,0 @@
|
|||||||
package net.kanawo.emcbuilder;
|
|
||||||
|
|
||||||
import org.apache.logging.log4j.LogManager;
|
|
||||||
import org.apache.logging.log4j.Logger;
|
|
||||||
|
|
||||||
import cpw.mods.fml.common.Mod;
|
|
||||||
import cpw.mods.fml.common.SidedProxy;
|
|
||||||
import cpw.mods.fml.common.event.FMLInitializationEvent;
|
|
||||||
import cpw.mods.fml.common.event.FMLPostInitializationEvent;
|
|
||||||
import cpw.mods.fml.common.event.FMLPreInitializationEvent;
|
|
||||||
import cpw.mods.fml.common.event.FMLServerStartingEvent;
|
|
||||||
|
|
||||||
@Mod(modid = EMCBuilder.MODID, version = "1.0.0", name = "EMCBuilder", acceptedMinecraftVersions = "[1.7.10]")
|
|
||||||
public class EMCBuilder {
|
|
||||||
|
|
||||||
public static final String MODID = "emcbuilder";
|
|
||||||
public static final Logger LOG = LogManager.getLogger(MODID);
|
|
||||||
|
|
||||||
@SidedProxy(clientSide = "net.kanawo.emcbuilder.ClientProxy", serverSide = "net.kanawo.emcbuilder.CommonProxy")
|
|
||||||
public static CommonProxy proxy;
|
|
||||||
|
|
||||||
@Mod.EventHandler
|
|
||||||
// preInit "Run before anything else. Read your config, create blocks, items, etc, and register them with the
|
|
||||||
// GameRegistry." (Remove if not needed)
|
|
||||||
public void preInit(FMLPreInitializationEvent event) {
|
|
||||||
proxy.preInit(event);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Mod.EventHandler
|
|
||||||
// load "Do your mod setup. Build whatever data structures you care about. Register recipes." (Remove if not needed)
|
|
||||||
public void init(FMLInitializationEvent event) {
|
|
||||||
proxy.init(event);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Mod.EventHandler
|
|
||||||
// postInit "Handle interaction with other mods, complete your setup based on this." (Remove if not needed)
|
|
||||||
public void postInit(FMLPostInitializationEvent event) {
|
|
||||||
proxy.postInit(event);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Mod.EventHandler
|
|
||||||
// register server commands in this event handler (Remove if not needed)
|
|
||||||
public void serverStarting(FMLServerStartingEvent event) {
|
|
||||||
proxy.serverStarting(event);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,6 +1,6 @@
|
|||||||
MIT License
|
MIT License
|
||||||
|
|
||||||
Copyright (c) [year] [fullname]
|
Copyright (c) 2026 agomizi1cm
|
||||||
|
|
||||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||||
of this software and associated documentation files (the "Software"), to deal
|
of this software and associated documentation files (the "Software"), to deal
|
||||||
|
|||||||
@@ -0,0 +1,2 @@
|
|||||||
|
tile.emcBuilder.name=EMC Builder
|
||||||
|
gui.cemodern.stored=EMC: %s
|
||||||
@@ -0,0 +1,2 @@
|
|||||||
|
tile.emcBuilder.name=EMCビルダー
|
||||||
|
gui.cemodern.stored=EMC: %s
|
||||||
Binary file not shown.
|
After Width: | Height: | Size: 1.1 KiB |
Binary file not shown.
|
After Width: | Height: | Size: 1.1 KiB |
Binary file not shown.
|
After Width: | Height: | Size: 1.5 KiB |
Binary file not shown.
|
After Width: | Height: | Size: 2.1 KiB |
@@ -3,18 +3,18 @@
|
|||||||
"modList": [{
|
"modList": [{
|
||||||
"modid": "${modId}",
|
"modid": "${modId}",
|
||||||
"name": "${modName}",
|
"name": "${modName}",
|
||||||
"description": "An example mod for Minecraft 1.7.10 with Forge focused on a stable setup.",
|
"description": "A Minecraft 1.7.10 port of CE. Adds the EMC Builder, a BuildCraft Builder that pays for its materials with EMC.",
|
||||||
"version": "${modVersion}",
|
"version": "${modVersion}",
|
||||||
"mcversion": "${minecraftVersion}",
|
"mcversion": "${minecraftVersion}",
|
||||||
"url": "https://github.com/SinTh0r4s/MyMod",
|
"url": "",
|
||||||
"updateUrl": "",
|
"updateUrl": "",
|
||||||
"authorList": ["SinTho0r4s"],
|
"authorList": ["agomizi1cm"],
|
||||||
"credits": "",
|
"credits": "Original CE. Built on BuildCraft and ProjectE.",
|
||||||
"logoFile": "",
|
"logoFile": "",
|
||||||
"screenshots": [],
|
"screenshots": [],
|
||||||
"parent": "",
|
"parent": "",
|
||||||
"requiredMods": [],
|
"requiredMods": ["BuildCraft|Builders", "ProjectE"],
|
||||||
"dependencies": [],
|
"dependencies": ["BuildCraft|Builders", "ProjectE"],
|
||||||
"dependants": [],
|
"dependants": [],
|
||||||
"useDependencyInformation": false
|
"useDependencyInformation": false
|
||||||
}]
|
}]
|
||||||
|
|||||||
Reference in new issue
Block a user