/**
* THIS IS CREATED BY tom_mai78101. PLEASE GIVE CREDIT FOR WORKING ON A CLONE.
*
* ALL WORKS COPYRIGHTED TO The Pokémon Company and Nintendo. I REPEAT, THIS IS A CLONE.
*
* YOU MAY NOT SELL COMMERCIALLY, OR YOU WILL BE PROSECUTED BY The Pokémon Company AND Nintendo.
*
* THE CREATOR IS NOT LIABLE FOR ANY DAMAGES DONE. FOLLOW LOCAL LAWS, BE RESPECTFUL, AND HAVE A GOOD DAY!
* */
package level;
import resources.Art;
import screen.BaseBitmap;
public class PixelData {
// This class contains all of the area's pixel color, pixel's properties, pixel flags to check, etc.
// This object will be loaded along with other PixelData objects when loading an area.
/*
* Pixel data types: (Including alpha values)
*
* 0xFF00FF00: Flat grass (Can be walked, no Pokémon) 0xFF0000DD: Ledges Horizontal 0xFF0000AA: Small tree
*
* Anything else: Flat grass.
*/
// This is also the ID number for the pixel.
private int color;
// If false, it's an obstacle.
private boolean[] facingsBlocked = new boolean[4];
public int xPosition;
public int yPosition;
// This represents the art resource this PixelData object is representing.
// This can also give flexibility when it comes to puzzle-themed areas.
// Now adding animations.
public BaseBitmap[] bitmap;
public BaseBitmap[] biomeBitmap;
public int bitmapTick;
public int biomeBitmapTick;
// This can also be "isWayPoint".
private boolean isWarpZone;
private int targetArea;
private int targetSector;
private int groundHeight;
private boolean triggerFlag;
private int targetMovementScriptID;
public PixelData(int pixel, int x, int y) {
this.xPosition = x;
this.yPosition = y;
this.color = pixel;
this.targetArea = -1;
this.targetSector = -1;
this.groundHeight = 0; // Default
this.bitmapTick = 0;
this.biomeBitmapTick = 0;
this.triggerFlag = false;
this.targetMovementScriptID = 0;
int alpha = (pixel >> 24) & 0xFF;
int red = (pixel >> 16) & 0xFF;
int green = (pixel >> 8) & 0xFF;
int blue = pixel & 0xFF;
setProperties(alpha, red, green, blue);
prepareBitmap(alpha, red, green, blue);
}
public void enableTrigger() {
this.triggerFlag = true;
}
public void disableTrigger() {
this.triggerFlag = false;
}
public boolean hasTriggerEvent() {
return this.triggerFlag;
}
public int getTargetScriptID() {
return this.targetMovementScriptID;
}
public void disableWarpZone() {
this.isWarpZone = false;
}
public void enableWarpZone() {
this.isWarpZone = true;
}
public boolean isWarpZoneEnabled() {
return this.isWarpZone;
}
/**
* Sets the bitmap tile the pixel data is representing.
*
* <p>
* When setting the bitmap, first it must set the bitmap to something other than null. Since the bitmap variable holds an array, it takes in at least 1 bitmap pre-loaded by the Art class. Then, once the bitmap is set, it must break all the way outside of the nested switch conditions, otherwise,
* setting bitmaps will overwrite correct data with incorrect data.
*
* <p>
* If the bitmap stays null, the bitmap will then be set to "NO PNG" error bitmap, which when loaded into the game, the game will not crash, and the developers/players can tell where the bitmap loading has gone wrong.
*
* <p>
* If the bitmap is an animated bitmap, the Art class will load the animated bitmap into an array. The next step would be to just pass the array to this bitmap.
*
* @param alpha
* The alpha value of the pixel data's color.
* @param red
* The red value of the pixel data's color.
* @param green
* The green value of the pixel data's color.
* @param blue
* The blue value of the pixel data's color.
* @return Nothing.
* */
public void prepareBitmap(int alpha, int red, int green, int blue) {
switch (alpha) {
case 0x01: // Path
this.bitmap = new BaseBitmap[1];
// Tile Type
switch (red) {
case 0x00: // Grass Path
this.bitmap[0] = Art.grass;
break;
case 0x01: // Mountain Ground Path
this.bitmap[0] = Art.mt_ground;
break;
case 0x02: // Road Path
this.bitmap[0] = Art.path;
break;
case 0x03: // Hardwood Floor (Indoors)
this.bitmap[0] = Art.hardwood_indoors;
break;
case 0x04: // Tatami Floor Type 1 (Indoors)
this.bitmap[0] = Art.tatami_1_indoors;
break;
case 0x05: // Tatami Floor Type 2 (Indoors)
this.bitmap[0] = Art.tatami_2_indoors;
break;
default:
break;
}
switch (green) { // Area Type
case 0x00:
this.biomeBitmap = new BaseBitmap[1];
this.biomeBitmap[0] = Art.grass; // Forest
break;
case 0x01:
// TODO: Change this biome bitmap to something that represents the city even more.
this.biomeBitmap = new BaseBitmap[1];
this.biomeBitmap[0] = Art.path; // City
case 0x02:
this.biomeBitmap = new BaseBitmap[1];
this.biomeBitmap[0] = Art.mt_ground; // Mountain
break;
case 0x03:
this.biomeBitmap = new BaseBitmap[1];
this.biomeBitmap[0] = Art.water[0];
// TODO: Add more area type biome bitmaps here to the Path. (Refer to documentation.)
default:
break;
}
break;
case 0x02: // Ledge
{
// TODO: Add biome bitmaps to ledge.
this.bitmap = new BaseBitmap[1];
switch (red) {
case 0x00: // Bottom
this.bitmap[0] = Art.ledge_bottom;
break;
case 0x01: // Bottom left
this.bitmap[0] = Art.ledge_bottom_left;
break;
case 0x02: // Right
this.bitmap[0] = Art.ledge_left;
break;
case 0x03: // Top Left
this.bitmap[0] = Art.ledge_top_left;
break;
case 0x04: // Top
this.bitmap[0] = Art.ledge_top;
break;
case 0x05: // Top Right
this.bitmap[0] = Art.ledge_top_right;
break;
case 0x06: // Left
this.bitmap[0] = Art.ledge_right;
break;
case 0x07: // Bottom Right
this.bitmap[0] = Art.ledge_bottom_right;
break;
// ---------------------------------------------------------
case 0x08:
this.bitmap[0] = Art.ledge_mt_bottom;
break;
case 0x09:
this.bitmap[0] = Art.ledge_mt_bottom_left;
break;
case 0x0A:
this.bitmap[0] = Art.ledge_mt_left;
break;
case 0x0B:
this.bitmap[0] = Art.ledge_mt_top_left;
break;
case 0x0C:
this.bitmap[0] = Art.ledge_mt_top;
break;
case 0x0D:
this.bitmap[0] = Art.ledge_mt_top_right;
break;
case 0x0E:
this.bitmap[0] = Art.ledge_mt_right;
break;
case 0x0F:
this.bitmap[0] = Art.ledge_mt_bottom_right;
break;
// ---------------------------------------------------------
case 0x10:
this.bitmap[0] = Art.ledge_inner_bottom;
break;
case 0x11:
this.bitmap[0] = Art.ledge_inner_bottom_left;
break;
case 0x12:
this.bitmap[0] = Art.ledge_inner_left;
break;
case 0x13:
this.bitmap[0] = Art.ledge_inner_top_left;
break;
case 0x14:
this.bitmap[0] = Art.ledge_inner_top;
break;
case 0x15:
this.bitmap[0] = Art.ledge_inner_top_right;
break;
case 0x16:
this.bitmap[0] = Art.ledge_inner_right;
break;
case 0x17:
this.bitmap[0] = Art.ledge_inner_bottom_right;
break;
// ---------------------------------------------------------
case 0x18:
this.bitmap[0] = Art.Ledge_bottom_left_corner;
break;
case 0x19:
this.bitmap[0] = Art.Ledge_bottom_right_corner;
break;
}
break;
}
case 0x03: // Obstacles
this.bitmap = new BaseBitmap[1];
switch (red) {
case 0x00: // Small Tree
this.bitmap[0] = Art.smallTree;
break;
case 0x01: // Logs
this.bitmap[0] = Art.logs;
break;
case 0x02: // Planks
this.bitmap[0] = Art.planks;
break;
case 0x03: // Scaffolding (Left)
this.bitmap[0] = Art.scaffolding_left;
break;
case 0x04: // Scaffolding (Right)
this.bitmap[0] = Art.scaffolding_right;
break;
case 0x05: // Sign
this.bitmap[0] = Art.sign;
break;
case 0x06: // Workbench Left
this.bitmap[0] = Art.workbench_left;
break;
case 0x07: // Workbench Right
this.bitmap[0] = Art.workbench_right;
break;
case 0x08: // Dead small tree
this.bitmap[0] = Art.deadSmallTree;
break;
}
break;
case 0x04: // Warp point (Refer to documentation for flaws.)
this.bitmap = new BaseBitmap[1];
this.bitmap[0] = Art.forestEntrance;
break;
case 0x05: // Area Sector Point (Refer to documentation.)
this.bitmap = new BaseBitmap[1];
// TODO: Add new bitmaps for connection points to make them blend in with the surroundings.
// TODO: Create more biome bitmaps.
// TODO (6/19/2015): 0x05000003 is a water tile in the level editor, but it's really not a water tile.
this.bitmap[0] = Art.grass;
break;
case 0x06: // Stairs
this.bitmap = new BaseBitmap[1];
switch (red) {
case 0x00:
this.bitmap[0] = Art.stairs_bottom;
break;
case 0x01:
this.bitmap[0] = Art.stairs_left;
break;
case 0x02:
this.bitmap[0] = Art.stairs_top;
break;
case 0x03:
this.bitmap[0] = Art.stairs_right;
break;
case 0x04:
this.bitmap[0] = Art.stairs_mt_bottom;
break;
case 0x05:
this.bitmap[0] = Art.stairs_mt_left;
break;
case 0x06:
this.bitmap[0] = Art.stairs_mt_top;
break;
case 0x07:
this.bitmap[0] = Art.stairs_mt_right;
break;
}
break;
case 0x07: { // Water
// Always start with the first frame of any animation.
// TODO: Add more water tiles with borders.
// TODO (6/19/2015): Make the borders a bit more thicker. Possibly the land border near the edges of the water tiles.
switch (red) {
case 0x00: // Pure water, no border.
this.bitmap = Art.water;
break;
case 0x01: // Left Border
this.bitmap = Art.water_left;
break;
case 0x02: // Top Left Border
this.bitmap = Art.water_top_left;
break;
case 0x03: // Top Border
this.bitmap = Art.water_top;
break;
case 0x04: // Top Right Border
this.bitmap = Art.water_top_right;
break;
case 0x05: // Right Border
this.bitmap = Art.water_right;
break;
}
break;
}
case 0x08: // House
this.bitmap = new BaseBitmap[1];
switch (red) { // House related tiles. Way too many to list them orderly.
case 0x00: // Bottom wall
this.bitmap[0] = Art.house_bottom;
break;
case 0x01: // Bottom left wall
this.bitmap[0] = Art.house_bottom_left;
break;
case 0x02: // Bottom right wall
this.bitmap[0] = Art.house_bottom_right;
break;
case 0x03: // Center wall
this.bitmap[0] = Art.house_center;
break;
case 0x04: // Center wall with windows in center
this.bitmap[0] = Art.house_center_windows_center;
break;
case 0x05: // Center wall with windows on left
this.bitmap[0] = Art.house_center_windows_left;
break;
case 0x06: // Center wall with windows on right
this.bitmap[0] = Art.house_center_windows_right;
break;
case 0x07: // Left wall
this.bitmap[0] = Art.house_left;
break;
case 0x08: // Left wall with windows on right
this.bitmap[0] = Art.house_left_windows_right;
break;
case 0x09: // Right wall
this.bitmap[0] = Art.house_right;
break;
case 0x0A: // Right wall with windows on left
this.bitmap[0] = Art.house_right_windows_left;
break;
case 0x0B: // Single Roof left
this.bitmap[0] = Art.changeColors(Art.house_roof_left, WorldConstants.convertToAreaColor(green));
// this.bitmap[0] = Art.house_roof_left;
break;
case 0x0C: // Single Roof middle
this.bitmap[0] = Art.changeColors(Art.house_roof_middle, WorldConstants.convertToAreaColor(green));
break;
case 0x0D: // Single Roof right
this.bitmap[0] = Art.changeColors(Art.house_roof_right, WorldConstants.convertToAreaColor(green));
break;
}
break;
case 0x09: // House Door
this.bitmap = new BaseBitmap[1];
this.bitmap[0] = Art.house_door;
break;
case 0x0A: // Item
this.bitmap = new BaseBitmap[1];
this.bitmap[0] = Art.item;
break;
case 0x0B: // Carpet Floor (Indoors)
this.bitmap = new BaseBitmap[1];
this.bitmap[0] = Art.carpet_indoors;
this.biomeBitmap = Art.exit_arrow;
break;
case 0x0C: // Carpet Floors (Outdoors)
this.bitmap = new BaseBitmap[1];
this.bitmap[0] = Art.carpet_outdoors;
this.biomeBitmap = Art.exit_arrow;
break;
case 0x0D: // Starting position when game has initialized;
this.bitmap = new BaseBitmap[1];
switch (red) {
case 0x01:
default:
this.bitmap[0] = Art.grass;
break;
}
break;
default: // Any other type of tiles.
break;
}
if (this.bitmap == null) {
this.bitmap = new BaseBitmap[1];
this.bitmap[0] = Art.error;
}
if (this.biomeBitmap == null) {
this.biomeBitmap = new BaseBitmap[1];
this.biomeBitmap[0] = Art.grass; // By default, biome bitmap should be grass.
}
}
/**
* Prepares the bitmap if the color has been pre-determined.
*
* <p>
* Will cause undefined behaviors if the colors have not been set yet.
*
* @return Nothing.
* */
public void prepareBitmap() {
int alpha = (this.color >> 24) & 0xFF;
int red = (this.color >> 16) & 0xFF;
int green = (this.color >> 8) & 0xFF;
int blue = this.color & 0xFF;
this.prepareBitmap(alpha, red, green, blue);
}
/**
* Sets the properties of a given pixel data. This is where the game gets the area's information on what the player should do and don't.
*
* <p>
* Some of the features are currently unused. Especially collision detection.
*
* <p>
* Only the ones that set target areas, warp zone areas, etc. are the ones being used.
*
* @param alpha
* The alpha value of the pixel data's color.
* @param red
* The red value of the pixel data's color.
* @param green
* The green value of the pixel data's color.
* @param blue
* The blue value of the pixel data's color.
* @return Nothing.
* */
public void setProperties(int alpha, int red, int green, int blue) {
this.targetArea = 0;
this.isWarpZone = false;
this.groundHeight = 0;
switch (alpha) {
case 0x01: // Grass
this.groundHeight = blue;
break;
case 0x02: // Ledges
break;
case 0x03: // Obstacles
this.facingsBlocked[0] = this.facingsBlocked[1] = this.facingsBlocked[2] = this.facingsBlocked[3] = false;
break;
case 0x04: // Warp Point
if (red < 0x01) {
// This is error checking prevention.
red = 0x01;
}
this.targetArea = WorldConstants.isModsEnabled.booleanValue() ? red + 1001 : red;
this.isWarpZone = true;
break;
case 0x05: // ACP (Refer to documentation.)
if (red < 0x01) {
// This is error checking prevention.
red = 0x01;
}
this.targetArea = WorldConstants.isModsEnabled.booleanValue() ? red + 1001 : red;
this.targetSector = green;
this.isWarpZone = false;
// this.facingsBlocked[0] = this.facingsBlocked[1] = this.facingsBlocked[2] = this.facingsBlocked[3] = true;
break;
case 0x06: // Stairs
break;
case 0x07: // Water
// TODO: Needs to do something with facingsBlocked[] array. It must not block the player, however, without special boolean value, it will always block player from advancing.
// this.facingsBlocked[0] = this.facingsBlocked[1] = this.facingsBlocked[2] = this.facingsBlocked[3] = true;
case 0x08: // House
// this.facingsBlocked[0] = this.facingsBlocked[1] = this.facingsBlocked[2] = this.facingsBlocked[3] = false;
break;
case 0x09: // House Door
if (red < 0x01) {
// This is error checking prevention.
red = 0x01;
}
this.targetArea = WorldConstants.isModsEnabled.booleanValue() ? red + 1001 : red;
this.isWarpZone = true;
break;
case 0x0A: // Item
break;
case 0x0B: // Carpets
case 0x0C: // Carpets
if (red < 0x01) {
// This is error checking prevention.
red = 0x01;
}
this.targetArea = WorldConstants.isModsEnabled.booleanValue() ? red + 1001 : red;
break;
case 0x0D: // Default Starting Position
break;
default:
this.facingsBlocked[0] = this.facingsBlocked[1] = this.facingsBlocked[2] = this.facingsBlocked[3] = false;
break;
}
}
public int getColor() {
return this.color;
}
// public int getParentAreaID() {
// return parentArea;
// }
public int getTargetAreaID() {
return targetArea;
}
public boolean[] isWalkThroughable() {
return this.facingsBlocked;
}
public int getTargetSectorID() {
return this.targetSector;
}
public void tick() {
this.bitmapTick++;
if (this.bitmapTick >= this.bitmap.length)
this.bitmapTick = 0;
this.biomeBitmapTick++;
if (this.biomeBitmapTick >= this.biomeBitmap.length)
this.biomeBitmapTick = 0;
}
public BaseBitmap getBitmap() {
return this.bitmap[this.bitmapTick];
}
public int getGroundHeight() {
return this.groundHeight;
}
public BaseBitmap getBiomeBitmap() {
return this.biomeBitmap[this.biomeBitmapTick];
}
}