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

mmb.engine.block.BlockEntry 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.engine.block;

import java.awt.Graphics;

import org.joml.Vector2d;

import mmb.NN;
import mmb.Nil;
import mmb.beans.Saver;
import mmb.content.electric.Electricity;
import mmb.content.ppipe.PipeTunnelEntry;
import mmb.engine.inv.Inventory;
import mmb.engine.inv.NoSuchInventory;
import mmb.engine.inv.io.InventoryReader;
import mmb.engine.inv.io.InventoryWriter;
import mmb.engine.rotate.Chiral;
import mmb.engine.rotate.ChiralRotation;
import mmb.engine.rotate.Chirality;
import mmb.engine.rotate.Rotable;
import mmb.engine.rotate.Rotation;
import mmb.engine.rotate.Side;
import mmb.engine.texture.BlockDrawer;
import mmb.engine.worlds.world.Player;
import mmb.engine.worlds.world.World;

/**
 * @author oskar
 * The following methods can be overridden:
 * provideSignal - 
 */
public interface BlockEntry extends Saver, Rotable, Chiral {	
	/** @return the block type */
	@NN public BlockType type();
	/**
	 * @param type block type to check
	 * @return does given type match actual type?
	 */
	public default boolean typeof(BlockType type) {
		return type == type();
	}
	
	//Block I/O
	/**
	 * Gets the electrical connection on this block
	 * @param s
	 * @return the electrical connection on given side.
	 */
	@Nil public default Electricity getElectricalConnection(Side s) {
		return null;
	}
	/**
	 * @param s side, from which to get signal
	 * @return the WireWorld signal
	 */
	public default boolean provideSignal(Side s) {
		return false;
	}
	/**
	 * @param s side, from which to get inventory
	 * @return inventory at given side
	 */
	@NN public default Inventory getInventory(Side s) {
		return NoSuchInventory.INSTANCE;
	}
	/**
	 * @param s side, from which to get output
	 * @return inventory reader at given side
	 */
	@NN public default InventoryReader getOutput(Side s) {
		return getInventory(s).createReader();
	}
	/**
	 * @param s side, from which to get input
	 * @return inventory writer at given side
	 */
	@NN public default InventoryWriter getInput(Side s) {
		return getInventory(s).createWriter();
	}
	
	//Block events
	/**
	 * Moves this block to a new map
	 * @param map new map (can be the same, or null if block goes off map)
	 * @param x X coordinate on a new map
	 * @param y Y coordinate on a new map
	 * @throws IllegalStateException if given map/position combination is not surface
	 */
	public void resetMap(@Nil World map, int x, int y); //should only be called by World
	/**
	 * Called when world is initialized
	 * 
Exception handling: If exception is thrown by this method, the block is not properly initialized * @param map world, which is initialized * @param x X coordinate of the block * @param y Y coordinate of the block */ public default void onStartup(World map, int x, int y) { //optional } /** * Called just after world is initialized *
Exception handling: If exception is thrown by this method, the block is not properly initialized * @param map world, which is initialized * @param x X coordinate of the block * @param y Y coordinate of the block */ public default void postLoad(World map, int x, int y) { //optional } /** * Called when block is placed *
Exception handling: If exception is thrown by this method, the block is not placed * @param map world, in which the block is placed * @param x X coordinate of the block * @param y Y cordinate of the block */ public default void onPlace(World map, int x, int y) { //optional } /** * Called when block is broken *
Exception handling: If exception is thrown by this method, the block is not broken * @param map world, in which block is broken * @param x X coordinate of the block * @param y Y cordinate of the block */ public default void onBreak(World map, int x, int y) { //optional } /** * Called when world is closed *
Exception handling: If exception is thrown by this method, the block is not properly closed * @param map world, which is shutting down */ public default void onShutdown(World map) { //optional } /** * Renders a block * @param x left X coordinate * @param y upper Y coordinate * @param g graphics context * @param side side size */ public default void render(int x, int y, Graphics g, int side) { BlockDrawer drawer = type().getTexture(); drawer.draw(this, x, y, g, side); } /** * Prints debug information for use in debug menu * @param sb string builder */ public default void debug(StringBuilder sb) { //unused } /** * Creates a block-wise copy of this block entry. * The returned block entry may have position data attached, * or it may be identical. * @return a copy of this block * @implSpec This method must not throw any exceptions * @apiNote Used to copy blocks by world editing tools */ @NN public BlockEntry blockCopy(); //Rotations - rotary /** * Checks if given block supports rotations * @return is given block rotable? */ public default boolean isRotary() { return false; } @Override default void setRotation(Rotation rotation) { //does nothing } @Override @NN default Rotation getRotation() { return Rotation.N; } /** Rotates the block clockwise */ public default void wrenchCW() { setRotation(getRotation().cw()); } /** Rotates the block counter-clockwise */ public default void wrenchCCW() { setRotation(getRotation().cw()); } /** * Wrenches the block in chirality's "right" direction * @param chiral chirality to use */ public default void wrenchRight(Chirality chiral) { setRotation(chiral.right(getRotation())); } /** * Wrenches the block in chirality's "left" direction * @param chiral chirality to use */ public default void wrenchLeft(Chirality chiral) { setRotation(chiral.left(getRotation())); } //Rotations - chiral /** * Checks if given block is chiral * @return is given block chiral? */ public default boolean isChiral() { return false; } @Override @NN default Chirality getChirality() { return Chirality.R; } @Override default void setChirality(Chirality chirality) { //does nothing } /** * Reverses the chirality of this block */ default void flip() { setChirality(getChirality().reverse()); } //Rotation - chirotation default void setChirotation(ChiralRotation rotation) { setRotation(rotation.rotation); setChirality(rotation.chirality); } /** @return chirality and rotation of this block together */ @NN default ChiralRotation getChirotation() { return ChiralRotation.of(getRotation(), getChirality()); } /** Flips on | plane */ public default void flipH() { setChirotation(getChirotation().flipH()); } /** Flips on ― plane */ public default void flipV() { setChirotation(getChirotation().flipV()); } /** Flips on / plane */ public default void flipNE() { setChirotation(getChirotation().flipNE()); } /** Flips on \ plane*/ public default void flipNW() { setChirotation(getChirotation().flipNW()); } //Player collision int FLAGS_COLLIDE_LEFT = 1; int FLAGS_COLLIDE_RIGHT = 2; int FLAGS_COLLIDE_UP = 4; int FLAGS_COLLIDE_DOWN = 8; int NO_COLLISION = 0; int COLLIDE_ALL = 15; /** * Runs on player collision * @param blockX the block's X position * @param blockY the block's Y position * @param world the world, in which the player resides * @param player the player which collides with the block */ public default void onPlayerCollide(int blockX, int blockY, World world, Player player) { if(!isSurface()) displaceFrom(blockX, blockY, blockX+1.0, blockY+1.0, player, true); } /** * @return is this block entry surface? */ public default boolean isSurface() { return type().isSurface(); } /** * @param x1 * @param y1 * @param x2 * @param y2 * @param player player to displace * @param move TODO should player be moved * @return rectangle collision: 0 if none, 1 if horizontal, 2 if vertical */ static int displaceFrom(double x1, double y1, double x2, double y2, Player player, boolean move) { //Displace on X axis double px1 = player.pos.x-0.3; double py1 = player.pos.y-0.3; double px2 = player.pos.x+0.3; double py2 = player.pos.y+0.3; Vector2d offset = new Vector2d(); int coll = displace(x1, y1, x2, y2, px1, py1, px2, py2, offset); if(move) { player.pos.add(offset); if(coll == 1) { player.speed.x = 0; } if(coll == 2) { player.speed.y = 0; } } return coll; } /** * @param cx1 first X coordinate of the stationary rectangle * @param cy1 first Y coordinate of the stationary rectangle * @param cx2 second X coordinate of the stationary rectangle * @param cy2 second Y coordinate of the stationary rectangle * @param px1 first X coordinate of the movable rectangle * @param py1 first Y coordinate of the movable rectangle * @param px2 second X coordinate of the movable rectangle * @param py2 second Y coordinate of the movable rectangle * @param out the vector, which stores offset * @return rectangle collision: 0 if none, 1 if horizontal, 2 if vertical */ static int displace(double cx1, double cy1, double cx2, double cy2, double px1, double py1, double px2, double py2, Vector2d out) { double radCX = (cx2-cx1)/2; double centerCX = (cx2+cx1)/2; double radPX = (px2-px1)/2; double centerPX = (px2+px1)/2; double distX = Math.abs(centerPX-centerCX); double infringeX = (radPX+radCX) - distX; boolean colx = infringeX > 0; double radCY = (cy2-cy1)/2; double centerCY = (cy2+cy1)/2; double radPY = (py2-py1)/2; double centerPY = (py2+py1)/2; double distY = Math.abs(centerPY-centerCY); double infringeY = (radPY+radCY) - distY; boolean coly = infringeY > 0; boolean collide = colx && coly; if(!collide) return 0; if(infringeX < infringeY) { //displace horizontally if(centerPX > centerCX) { //displace right out.x = infringeX; }else{ //displace left out.x = -infringeX; } return 1; //not working as expected } //displace vertically if(centerPY > centerCY) { //displace down out.y = infringeY; }else{ //displace up out.y = -infringeY; } return 2; } //Pipe tunnels /** * Gets the pipe tunnel at given side * @param s the side from which pipe enters * @return the pipe tunnel entry for this pipe, or null if none */ public default PipeTunnelEntry getPipeTunnel(Side s) { return null; } }




© 2015 - 2024 Weber Informatics LLC | Privacy Policy