2021-05-17 03:02:24 +08:00
package com.gtnewhorizon.structurelib.structure ;
2022-08-08 17:40:12 +08:00
import static com.gtnewhorizon.structurelib.StructureLib.LOGGER ;
import static com.gtnewhorizon.structurelib.StructureLib.PANIC_MODE ;
import com.gtnewhorizon.structurelib.StructureLibAPI ;
import java.util.function.Consumer ;
2022-08-30 23:27:18 +08:00
import net.minecraft.block.Block ;
2022-09-11 02:54:11 +08:00
import net.minecraft.entity.player.EntityPlayer ;
2022-08-08 17:40:12 +08:00
import net.minecraft.entity.player.EntityPlayerMP ;
2021-05-17 03:02:24 +08:00
import net.minecraft.item.ItemStack ;
2022-08-08 17:40:12 +08:00
import net.minecraft.util.IChatComponent ;
2021-05-17 03:02:24 +08:00
import net.minecraft.world.World ;
/**
* Use StructureUtility to instantiate
*/
public interface IStructureElement < T > {
2022-07-08 17:14:18 +08:00
boolean check ( T t , World world , int x , int y , int z );
2021-05-17 03:02:24 +08:00
2022-07-08 17:14:18 +08:00
boolean spawnHint ( T t , World world , int x , int y , int z , ItemStack trigger );
2021-05-17 03:02:24 +08:00
2022-07-08 17:14:18 +08:00
boolean placeBlock ( T t , World world , int x , int y , int z , ItemStack trigger );
2021-05-17 03:02:24 +08:00
2022-08-08 17:40:12 +08:00
/**
* Try place the block by taking resource from given IItemSource.
2022-08-30 23:27:18 +08:00
* <p>
2022-09-11 02:54:11 +08:00
* You might want to use {@link StructureUtility#survivalPlaceBlock(Block, int, World, int, int, int, IItemSource, net.minecraft.entity.player.EntityPlayer)}
2022-08-30 23:27:18 +08:00
* or its overloads to implement this.
2022-08-08 17:40:12 +08:00
*
2022-08-30 23:27:18 +08:00
* @param trigger trigger item
2022-08-08 17:40:12 +08:00
* @param s drain resources from this place
2022-08-30 23:27:18 +08:00
* @param actor source of action. for very critical errors you can also just send the error messages here, bypassing
* any filter that chatter might have.
* @param chatter send error messages here. Caller will choose an appropriate way to forward it to player if the
* other fallbacks also fails.
2022-09-11 02:54:11 +08:00
* @deprecated caller should call the non deprecated overload. implementor for reusable {@link IStructureElement}
* should still implement this. implementor for private implementations can freely ignore this as long as you know
* the caller will not call this overload.
2022-08-08 17:40:12 +08:00
*/
2022-09-11 02:54:11 +08:00
@Deprecated
2022-08-08 17:40:12 +08:00
default PlaceResult survivalPlaceBlock (
T t ,
World world ,
int x ,
int y ,
int z ,
ItemStack trigger ,
IItemSource s ,
EntityPlayerMP actor ,
Consumer < IChatComponent > chatter ) {
if ( PANIC_MODE ) throw new RuntimeException ( "Panic Tripwire hit" );
2022-08-30 23:27:18 +08:00
if ( StructureLibAPI . isDebugEnabled ())
2022-08-08 17:40:12 +08:00
LOGGER . error (
"Default implementation of survivalPlaceBlock hit! Things aren't going to work well! IStructureElement class: {}" ,
getClass (). getName ());
if ( ! StructureLibAPI . isBlockTriviallyReplaceable ( world , x , y , z , actor )) return PlaceResult . REJECT ;
return PlaceResult . SKIP ;
}
2022-09-11 02:54:11 +08:00
/**
* Try place the block by taking resource from given IItemSource.
* <p>
* You might want to use {@link StructureUtility#survivalPlaceBlock(Block, int, World, int, int, int, IItemSource, net.minecraft.entity.player.EntityPlayer)}
* or its overloads to implement this.
*
* @param trigger trigger item
* @param env autoplacing environment
*/
default PlaceResult survivalPlaceBlock (
T t , World world , int x , int y , int z , ItemStack trigger , AutoPlaceEnvironment env ) {
EntityPlayer actor = env . getActor ();
if ( actor instanceof EntityPlayerMP )
return survivalPlaceBlock (
t , world , x , y , z , trigger , env . getSource (), ( EntityPlayerMP ) actor , env . getChatter ());
if ( PANIC_MODE ) throw new RuntimeException ( "Panic Tripwire hit" );
if ( StructureLibAPI . isDebugEnabled ())
LOGGER . info (
"Fallback shim code of survivalPlaceBlock hit! Things aren't going to work well! IStructureElement class: {}" ,
getClass (). getName ());
return PlaceResult . SKIP ;
}
2022-08-08 17:40:12 +08:00
/**
* Forget the messed up class dependency graph for now. this is just so convenient.
*/
default IStructureElementNoPlacement < T > noPlacement () {
return new IStructureElementNoPlacement < T > () {
@Override
public boolean check ( T t , World world , int x , int y , int z ) {
return IStructureElement . this . check ( t , world , x , y , z );
}
@Override
public boolean spawnHint ( T t , World world , int x , int y , int z , ItemStack trigger ) {
return IStructureElement . this . spawnHint ( t , world , x , y , z , trigger );
}
};
}
2022-07-08 17:14:18 +08:00
default int getStepA () {
return 1 ;
}
2021-05-17 03:02:24 +08:00
2022-07-08 17:14:18 +08:00
default int getStepB () {
return 0 ;
}
2021-05-17 03:02:24 +08:00
2022-07-08 17:14:18 +08:00
default int getStepC () {
return 0 ;
}
2021-05-17 03:02:24 +08:00
2022-07-08 17:14:18 +08:00
default boolean resetA () {
return false ;
}
2021-05-17 03:02:24 +08:00
2022-07-08 17:14:18 +08:00
default boolean resetB () {
return false ;
}
2021-05-17 03:02:24 +08:00
2022-07-08 17:14:18 +08:00
default boolean resetC () {
return false ;
}
2021-05-17 03:02:24 +08:00
2022-07-08 17:14:18 +08:00
default boolean isNavigating () {
return false ;
}
2022-08-08 17:40:12 +08:00
enum PlaceResult {
/**
* This element either exists already, or does not yet have an implementation for survivalPlaceBlock, or
* some other unforeseen situations.
2022-08-24 12:36:48 +08:00
* TODO this definition doesn't seem right. Should we separate SKIP from EXISTS, or SKIP from ERROR?
2022-08-08 17:40:12 +08:00
*/
SKIP ,
/**
* This element's space is occupied by other stuff and require player attention, or player missing required resource,
* or the block cannot be placed due to obscure mechanisms, or some other unforeseen situations.
*/
REJECT ,
/**
* Autoplace cannot proceed within this tick. To proceed further would require stopping the placement and wait for next round.
*/
STOP ,
/**
* Element placed successfully.
*/
ACCEPT ,
/**
* Combination of ACCEPT and STOP.
2022-08-30 23:27:18 +08:00
* <p>
2022-08-08 17:40:12 +08:00
* Element placed successfully. To proceed further would require stopping the placement and wait for next round.
*/
ACCEPT_STOP ;
}
2021-05-17 03:02:24 +08:00
}