mirror of
https://github.com/SquidDev-CC/CC-Tweaked
synced 2025-11-12 19:33:00 +00:00
Add turtle events
The main aim of this is to allow for greater extensibility for other mods. For instance, you can now prevent turtles placing dirt blocks, or turning when on gravel.
This commit is contained in:
@@ -11,11 +11,14 @@ import dan200.computercraft.api.lua.LuaException;
|
||||
import dan200.computercraft.api.turtle.ITurtleAccess;
|
||||
import dan200.computercraft.api.turtle.ITurtleCommand;
|
||||
import dan200.computercraft.api.turtle.TurtleSide;
|
||||
import dan200.computercraft.api.turtle.event.TurtleAction;
|
||||
import dan200.computercraft.api.turtle.event.TurtleActionEvent;
|
||||
import dan200.computercraft.core.apis.IAPIEnvironment;
|
||||
import dan200.computercraft.core.apis.ILuaAPI;
|
||||
import dan200.computercraft.shared.turtle.core.*;
|
||||
import net.minecraft.item.Item;
|
||||
import net.minecraft.item.ItemStack;
|
||||
import net.minecraftforge.common.MinecraftForge;
|
||||
|
||||
import javax.annotation.Nonnull;
|
||||
import java.util.HashMap;
|
||||
@@ -439,6 +442,13 @@ public class TurtleAPI implements ILuaAPI
|
||||
table.put( "name", name );
|
||||
table.put( "damage", damage );
|
||||
table.put( "count", count );
|
||||
|
||||
TurtleActionEvent event = new TurtleActionEvent( m_turtle, TurtleAction.INSPECT_ITEM );
|
||||
if( MinecraftForge.EVENT_BUS.post( event ) )
|
||||
{
|
||||
return new Object[] { false, event.getFailureMessage() };
|
||||
}
|
||||
|
||||
return new Object[] { table };
|
||||
}
|
||||
else
|
||||
|
||||
@@ -10,12 +10,14 @@ import dan200.computercraft.api.turtle.ITurtleAccess;
|
||||
import dan200.computercraft.api.turtle.ITurtleCommand;
|
||||
import dan200.computercraft.api.turtle.TurtleAnimation;
|
||||
import dan200.computercraft.api.turtle.TurtleCommandResult;
|
||||
import dan200.computercraft.api.turtle.event.TurtleInventoryEvent;
|
||||
import dan200.computercraft.shared.util.InventoryUtil;
|
||||
import dan200.computercraft.shared.util.WorldUtil;
|
||||
import net.minecraft.item.ItemStack;
|
||||
import net.minecraft.util.EnumFacing;
|
||||
import net.minecraft.util.math.BlockPos;
|
||||
import net.minecraft.world.World;
|
||||
import net.minecraftforge.common.MinecraftForge;
|
||||
import net.minecraftforge.items.IItemHandler;
|
||||
|
||||
import javax.annotation.Nonnull;
|
||||
@@ -59,6 +61,16 @@ public class TurtleDropCommand implements ITurtleCommand
|
||||
EnumFacing side = direction.getOpposite();
|
||||
|
||||
IItemHandler inventory = InventoryUtil.getInventory( world, newPosition, side );
|
||||
|
||||
// Fire the event, restoring the inventory and exiting if it is cancelled.
|
||||
TurtlePlayer player = TurtlePlaceCommand.createPlayer( turtle, oldPosition, direction );
|
||||
TurtleInventoryEvent.Drop event = new TurtleInventoryEvent.Drop( turtle, player, world, newPosition, inventory, stack );
|
||||
if( MinecraftForge.EVENT_BUS.post( event ) )
|
||||
{
|
||||
InventoryUtil.storeItems( stack, turtle.getItemHandler(), turtle.getSelectedSlot() );
|
||||
return TurtleCommandResult.failure( event.getFailureMessage() );
|
||||
}
|
||||
|
||||
if( inventory != null )
|
||||
{
|
||||
// Drop the item into the inventory
|
||||
|
||||
@@ -8,11 +8,14 @@ package dan200.computercraft.shared.turtle.core;
|
||||
|
||||
import dan200.computercraft.ComputerCraft;
|
||||
import dan200.computercraft.api.turtle.*;
|
||||
import dan200.computercraft.api.turtle.event.TurtleAction;
|
||||
import dan200.computercraft.api.turtle.event.TurtleActionEvent;
|
||||
import dan200.computercraft.shared.proxy.CCTurtleProxyCommon;
|
||||
import dan200.computercraft.shared.util.InventoryUtil;
|
||||
import dan200.computercraft.shared.util.WorldUtil;
|
||||
import net.minecraft.item.ItemStack;
|
||||
import net.minecraft.util.math.BlockPos;
|
||||
import net.minecraftforge.common.MinecraftForge;
|
||||
import net.minecraftforge.items.IItemHandler;
|
||||
|
||||
import javax.annotation.Nonnull;
|
||||
@@ -63,6 +66,12 @@ public class TurtleEquipCommand implements ITurtleCommand
|
||||
oldUpgradeStack = null;
|
||||
}
|
||||
|
||||
TurtleActionEvent event = new TurtleActionEvent( turtle, TurtleAction.EQUIP );
|
||||
if( MinecraftForge.EVENT_BUS.post( event ) )
|
||||
{
|
||||
return TurtleCommandResult.failure( event.getFailureMessage() );
|
||||
}
|
||||
|
||||
// Do the swapping:
|
||||
if( newUpgradeStack != null )
|
||||
{
|
||||
|
||||
@@ -10,13 +10,15 @@ 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 dan200.computercraft.shared.util.WorldUtil;
|
||||
import net.minecraft.block.Block;
|
||||
import net.minecraft.block.properties.IProperty;
|
||||
import net.minecraft.block.state.IBlockState;
|
||||
import net.minecraft.util.math.BlockPos;
|
||||
import net.minecraft.util.EnumFacing;
|
||||
import net.minecraft.util.math.BlockPos;
|
||||
import net.minecraft.world.World;
|
||||
import net.minecraftforge.common.MinecraftForge;
|
||||
|
||||
import javax.annotation.Nonnull;
|
||||
import java.util.HashMap;
|
||||
@@ -46,14 +48,14 @@ public class TurtleInspectCommand implements ITurtleCommand
|
||||
|
||||
if( WorldUtil.isBlockInWorld( world, newPosition ) )
|
||||
{
|
||||
if( !FAIL_ON_AIR || !world.isAirBlock( newPosition ) )
|
||||
IBlockState state = world.getBlockState( newPosition );
|
||||
if( !FAIL_ON_AIR || !state.getBlock().isAir( state, world, newPosition ) )
|
||||
{
|
||||
IBlockState state = world.getBlockState( newPosition );
|
||||
Block block = state.getBlock();
|
||||
String name = Block.REGISTRY.getNameForObject( block ).toString();
|
||||
int metadata = block.getMetaFromState( state );
|
||||
|
||||
Map<Object, Object> table = new HashMap<>();
|
||||
Map<String, Object> table = new HashMap<>();
|
||||
table.put( "name", name );
|
||||
table.put( "metadata", metadata );
|
||||
|
||||
@@ -73,7 +75,15 @@ public class TurtleInspectCommand implements ITurtleCommand
|
||||
}
|
||||
table.put( "state", stateTable );
|
||||
|
||||
return TurtleCommandResult.success( new Object[]{ table } );
|
||||
// Fire the event, exiting if it is cancelled
|
||||
TurtlePlayer turtlePlayer = TurtlePlaceCommand.createPlayer( turtle, oldPosition, direction );
|
||||
TurtleBlockEvent.Inspect event = new TurtleBlockEvent.Inspect( turtle, turtlePlayer, world, newPosition, state, table );
|
||||
if( MinecraftForge.EVENT_BUS.post( event ) )
|
||||
{
|
||||
return TurtleCommandResult.failure( event.getFailureMessage() );
|
||||
}
|
||||
|
||||
return TurtleCommandResult.success( new Object[] { table } );
|
||||
}
|
||||
}
|
||||
|
||||
@@ -83,7 +93,7 @@ public class TurtleInspectCommand implements ITurtleCommand
|
||||
table.put( "name", "minecraft:air" );
|
||||
table.put( "metadata", 0 );
|
||||
table.put( "state", new HashMap<>() );
|
||||
return TurtleCommandResult.success( new Object[]{ table } );
|
||||
return TurtleCommandResult.success( new Object[] { table } );
|
||||
}
|
||||
return TurtleCommandResult.failure( "No block to inspect" );
|
||||
}
|
||||
|
||||
@@ -11,13 +11,15 @@ import dan200.computercraft.api.turtle.ITurtleAccess;
|
||||
import dan200.computercraft.api.turtle.ITurtleCommand;
|
||||
import dan200.computercraft.api.turtle.TurtleAnimation;
|
||||
import dan200.computercraft.api.turtle.TurtleCommandResult;
|
||||
import dan200.computercraft.api.turtle.event.TurtleBlockEvent;
|
||||
import dan200.computercraft.shared.util.WorldUtil;
|
||||
import net.minecraft.block.Block;
|
||||
import net.minecraft.entity.Entity;
|
||||
import net.minecraft.util.EnumFacing;
|
||||
import net.minecraft.util.math.AxisAlignedBB;
|
||||
import net.minecraft.util.math.BlockPos;
|
||||
import net.minecraft.util.EnumFacing;
|
||||
import net.minecraft.world.World;
|
||||
import net.minecraftforge.common.MinecraftForge;
|
||||
|
||||
import javax.annotation.Nonnull;
|
||||
import java.util.List;
|
||||
@@ -103,6 +105,12 @@ public class TurtleMoveCommand implements ITurtleCommand
|
||||
}
|
||||
}
|
||||
|
||||
TurtleBlockEvent.Move moveEvent = new TurtleBlockEvent.Move( turtle, turtlePlayer, oldWorld, newPosition );
|
||||
if( MinecraftForge.EVENT_BUS.post( moveEvent ) )
|
||||
{
|
||||
return TurtleCommandResult.failure( moveEvent.getFailureMessage() );
|
||||
}
|
||||
|
||||
// Check fuel level
|
||||
if( turtle.isFuelNeeded() && turtle.getFuelLevel() < 1 )
|
||||
{
|
||||
|
||||
@@ -11,6 +11,7 @@ import dan200.computercraft.api.turtle.ITurtleAccess;
|
||||
import dan200.computercraft.api.turtle.ITurtleCommand;
|
||||
import dan200.computercraft.api.turtle.TurtleAnimation;
|
||||
import dan200.computercraft.api.turtle.TurtleCommandResult;
|
||||
import dan200.computercraft.api.turtle.event.TurtleBlockEvent;
|
||||
import dan200.computercraft.shared.util.DirectionUtil;
|
||||
import dan200.computercraft.shared.util.InventoryUtil;
|
||||
import dan200.computercraft.shared.util.WorldUtil;
|
||||
@@ -31,6 +32,7 @@ import net.minecraft.util.text.TextComponentString;
|
||||
import net.minecraft.world.World;
|
||||
import net.minecraft.world.WorldServer;
|
||||
import net.minecraftforge.common.ForgeHooks;
|
||||
import net.minecraftforge.common.MinecraftForge;
|
||||
import net.minecraftforge.event.entity.player.PlayerInteractEvent;
|
||||
import net.minecraftforge.fml.common.eventhandler.Event;
|
||||
import org.apache.commons.lang3.tuple.Pair;
|
||||
@@ -64,6 +66,16 @@ public class TurtlePlaceCommand implements ITurtleCommand
|
||||
World world = turtle.getWorld();
|
||||
BlockPos coordinates = WorldUtil.moveCoords( turtle.getPosition(), direction );
|
||||
|
||||
// Create a fake player, and orient it appropriately
|
||||
BlockPos playerPosition = WorldUtil.moveCoords( turtle.getPosition(), direction );
|
||||
TurtlePlayer turtlePlayer = createPlayer( turtle, playerPosition, direction );
|
||||
|
||||
TurtleBlockEvent.Place place = new TurtleBlockEvent.Place( turtle, turtlePlayer, turtle.getWorld(), coordinates, stack );
|
||||
if( MinecraftForge.EVENT_BUS.post( place ) )
|
||||
{
|
||||
return TurtleCommandResult.failure( place.getFailureMessage() );
|
||||
}
|
||||
|
||||
IBlockState previousState;
|
||||
if( WorldUtil.isBlockInWorld( world, coordinates ) )
|
||||
{
|
||||
@@ -75,8 +87,8 @@ public class TurtlePlaceCommand implements ITurtleCommand
|
||||
}
|
||||
|
||||
// Do the deploying
|
||||
String[] errorMessage = new String[1];
|
||||
ItemStack remainder = deploy( stack, turtle, direction, m_extraArguments, errorMessage );
|
||||
String[] errorMessage = new String[ 1 ];
|
||||
ItemStack remainder = deploy( stack, turtle, turtlePlayer, direction, m_extraArguments, errorMessage );
|
||||
if( remainder != stack )
|
||||
{
|
||||
// Put the remaining items back
|
||||
@@ -117,6 +129,11 @@ public class TurtlePlaceCommand implements ITurtleCommand
|
||||
BlockPos playerPosition = WorldUtil.moveCoords( turtle.getPosition(), direction );
|
||||
TurtlePlayer turtlePlayer = createPlayer( turtle, playerPosition, direction );
|
||||
|
||||
return deploy( stack, turtle, turtlePlayer, direction, extraArguments, o_errorMessage );
|
||||
}
|
||||
|
||||
public static ItemStack deploy( @Nonnull ItemStack stack, ITurtleAccess turtle, TurtlePlayer turtlePlayer, EnumFacing direction, Object[] extraArguments, String[] o_errorMessage )
|
||||
{
|
||||
// Deploy on an entity
|
||||
ItemStack remainder = deployOnEntity( stack, turtle, turtlePlayer, direction, extraArguments, o_errorMessage );
|
||||
if( remainder != stack )
|
||||
|
||||
@@ -10,9 +10,12 @@ import dan200.computercraft.api.turtle.ITurtleAccess;
|
||||
import dan200.computercraft.api.turtle.ITurtleCommand;
|
||||
import dan200.computercraft.api.turtle.TurtleAnimation;
|
||||
import dan200.computercraft.api.turtle.TurtleCommandResult;
|
||||
import dan200.computercraft.api.turtle.event.TurtleAction;
|
||||
import dan200.computercraft.api.turtle.event.TurtleActionEvent;
|
||||
import dan200.computercraft.shared.util.InventoryUtil;
|
||||
import net.minecraft.item.ItemStack;
|
||||
import net.minecraft.tileentity.TileEntityFurnace;
|
||||
import net.minecraftforge.common.MinecraftForge;
|
||||
|
||||
import javax.annotation.Nonnull;
|
||||
|
||||
@@ -71,6 +74,12 @@ public class TurtleRefuelCommand implements ITurtleCommand
|
||||
return TurtleCommandResult.failure( "Items not combustible" );
|
||||
}
|
||||
|
||||
TurtleActionEvent event = new TurtleActionEvent( turtle, TurtleAction.REFUEL );
|
||||
if( MinecraftForge.EVENT_BUS.post( event ) )
|
||||
{
|
||||
return TurtleCommandResult.failure( event.getFailureMessage() );
|
||||
}
|
||||
|
||||
if( !testOnly )
|
||||
{
|
||||
// Determine fuel to give and replacement item to leave behind
|
||||
|
||||
@@ -10,6 +10,7 @@ import dan200.computercraft.api.turtle.ITurtleAccess;
|
||||
import dan200.computercraft.api.turtle.ITurtleCommand;
|
||||
import dan200.computercraft.api.turtle.TurtleAnimation;
|
||||
import dan200.computercraft.api.turtle.TurtleCommandResult;
|
||||
import dan200.computercraft.api.turtle.event.TurtleInventoryEvent;
|
||||
import dan200.computercraft.shared.util.InventoryUtil;
|
||||
import dan200.computercraft.shared.util.WorldUtil;
|
||||
import net.minecraft.entity.Entity;
|
||||
@@ -19,6 +20,7 @@ import net.minecraft.util.EnumFacing;
|
||||
import net.minecraft.util.math.AxisAlignedBB;
|
||||
import net.minecraft.util.math.BlockPos;
|
||||
import net.minecraft.world.World;
|
||||
import net.minecraftforge.common.MinecraftForge;
|
||||
import net.minecraftforge.items.IItemHandler;
|
||||
|
||||
import javax.annotation.Nonnull;
|
||||
@@ -56,6 +58,15 @@ public class TurtleSuckCommand implements ITurtleCommand
|
||||
EnumFacing side = direction.getOpposite();
|
||||
|
||||
IItemHandler inventory = InventoryUtil.getInventory( world, newPosition, side );
|
||||
|
||||
// Fire the event, exiting if it is cancelled.
|
||||
TurtlePlayer player = TurtlePlaceCommand.createPlayer( turtle, oldPosition, direction );
|
||||
TurtleInventoryEvent.Suck event = new TurtleInventoryEvent.Suck( turtle, player, world, newPosition, inventory );
|
||||
if( MinecraftForge.EVENT_BUS.post( event ) )
|
||||
{
|
||||
return TurtleCommandResult.failure( event.getFailureMessage() );
|
||||
}
|
||||
|
||||
if( inventory != null )
|
||||
{
|
||||
// Take from inventory of thing in front
|
||||
|
||||
@@ -10,7 +10,10 @@ import dan200.computercraft.api.turtle.ITurtleAccess;
|
||||
import dan200.computercraft.api.turtle.ITurtleCommand;
|
||||
import dan200.computercraft.api.turtle.TurtleAnimation;
|
||||
import dan200.computercraft.api.turtle.TurtleCommandResult;
|
||||
import dan200.computercraft.api.turtle.event.TurtleAction;
|
||||
import dan200.computercraft.api.turtle.event.TurtleActionEvent;
|
||||
import dan200.computercraft.shared.util.DirectionUtil;
|
||||
import net.minecraftforge.common.MinecraftForge;
|
||||
|
||||
import javax.annotation.Nonnull;
|
||||
|
||||
@@ -27,6 +30,12 @@ public class TurtleTurnCommand implements ITurtleCommand
|
||||
@Override
|
||||
public TurtleCommandResult execute( @Nonnull ITurtleAccess turtle )
|
||||
{
|
||||
TurtleActionEvent event = new TurtleActionEvent( turtle, TurtleAction.TURN );
|
||||
if( MinecraftForge.EVENT_BUS.post( event ) )
|
||||
{
|
||||
return TurtleCommandResult.failure( event.getFailureMessage() );
|
||||
}
|
||||
|
||||
switch( m_direction )
|
||||
{
|
||||
case Left:
|
||||
|
||||
@@ -9,6 +9,8 @@ package dan200.computercraft.shared.turtle.upgrades;
|
||||
import dan200.computercraft.ComputerCraft;
|
||||
import dan200.computercraft.api.peripheral.IPeripheral;
|
||||
import dan200.computercraft.api.turtle.*;
|
||||
import dan200.computercraft.api.turtle.event.TurtleAttackEvent;
|
||||
import dan200.computercraft.api.turtle.event.TurtleBlockEvent;
|
||||
import dan200.computercraft.shared.turtle.core.TurtleBrain;
|
||||
import dan200.computercraft.shared.turtle.core.TurtlePlaceCommand;
|
||||
import dan200.computercraft.shared.turtle.core.TurtlePlayer;
|
||||
@@ -128,11 +130,11 @@ public class TurtleTool implements ITurtleUpgrade
|
||||
{
|
||||
case Attack:
|
||||
{
|
||||
return attack( turtle, direction );
|
||||
return attack( turtle, direction, side );
|
||||
}
|
||||
case Dig:
|
||||
{
|
||||
return dig( turtle, direction );
|
||||
return dig( turtle, direction, side );
|
||||
}
|
||||
default:
|
||||
{
|
||||
@@ -161,7 +163,7 @@ public class TurtleTool implements ITurtleUpgrade
|
||||
return 3.0f;
|
||||
}
|
||||
|
||||
private TurtleCommandResult attack( final ITurtleAccess turtle, EnumFacing direction )
|
||||
private TurtleCommandResult attack( final ITurtleAccess turtle, EnumFacing direction, TurtleSide side )
|
||||
{
|
||||
// Create a fake player, and orient it appropriately
|
||||
final World world = turtle.getWorld();
|
||||
@@ -178,8 +180,21 @@ public class TurtleTool implements ITurtleUpgrade
|
||||
ItemStack stackCopy = m_item.copy();
|
||||
turtlePlayer.loadInventory( stackCopy );
|
||||
|
||||
// Start claiming entity drops
|
||||
Entity hitEntity = hit.getKey();
|
||||
|
||||
// Fire several events to ensure we have permissions.
|
||||
if( MinecraftForge.EVENT_BUS.post( new AttackEntityEvent( turtlePlayer, hitEntity ) ) || !hitEntity.canBeAttackedWithItem() )
|
||||
{
|
||||
return TurtleCommandResult.failure( "Nothing to attack here" );
|
||||
}
|
||||
|
||||
TurtleAttackEvent attackEvent = new TurtleAttackEvent( turtle, turtlePlayer, hitEntity, this, side );
|
||||
if( MinecraftForge.EVENT_BUS.post( attackEvent ) )
|
||||
{
|
||||
return TurtleCommandResult.failure( attackEvent.getFailureMessage() );
|
||||
}
|
||||
|
||||
// Start claiming entity drops
|
||||
ComputerCraft.setEntityDropConsumer( hitEntity, ( entity, drop ) ->
|
||||
{
|
||||
ItemStack remainder = InventoryUtil.storeItems( drop, turtle.getItemHandler(), turtle.getSelectedSlot() );
|
||||
@@ -191,8 +206,7 @@ public class TurtleTool implements ITurtleUpgrade
|
||||
|
||||
// Attack the entity
|
||||
boolean attacked = false;
|
||||
if( hitEntity.canBeAttackedWithItem() && !hitEntity.hitByEntity( turtlePlayer )
|
||||
&& !MinecraftForge.EVENT_BUS.post( new AttackEntityEvent( turtlePlayer, hitEntity ) ) )
|
||||
if( !hitEntity.hitByEntity( turtlePlayer ) )
|
||||
{
|
||||
float damage = (float)turtlePlayer.getEntityAttribute( SharedMonsterAttributes.ATTACK_DAMAGE ).getAttributeValue();
|
||||
damage *= getDamageMultiplier();
|
||||
@@ -233,7 +247,7 @@ public class TurtleTool implements ITurtleUpgrade
|
||||
return TurtleCommandResult.failure( "Nothing to attack here" );
|
||||
}
|
||||
|
||||
private TurtleCommandResult dig( ITurtleAccess turtle, EnumFacing direction )
|
||||
private TurtleCommandResult dig( ITurtleAccess turtle, EnumFacing direction, TurtleSide side )
|
||||
{
|
||||
// Get ready to dig
|
||||
World world = turtle.getWorld();
|
||||
@@ -266,6 +280,13 @@ public class TurtleTool implements ITurtleUpgrade
|
||||
return TurtleCommandResult.failure( "Unbreakable block detected" );
|
||||
}
|
||||
|
||||
// Fire the dig event, checking whether it was cancelled.
|
||||
TurtleBlockEvent.Dig digEvent = new TurtleBlockEvent.Dig( turtle, turtlePlayer, world, newPosition, world.getBlockState( newPosition ), this, side );
|
||||
if( MinecraftForge.EVENT_BUS.post( digEvent ) )
|
||||
{
|
||||
return TurtleCommandResult.failure( digEvent.getFailureMessage() );
|
||||
}
|
||||
|
||||
// Consume the items the block drops
|
||||
if( canHarvestBlock( world, newPosition ) )
|
||||
{
|
||||
|
||||
Reference in New Issue
Block a user