All Downloads are FREE. Search and download functionalities are using the official Maven repository.

mmb.content.modular.Slot Maven / Gradle / Ivy

Go to download

Dependency for the MultiMachineBuilder, a voxel game about building an industrial empire in a finite world. THIS RELEASE IS NOT PLAYABLE. To play the game, donwload from >ITCH.IO LINK HERE< or >GH releases link here<

There is a newer version: 0.6
Show newest version
/**
 * 
 */
package mmb.content.modular;

import mmb.NN;
import mmb.Nil;
import mmb.content.modular.BlockModule.BlockModuleParams;
import mmb.data.variables.ListenableValue;
import mmb.engine.debug.Debugger;
import mmb.engine.inv.storage.BaseSingleItemInventory;
import mmb.engine.item.ItemEntry;
import mmb.engine.rotate.Side;
import mmb.engine.worlds.world.World;

/**
 * A type-checked slot for a module.
 * The class should be extended to add requested functionality.
 * For best results, use {@link ModuleSlot} for modules, or {@link CoreSlot} for the core
 * @author oskar
 * @param  type of values
 */
public class Slot extends ListenableValue<@Nil T>{
	@NN private static final Debugger debug = new Debugger("MODULAR SLOTS");
	/** The type of the slots */
	@NN public final Class type;
	/**
	 * Sets a value if it extends the expected type
	 * @param value
	 * @return does the input have a correct type
	 */
	@SuppressWarnings("unchecked")
	public boolean setto(@Nil Object value) {
		if(!test(value)) return false;
		set((T) value);
		return true;
	}
	/**
	 * Tests the type of the input
	 * @param totest value to test
	 * @return does the input have a correct type
	 */
	public final boolean test(@Nil Object totest) {
		return totest == null || type.isInstance(totest);
	}
	/**
	 * Creates a slot
	 * @param type type of values;
	 */
	public Slot(Class type) {
		super(null);
		listenadd(this::addNew);
		listenrem(this::removeOld);
		this.type = type;
	}
	/**
	 * Called when an old value is removed
	 * @param module removed module
	 */
	protected void removeOld(@Nil T module) {
		//to be overridden
	}
	/**
	 * Called when a new value is added
	 * @param module
	 */
	protected void addNew(@Nil T module) {
		//to be overridden
	}
		
	/**
	 * An implementation of a slot for block modules
	 * @author oskar
	 * @param  type of the hosting block
	 * @param  type of the block module
	 */
	public static class ModuleSlot, Tmodule extends BlockModule> extends Slot{
		/** The logical side on which the slot is located */
		@NN public final Side logicalSide;
		/** The owner of this slot */
		@NN public final Tblock block;
		/**
		 * Creates a module slot
		 * @param logicalSide the logical side (before rotation)
		 * @param block block which hosts this slot
		 * @param type type of values
		 */
		public ModuleSlot(Side logicalSide, Tblock block, Class type) {
			super(type);
			this.block = block;
			this.logicalSide = logicalSide;
		}

		@Override
		protected void removeOld(@Nil Tmodule module) {
			if(module == null) return;
			//When killed, drop items
			//Find where to drop
			World w = block.owner();
			int x = block.posX();
			int y = block.posY();
			//Drop the items
			debug.printl("Dropping items");
			Side realSide = block.getChirotation().apply(logicalSide);
			BlockModuleParams bmp = new BlockModuleParams<>(block, logicalSide, realSide);
			w.dropChance(module.dropItems(), x, y);
			module.onBroken(bmp);
		}

		@Override
		protected void addNew(@Nil Tmodule module) {
			Side realSide = block.getChirotation().apply(logicalSide);
			BlockModuleParams bmp = new BlockModuleParams<>(block, logicalSide, realSide);
			if(module != null) module.onAdded(bmp);
		}
	}
	/**
	 * An implementation of a slot for block modules
	 * @author oskar
	 * @param  type of the hosting block
	 * @param  type of the block core
	 */
	public static class CoreSlot, Tcore extends BlockCore> extends Slot{
		/** The owner of this slot */
		@NN public final Tblock block;
		/**
		 * Creates a core slot
		 * @param block block which hosts this slot
		 * @param type type of values
		 */
		public CoreSlot(Tblock block, Class type) {
			super(type);
			this.block = block;
		}

		@Override
		protected void removeOld(@Nil Tcore module) {
			if(module == null) return;
			//When killed, drop items
			//Find where to drop
			World w = block.owner();
			int x = block.posX();
			int y = block.posY();
			//Drop the items
			debug.printl("Dropping items");
			w.dropChance(module.dropItems(), x, y);
			module.onBroken(block);
		}

		@Override
		protected void addNew(@Nil Tcore module) {
			if(module != null) module.onAdded(block);
		}
	}
	/**
	 * An implementation for the {@link ModularBlock#slotInternal(Side)} method with slots on all sides
	 * @author oskar
	 * @param  type of the hosting block
	 * @param  type of the block modules
	 */
	public static class SidedSlotHelper, Tmodule extends BlockModule>{
		/** The upper slot */
		@NN public final ModuleSlot U;
		/** The lower slot */
		@NN public final ModuleSlot D;
		/** The left slot */
		@NN public final ModuleSlot L;
		/** The right slot */
		@NN public final ModuleSlot R;
		/**
		 * Creates a sided slot helper
		 * @param cls type of the modules
		 * @param block host block
		 */
		public SidedSlotHelper(Class cls, Tblock block) {
			U = new ModuleSlot<>(Side.U, block, cls);
			D = new ModuleSlot<>(Side.D, block, cls);
			L = new ModuleSlot<>(Side.L, block, cls);
			R = new ModuleSlot<>(Side.R, block, cls);
		}
		/**
		 * Gets a slot on a given side
		 * @param s side to get from
		 * @return a module slot, or null if side is a corner or null
		 */
		@Nil public ModuleSlot get(Side s){
			switch(s) {
			case U: return U;
			case D: return D;
			case L: return L;
			case R: return R;
			default: return null;
			}
		}
	}
	/**
	 * An inventory implementation using a slot
	 * @author oskar
	 * @param  type of items in the slot
	 */
	public static class SlotInv<@Nil Titem extends ItemEntry> extends BaseSingleItemInventory{
		/** The slot used by the inventory */
		@NN public final Slot slot;
		/**
		 * Creates a slot-based inventory
		 * @param slot slot to use
		 */
		public SlotInv(Slot slot) {
			this.slot = slot;
			setCapacity(Double.POSITIVE_INFINITY);
		}
		@Override
		public ItemEntry getContents() {
			return slot.get();
		}
		@Override
		public boolean setContents(@Nil ItemEntry contents) {
			return slot.setto(contents);
		}
		@Override
		public boolean test(ItemEntry e) {
			return slot.test(e);
		}
	}
	
}




© 2015 - 2024 Weber Informatics LLC | Privacy Policy