1
0
mirror of https://github.com/SquidDev-CC/CC-Tweaked synced 2025-11-14 04:07:09 +00:00

Clean up data-gathering code

- Refer to this as "data" rather than "metadata". I'm still not sure
   where the meta came from - blame OpenPeripheral I guess.
 - Likewise, use getItemDetail within inventory methods, rather than
   getItemMeta.
 - Refactor common data-getting code into one class. This means that
   turtle.getItemDetail, turtle.inspect and commands.getBlockInfo all
   use the same code.
 - turtle.getItemDetail now accepts a second "detailed" parameter which
   will include the full metadata (#471, #452).
 - Tags are now only included in the detailed list. This is a breaking
   change, however should only affect one version (1.89.x) and I'm not
   convinced that the previous behaviour was safe.
This commit is contained in:
SquidDev
2020-06-30 12:35:39 +01:00
parent 8f3a56dd32
commit 36bb8b67c9
12 changed files with 143 additions and 93 deletions

View File

@@ -13,13 +13,12 @@ import dan200.computercraft.api.turtle.TurtleSide;
import dan200.computercraft.api.turtle.event.TurtleActionEvent;
import dan200.computercraft.api.turtle.event.TurtleInspectItemEvent;
import dan200.computercraft.core.apis.IAPIEnvironment;
import dan200.computercraft.core.asm.TaskCallback;
import dan200.computercraft.core.tracking.TrackingField;
import dan200.computercraft.shared.peripheral.generic.data.ItemData;
import dan200.computercraft.shared.turtle.core.*;
import net.minecraft.item.Item;
import net.minecraft.item.ItemStack;
import net.minecraft.util.ResourceLocation;
import net.minecraftforge.common.MinecraftForge;
import net.minecraftforge.registries.ForgeRegistries;
import java.util.HashMap;
import java.util.Map;
@@ -309,28 +308,26 @@ public class TurtleAPI implements ILuaAPI
}
@LuaFunction
public final Object[] getItemDetail( Optional<Integer> slotArg ) throws LuaException
public final MethodResult getItemDetail( ILuaContext context, Optional<Integer> slotArg, Optional<Boolean> detailedArg ) throws LuaException
{
// FIXME: There's a race condition here if the stack is being modified (mutating NBT, etc...)
// on another thread. The obvious solution is to move this into a command, but some programs rely
// on this having a 0-tick delay.
int slot = checkSlot( slotArg ).orElse( turtle.getSelectedSlot() );
boolean detailed = detailedArg.orElse( false );
return detailed
? TaskCallback.make( context, () -> getItemDetail( slot, true ) )
: MethodResult.of( getItemDetail( slot, false ) );
}
private Object[] getItemDetail( int slot, boolean detailed )
{
ItemStack stack = turtle.getInventory().getStackInSlot( slot );
if( stack.isEmpty() ) return new Object[] { null };
Item item = stack.getItem();
String name = ForgeRegistries.ITEMS.getKey( item ).toString();
int count = stack.getCount();
Map<String, Object> table = detailed
? ItemData.fill( new HashMap<>(), stack )
: ItemData.fillBasic( new HashMap<>(), stack );
Map<String, Object> table = new HashMap<>();
table.put( "name", name );
table.put( "count", count );
Map<String, Boolean> tags = new HashMap<>();
for( ResourceLocation location : item.getTags() ) tags.put( location.toString(), true );
table.put( "tags", tags );
TurtleActionEvent event = new TurtleInspectItemEvent( turtle, stack, table );
TurtleActionEvent event = new TurtleInspectItemEvent( turtle, stack, table, detailed );
if( MinecraftForge.EVENT_BUS.post( event ) ) return new Object[] { false, event.getFailureMessage() };
return new Object[] { table };

View File

@@ -5,20 +5,16 @@
*/
package dan200.computercraft.shared.turtle.core;
import com.google.common.collect.ImmutableMap;
import dan200.computercraft.api.turtle.ITurtleAccess;
import dan200.computercraft.api.turtle.ITurtleCommand;
import dan200.computercraft.api.turtle.TurtleCommandResult;
import dan200.computercraft.api.turtle.event.TurtleBlockEvent;
import net.minecraft.block.Block;
import dan200.computercraft.shared.peripheral.generic.data.BlockData;
import net.minecraft.block.BlockState;
import net.minecraft.state.IProperty;
import net.minecraft.util.Direction;
import net.minecraft.util.ResourceLocation;
import net.minecraft.util.math.BlockPos;
import net.minecraft.world.World;
import net.minecraftforge.common.MinecraftForge;
import net.minecraftforge.registries.ForgeRegistries;
import javax.annotation.Nonnull;
import java.util.HashMap;
@@ -51,23 +47,7 @@ public class TurtleInspectCommand implements ITurtleCommand
return TurtleCommandResult.failure( "No block to inspect" );
}
Block block = state.getBlock();
String name = ForgeRegistries.BLOCKS.getKey( block ).toString();
Map<String, Object> table = new HashMap<>();
table.put( "name", name );
Map<Object, Object> stateTable = new HashMap<>();
for( ImmutableMap.Entry<IProperty<?>, ? extends Comparable<?>> entry : state.getValues().entrySet() )
{
IProperty<?> property = entry.getKey();
stateTable.put( property.getName(), getPropertyValue( property, entry.getValue() ) );
}
table.put( "state", stateTable );
Map<String, Boolean> tags = new HashMap<>();
for( ResourceLocation location : block.getTags() ) tags.put( location.toString(), true );
table.put( "tags", tags );
Map<String, Object> table = BlockData.fill( new HashMap<>(), state );
// Fire the event, exiting if it is cancelled
TurtlePlayer turtlePlayer = TurtlePlaceCommand.createPlayer( turtle, oldPosition, direction );
@@ -77,11 +57,4 @@ public class TurtleInspectCommand implements ITurtleCommand
return TurtleCommandResult.success( new Object[] { table } );
}
@SuppressWarnings( { "unchecked", "rawtypes" } )
private static Object getPropertyValue( IProperty property, Comparable value )
{
if( value instanceof String || value instanceof Number || value instanceof Boolean ) return value;
return property.getName( value );
}
}