Merge pull request #2770 from LeoDog896/autotiler

Autotiler docs and cleanup
This commit is contained in:
Anuken 2020-09-30 10:49:42 -04:00 committed by GitHub
commit b38e7f66ad
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
4 changed files with 74 additions and 12 deletions

View File

@ -94,3 +94,4 @@ The Slaylord
ThePlayerA
YellOw139
PetrGasparik
LeoDog896

View File

@ -14,20 +14,40 @@ import java.util.*;
//TODO documentation
public interface Autotiler{
//holds some static temporary variables, required due to some RoboVM bugs
/**
* Holds some static temporary variables, required due to some RoboVM bugs
*/
class AutotilerHolder{
static final int[] blendresult = new int[5];
static final BuildPlan[] directionals = new BuildPlan[4];
}
/** slices a texture region:
* mode == 0 -> no slice
* mode == 1 -> bottom
* mode == 2 -> top */
default TextureRegion sliced(TextureRegion input, int mode){
return mode == 0 ? input : mode == 1 ? botHalf(input) : topHalf(input);
/**
* The mode to slice a texture at.
*/
enum SliceMode{
noSlice,
bottom,
top
}
/**
* Slices a texture region depending on the SliceMode paramater
*
* @param input The TextureRegion to be sliced
* @param mode The SliceMode to be applied
* @return The sliced texture
*/
default TextureRegion sliced(TextureRegion input, SliceMode mode){
return mode == SliceMode.noSlice ? input : mode == SliceMode.bottom ? botHalf(input) : topHalf(input);
}
/**
* Get the top half of a texture
*
* @param input The TextureRegion to slice
* @return The top half of the texture
*/
default TextureRegion topHalf(TextureRegion input){
TextureRegion region = Tmp.tr1;
region.set(input);
@ -35,6 +55,12 @@ public interface Autotiler{
return region;
}
/**
* Get the buttom half of a texture
*
* @param input The TextureRegion to slice
* @return The buttom half of the texture
*/
default TextureRegion botHalf(TextureRegion input){
TextureRegion region = Tmp.tr1;
region.set(input);
@ -82,6 +108,8 @@ public interface Autotiler{
int[] blendresult = AutotilerHolder.blendresult;
blendresult[0] = 0;
blendresult[1] = blendresult[2] = 1;
// TODO code refactoring maybe?
int num =
(blends(tile, rotation, directional, 2, world) && blends(tile, rotation, directional, 1, world) && blends(tile, rotation, directional, 3, world)) ? 0 :
(blends(tile, rotation, directional, 1, world) && blends(tile, rotation, directional, 3, world)) ? 1 :
@ -92,6 +120,8 @@ public interface Autotiler{
-1;
transformCase(num, blendresult);
// Calculate bitmask for direction.
blendresult[3] = 0;
for(int i = 0; i < 4; i++){
@ -100,6 +130,8 @@ public interface Autotiler{
}
}
// Calculate direction for non-square sprites.
blendresult[4] = 0;
for(int i = 0; i < 4; i++){
@ -112,6 +144,12 @@ public interface Autotiler{
return blendresult;
}
/**
* Transforms the autotiler setting the connection and the y-scale
*
* @param num The number to use to transform the array
* @param bits The blending value array
*/
default void transformCase(int num, int[] bits){
if(num == 0){
bits[0] = 3;
@ -130,6 +168,18 @@ public interface Autotiler{
}
}
/**
* Check if a position is facing the secondary position at a rotation
*
* @param x The x coordinate of position 1
* @param y The y coordinate of position 1
* @param rotation The rotation of the tile on (x, y)
*
* @param x2 The x coordinate of position 2
* @param y2 The y coordinate of position 2
*
* @return If position 1 is facing position 2 at a certain angle
*/
default boolean facing(int x, int y, int rotation, int x2, int y2){
return Point2.equals(x + Geometry.d4(rotation).x,y + Geometry.d4(rotation).y, x2, y2);
}
@ -145,6 +195,8 @@ public interface Autotiler{
return checkWorld && blends(tile, rotation, direction);
}
// TODO docs -- use for direction?
default boolean blends(Tile tile, int rotation, int direction){
Building other = tile.getNearbyEntity(Mathf.mod(rotation - direction, 4));
return other != null && other.team == tile.team() && blends(tile, rotation, other.tileX(), other.tileY(), other.rotation, other.block);
@ -168,7 +220,16 @@ public interface Autotiler{
|| (!otherblock.rotatedOutput(otherx, othery) || Point2.equals(otherx + Geometry.d4(otherrot).x, othery + Geometry.d4(otherrot).y, tile.x, tile.y)));
}
/** @return whether this tile is looking at the other tile. */
/**
* Check if a position is facing the secondary position at a rotation
*
* @param tile The origin tile that is or is not facing the destinated `otherblock`
* @param rotation The rotation of the tile on (x, y)
*
* @param otherx The x coordinate of position 2
* @param othery The y coordinate of position 2
* @return whether this tile is looking at the other tile.
*/
default boolean lookingAt(Tile tile, int rotation, int otherx, int othery, Block otherblock){
Tile facing = Edges.getFacingEdge(otherblock, otherx, othery, tile);
return facing != null &&

View File

@ -124,7 +124,7 @@ public class Conveyor extends Block implements Autotiler{
int dir = rotation - i;
float rot = i == 0 ? rotation * 90 : (dir)*90;
Draw.rect(sliced(regions[0][frame], i != 0 ? 1 : 2), x + Geometry.d4x(dir) * tilesize*0.75f, y + Geometry.d4y(dir) * tilesize*0.75f, rot);
Draw.rect(sliced(regions[0][frame], i != 0 ? SliceMode.bottom : SliceMode.top), x + Geometry.d4x(dir) * tilesize*0.75f, y + Geometry.d4y(dir) * tilesize*0.75f, rot);
}
}

View File

@ -88,18 +88,18 @@ public class Conduit extends LiquidBlock implements Autotiler{
if((blending & (1 << i)) != 0){
int dir = r - i;
float rot = i == 0 ? rotation : (dir)*90;
drawAt(x + Geometry.d4x(dir) * tilesize*0.75f, y + Geometry.d4y(dir) * tilesize*0.75f, 0, rot, i != 0 ? 1 : 2);
drawAt(x + Geometry.d4x(dir) * tilesize*0.75f, y + Geometry.d4y(dir) * tilesize*0.75f, 0, rot, i != 0 ? SliceMode.bottom : SliceMode.top);
}
}
Draw.z(Layer.block);
Draw.scl(xscl, yscl);
drawAt(x, y, blendbits, rotation, 0);
drawAt(x, y, blendbits, rotation, SliceMode.noSlice);
Draw.reset();
}
protected void drawAt(float x, float y, int bits, float rotation, int slice){
protected void drawAt(float x, float y, int bits, float rotation, SliceMode slice){
Draw.color(botColor);
Draw.rect(sliced(botRegions[bits], slice), x, y, rotation);