-
Notifications
You must be signed in to change notification settings - Fork 79
/
ChiselBlockCrafting.java
303 lines (256 loc) · 6.44 KB
/
ChiselBlockCrafting.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
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
package mod.chiselsandbits.crafting;
import java.util.Random;
import mod.chiselsandbits.api.APIExceptions.InvalidBitItem;
import mod.chiselsandbits.api.IBitAccess;
import mod.chiselsandbits.api.IBitBag;
import mod.chiselsandbits.api.IBitBrush;
import mod.chiselsandbits.api.IBitVisitor;
import mod.chiselsandbits.api.ItemType;
import mod.chiselsandbits.chiseledblock.ItemBlockChiseled;
import mod.chiselsandbits.core.ChiselsAndBits;
import mod.chiselsandbits.helpers.ModUtil;
import mod.chiselsandbits.items.ItemBitBag;
import mod.chiselsandbits.items.ItemChisel;
import net.minecraft.block.state.IBlockState;
import net.minecraft.init.Blocks;
import net.minecraft.inventory.InventoryCrafting;
import net.minecraft.item.ItemBlock;
import net.minecraft.item.ItemStack;
import net.minecraft.item.crafting.IRecipe;
import net.minecraft.util.EnumFacing;
import net.minecraft.util.NonNullList;
import net.minecraft.world.World;
public class ChiselBlockCrafting implements IRecipe
{
static private class ChiselBlockInfo
{
public ItemStack chisel = ModUtil.getEmptyStack();
public int chisel_slot = -1;
public ItemStack bag = ModUtil.getEmptyStack();
public int bag_slot = -1;
public ItemStack block = ModUtil.getEmptyStack();
public int block_slot = -1;
public boolean isValid;
public boolean modified = false;
private static class Chiseler implements IBitVisitor
{
private final ItemStack chisel;
private final IBitBag bbag;
private final Random r = new Random();
final IBitBrush airBrush;
public boolean isSolid = false;
public boolean modified = false;
public Chiseler(
final ItemStack chisel,
final IBitBag bag ) throws InvalidBitItem
{
airBrush = ChiselsAndBits.getApi().createBrushFromState( null );
this.chisel = chisel;
bbag = bag;
r.setSeed( 0 ); // ensure that the results are always the same,
// crafting needs to be 'regular'
}
@Override
public IBitBrush visitBit(
final int x,
final int y,
final int z,
final IBitBrush currentValue )
{
if ( chisel.getItemDamage() < chisel.getMaxDamage() )
{
ModUtil.damageItem( chisel, r );
final ItemStack is = currentValue.getItemStack( 1 );
if ( is != null )
{
for ( int idx = 0; idx < bbag.getSlots(); ++idx )
{
if ( ModUtil.isEmpty( bbag.insertItem( idx, is, false ) ) )
{
modified = true;
return airBrush;
}
}
}
}
isSolid = true;
return currentValue;
};
};
public void doLogic()
{
bag = ModUtil.copy( bag );
block = ModUtil.copy( block );
chisel = ModUtil.copy( chisel );
try
{
final IBitAccess ba = ChiselsAndBits.getApi().createBitItem( block );
final Chiseler c = new Chiseler( chisel, ChiselsAndBits.getApi().getBitbag( bag ) );
if ( ba == null )
{
return;
}
ba.visitBits( c );
modified = c.modified;
if ( c.isSolid )
{
if ( ModUtil.getStackSize( block ) == 1 )
{
block = ba.getBitsAsItem( EnumFacing.NORTH, ItemType.CHISLED_BLOCK, false );
}
else
{
modified = false;
}
}
else
{
block = ModUtil.getEmptyStack();
}
}
catch ( final InvalidBitItem e )
{
}
}
};
private ChiselBlockInfo getInfo(
final InventoryCrafting inv )
{
final ChiselBlockInfo i = new ChiselBlockInfo();
boolean noDuplicates = true;
boolean noStrangeitems = true;
for ( int x = 0; x < inv.getSizeInventory(); ++x )
{
final ItemStack is = inv.getStackInSlot( x );
if ( ModUtil.isEmpty( is ) )
{
continue;
}
if ( is.getItem() instanceof ItemBitBag )
{
if ( i.bag_slot != -1 )
{
noDuplicates = false;
}
i.bag = is;
i.bag_slot = x;
continue;
}
if ( is.getItem() instanceof ItemChisel )
{
if ( i.chisel_slot != -1 )
{
noDuplicates = false;
}
i.chisel = is;
i.chisel_slot = x;
continue;
}
if ( is.getItem() instanceof ItemBlock )
{
if ( i.block_slot != -1 )
{
noDuplicates = false;
}
final IBlockState actingState = ModUtil.getStateFromItem( is );
if ( actingState.getBlock() != Blocks.AIR )
{
try
{
final IBitBrush state = ChiselsAndBits.getApi().createBrushFromState( actingState );
final IBitAccess item = ChiselsAndBits.getApi().createBitItem( ModUtil.getEmptyStack() );
assert item != null;
item.visitBits( new IBitVisitor() {
@Override
public IBitBrush visitBit(
final int x,
final int y,
final int z,
final IBitBrush currentValue )
{
return state;
}
} );
i.block = item.getBitsAsItem( EnumFacing.EAST, ItemType.CHISLED_BLOCK, false );
if ( i.block != null )
{
ModUtil.setStackSize( i.block, ModUtil.getStackSize( is ) );
i.block_slot = x;
continue;
}
}
catch ( final InvalidBitItem err )
{
// not supported.
}
}
}
if ( is.getItem() instanceof ItemBlockChiseled )
{
if ( i.block_slot != -1 )
{
noDuplicates = false;
}
i.block = is;
i.block_slot = x;
continue;
}
noStrangeitems = false;
}
i.isValid = i.chisel_slot != -1 && i.bag_slot != -1 && i.block_slot != -1 && noDuplicates && noStrangeitems;
return i;
}
@Override
public boolean matches(
final InventoryCrafting inv,
final World worldIn )
{
return getInfo( inv ).isValid;
}
@Override
public ItemStack getCraftingResult(
final InventoryCrafting inv )
{
final ChiselBlockInfo cbc = getInfo( inv );
cbc.doLogic();
if ( cbc.isValid && cbc.modified )
{
return cbc.bag;
}
return ModUtil.getEmptyStack();
}
@Override
public int getRecipeSize()
{
return 3;
}
@Override
public ItemStack getRecipeOutput()
{
return ModUtil.getEmptyStack();
}
@Override
public NonNullList<ItemStack> getRemainingItems(
final InventoryCrafting inv )
{
final NonNullList<ItemStack> list = NonNullList.func_191196_a();
final ChiselBlockInfo cbc = getInfo( inv );
cbc.doLogic();
for ( int x = 0; x < inv.getSizeInventory(); ++x )
{
if ( cbc.isValid && x == cbc.chisel_slot && !ModUtil.isEmpty( cbc.chisel ) && cbc.chisel.getItemDamage() < cbc.chisel.getMaxDamage() )
{
list.add( cbc.chisel );
}
else if ( cbc.isValid && x == cbc.block_slot && !ModUtil.isEmpty( cbc.block ) )
{
list.add( cbc.block );
}
else
{
list.add( ModUtil.getEmptyStack() );
}
}
return list;
}
}