-
Notifications
You must be signed in to change notification settings - Fork 497
/
PipeExtensionListener.java
153 lines (131 loc) · 6.1 KB
/
PipeExtensionListener.java
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
package buildcraft.transport.stripes;
import java.util.HashMap;
import java.util.HashSet;
import java.util.List;
import java.util.Map;
import net.minecraft.block.state.IBlockState;
import net.minecraft.item.ItemStack;
import net.minecraft.nbt.NBTTagCompound;
import net.minecraft.tileentity.TileEntity;
import net.minecraft.util.BlockPos;
import net.minecraft.util.EnumFacing;
import net.minecraft.util.MathHelper;
import net.minecraft.util.Vec3;
import net.minecraft.world.World;
import net.minecraft.world.WorldServer;
import net.minecraftforge.fml.common.eventhandler.SubscribeEvent;
import net.minecraftforge.fml.common.gameevent.TickEvent;
import buildcraft.BuildCraftTransport;
import buildcraft.api.core.BCLog;
import buildcraft.api.transport.IStripesActivator;
import buildcraft.core.lib.utils.Utils;
import buildcraft.core.proxy.CoreProxy;
import buildcraft.transport.Pipe;
import buildcraft.transport.PipeTransportItems;
import buildcraft.transport.TileGenericPipe;
import buildcraft.transport.TravelingItem;
import buildcraft.transport.utils.TransportUtils;
public class PipeExtensionListener {
private class PipeExtensionRequest {
public ItemStack stack;
public BlockPos pos;
public EnumFacing o;
public IStripesActivator h;
}
private final Map<Integer, HashSet<PipeExtensionRequest>> requests = new HashMap<>();
public void requestPipeExtension(ItemStack stack, World world, BlockPos pos, EnumFacing o, IStripesActivator h) {
if (world.isRemote) {
return;
}
if (!requests.containsKey(world.provider.getDimensionId())) {
requests.put(world.provider.getDimensionId(), new HashSet<PipeExtensionRequest>());
}
PipeExtensionRequest r = new PipeExtensionRequest();
r.stack = stack;
r.pos = pos;
r.o = o;
r.h = h;
requests.get(world.provider.getDimensionId()).add(r);
}
@SubscribeEvent
public void tick(TickEvent.WorldTickEvent event) {
if (event.phase == TickEvent.Phase.END && requests.containsKey(event.world.provider.getDimensionId())) {
HashSet<PipeExtensionRequest> rSet = requests.get(event.world.provider.getDimensionId());
World w = event.world;
for (PipeExtensionRequest r : rSet) {
Vec3 target = Utils.convert(r.pos);
boolean retract = r.stack.getItem() == BuildCraftTransport.pipeItemsVoid;
List<ItemStack> removedPipeStacks = null;
if (retract) {
target = target.add(Utils.convert(r.o, -1));
} else {
target = target.add(Utils.convert(r.o, 1));
if (!w.isAirBlock(Utils.convertFloor(target))) {
r.h.sendItem(r.stack, r.o.getOpposite());
continue;
}
}
// Step 1: Copy over and remove existing pipe
IBlockState oldState = w.getBlockState(r.pos);
NBTTagCompound nbt = new NBTTagCompound();
TileEntity old = w.getTileEntity(r.pos);
if (!(old instanceof TileGenericPipe)) {
BCLog.logger.warn("Found an invalid request at " + r.pos + " as " + old + " was not a tile generic pipe!");
continue;
}
old.writeToNBT(nbt);
w.setBlockToAir(r.pos);
boolean failedPlacement = false;
// Step 2: If retracting, remove previous pipe; if extending, add new pipe
BlockPos targetPos = Utils.convertFloor(target);
if (retract) {
removedPipeStacks = w.getBlockState(targetPos).getBlock().getDrops(w, targetPos, w.getBlockState(targetPos), 0);
w.setBlockToAir(targetPos);
} else {
r.stack.getItem().onItemUse(r.stack, CoreProxy.proxy.getBuildCraftPlayer((WorldServer) w, r.pos).get(), w, r.pos, EnumFacing.UP,
0, 0, 0);
}
// Step 3: Place stripes pipe back
// - Correct NBT coordinates
nbt.setInteger("x", MathHelper.floor_double(target.xCoord));
nbt.setInteger("y", MathHelper.floor_double(target.yCoord));
nbt.setInteger("z", MathHelper.floor_double(target.zCoord));
// - Create block and tile
w.setBlockState(targetPos, oldState, 3);
TileGenericPipe pipeTile = (TileGenericPipe) w.getTileEntity(targetPos);
pipeTile.readFromNBT(nbt);
pipeTile.setWorldObj(w);
pipeTile.validate();
pipeTile.update();
// Step 4: Hope for the best, clean up.
PipeTransportItems items = (PipeTransportItems) ((Pipe) pipeTile.getPipe()).transport;
if (!retract && !failedPlacement) {
r.stack.stackSize--;
}
if (r.stack.stackSize > 0) {
sendItem(items, r.stack, r.o.getOpposite());
}
if (removedPipeStacks != null) {
for (ItemStack s : removedPipeStacks) {
sendItem(items, s, r.o.getOpposite());
}
}
if (!retract && !failedPlacement) {
TileGenericPipe newPipeTile = (TileGenericPipe) w.getTileEntity(targetPos);
newPipeTile.update();
pipeTile.scheduleNeighborChange();
if (pipeTile.getPipe() != null) {
((Pipe) pipeTile.getPipe()).scheduleWireUpdate();
}
}
}
rSet.clear();
}
}
private void sendItem(PipeTransportItems transport, ItemStack itemStack, EnumFacing direction) {
Vec3 pos = Utils.convert(transport.container.getPos());
pos = pos.addVector(0.5, TransportUtils.getPipeFloorOf(itemStack), 0.5);
TravelingItem newItem = TravelingItem.make(pos, itemStack);
transport.injectItem(newItem, direction);
}
}