SpelunkyRemake / WoodTile.cpp
WoodTile.cpp
Raw
#include "pch.h"
#include "WoodTile.h"
#include "Item.h"
#include "Texture.h"

int WoodTile::m_Count{ 0 };

Texture* WoodTile::m_pTexture{ nullptr };

WoodTile::WoodTile(int x, int y, int itemType)
	: Tile(x, y, itemType)
	, m_SrcRect{ 0, 0, m_Size, m_Size }
	, m_Primes{ 2, 3, 5, 7 }
{
	if (m_pTexture == nullptr)
	{
		m_pTexture = new Texture{ "Resources/Sprites/wood_tiles.png" };
	}
	
	m_AdjacentTiles[int(Direction::UP)] = false;
	m_AdjacentTiles[int(Direction::DOWN)] = false;
	m_AdjacentTiles[int(Direction::LEFT)] = false;
	m_AdjacentTiles[int(Direction::RIGHT)] = false;

	m_SrcRectsMap[m_Primes[int(Direction::UP)]] = Rectf{ 256, 256, m_Size, m_Size };
	m_SrcRectsMap[m_Primes[int(Direction::DOWN)]] = Rectf{ 256, 192, m_Size, m_Size };
	m_SrcRectsMap[m_Primes[int(Direction::LEFT)]] = Rectf{ 256, 128, m_Size, m_Size };
	m_SrcRectsMap[m_Primes[int(Direction::RIGHT)]] = Rectf{ 256, 64, m_Size, m_Size };

	m_SrcRectsMap[m_Primes[int(Direction::DOWN)] * m_Primes[int(Direction::LEFT)]] = Rectf{ 192, 64, m_Size, m_Size };
	m_SrcRectsMap[m_Primes[int(Direction::UP)] * m_Primes[int(Direction::DOWN)] * m_Primes[int(Direction::LEFT)]] = Rectf{ 192, 128, m_Size, m_Size };
	m_SrcRectsMap[m_Primes[int(Direction::UP)] * m_Primes[int(Direction::LEFT)]] = Rectf{ 192, 192, m_Size, m_Size };

	m_SrcRectsMap[m_Primes[int(Direction::DOWN)] * m_Primes[int(Direction::LEFT)] * m_Primes[int(Direction::RIGHT)]] = Rectf{ 128, 64, m_Size, m_Size };
	m_SrcRectsMap[1] = Rectf{ 128, 128, m_Size, m_Size };
	m_SrcRectsMap[m_Primes[int(Direction::UP)] * m_Primes[int(Direction::LEFT)] * m_Primes[int(Direction::RIGHT)]] = Rectf{ 128, 64, m_Size, m_Size };

	m_SrcRectsMap[m_Primes[int(Direction::DOWN)] * m_Primes[int(Direction::RIGHT)]] = Rectf{ 64, 64, m_Size, m_Size };
	m_SrcRectsMap[m_Primes[int(Direction::DOWN)] * m_Primes[int(Direction::RIGHT)] * m_Primes[int(Direction::DOWN)]] = Rectf{ 64, 128, m_Size, m_Size };
	m_SrcRectsMap[m_Primes[int(Direction::UP)] * m_Primes[int(Direction::RIGHT)]] = Rectf{ 64, 192, m_Size, m_Size };

	m_SrcRectsMap[m_Primes[int(Direction::LEFT)] * m_Primes[int(Direction::RIGHT)]] = Rectf{ 0, 64, m_Size, m_Size };
	m_SrcRectsMap[m_Primes[int(Direction::UP)] * m_Primes[int(Direction::DOWN)]] = Rectf{ 0, 128, m_Size, m_Size };
	m_SrcRectsMap[m_Primes[int(Direction::UP)] * m_Primes[int(Direction::DOWN)] * m_Primes[int(Direction::LEFT)] * m_Primes[int(Direction::RIGHT)]] = Rectf{ 0, 192, m_Size, m_Size };

	m_Count++;
}

WoodTile::~WoodTile()
{
	m_Count--;

	if (m_Count == 0)
	{
		delete m_pTexture;
		m_pTexture = nullptr;
	}
}

void WoodTile::Init(Tile* pTiles[], int xTiles, int yTiles)
{
	int key{ 1 };

	//up
	if (m_Y < (yTiles - 1))
	{
		if (pTiles[utils::GetIdx(m_X, m_Y + 1, xTiles)] != nullptr)
		{
			m_AdjacentTiles[int(Direction::UP)] = true;
			if (dynamic_cast<WoodTile*>(pTiles[utils::GetIdx(m_X, m_Y + 1, xTiles)]) != nullptr) key *= m_Primes[int(Direction::UP)];
		}
	}

	//bottom
	if (m_Y > 0)
	{
		if (pTiles[utils::GetIdx(m_X, m_Y - 1, xTiles)] != nullptr)
		{
			m_AdjacentTiles[int(Direction::DOWN)] = true;
			if (dynamic_cast<WoodTile*>(pTiles[utils::GetIdx(m_X, m_Y - 1, xTiles)]) != nullptr) key *= m_Primes[int(Direction::DOWN)];
		}
	}

	//left
	if (m_X > 0)
	{
		if (pTiles[utils::GetIdx(m_X - 1, m_Y, xTiles)] != nullptr)
		{
			m_AdjacentTiles[int(Direction::LEFT)] = true;
			if (dynamic_cast<WoodTile*>(pTiles[utils::GetIdx(m_X - 1, m_Y, xTiles)]) != nullptr) key *= m_Primes[int(Direction::LEFT)];
		}
	}

	//right
	if (m_X < (xTiles - 1))
	{
		if (pTiles[utils::GetIdx(m_X + 1, m_Y, xTiles)] != nullptr)
		{
			m_AdjacentTiles[int(Direction::RIGHT)] = true;
			if (dynamic_cast<WoodTile*>(pTiles[utils::GetIdx(m_X + 1, m_Y, xTiles)]) != nullptr) key *= m_Primes[int(Direction::RIGHT)];
		}
	}

	m_SrcRect = m_SrcRectsMap[key];
}

void WoodTile::UpdateBorder(Tile* pTiles[], int xTiles, int yTiles)
{
	//TODO: save tiles around {UP, DOWN, LEFT, RIGHT} on Init and check here if they've been destroyed. for each destroyed adjacent tile draw border.

	//top
	if (m_Y < (yTiles - 1))
	{
		if (m_AdjacentTiles[int(Direction::UP)] && pTiles[utils::GetIdx(m_X, m_Y + 1, xTiles)] != nullptr)
		{
			SetBorder(Direction::UP, true);
		}
	}

	//bottom
	if (m_Y > 0)
	{
		if (m_AdjacentTiles[int(Direction::DOWN)] && pTiles[utils::GetIdx(m_X, m_Y - 1, xTiles)] != nullptr)
		{
			SetBorder(Direction::DOWN, true);
		}
	}

	//left
	if (m_X > 0)
	{
		if (m_AdjacentTiles[int(Direction::LEFT)] && pTiles[utils::GetIdx(m_X - 1, m_Y, xTiles)] != nullptr)
		{
			SetBorder(Direction::LEFT, true);
		}
	}

	//right
	if (m_X < (xTiles - 1))
	{
		if (m_AdjacentTiles[int(Direction::RIGHT)] && pTiles[utils::GetIdx(m_X + 1, m_Y, xTiles)] != nullptr)
		{
			SetBorder(Direction::RIGHT, true);
		}
	}
}

void WoodTile::Draw() const
{
	Rectf srcRect{ m_Position.x, m_Position.y, m_Size, m_Size };

	//Draw tile
	m_pTexture->Draw(m_Position, m_SrcRect );

	//Draw gold overlay
	switch (Item::Type(m_Item))
	{
	case Item::Type::GOLD_CHUNK_SMALL:
		m_pGoldTextures->Draw(Point2f{ m_Position.x, m_Position.y }, Rectf{ 0, 0, m_Size, m_Size });
		break;
	case Item::Type::GOLD_CHUNK_BIG:
		m_pGoldTextures->Draw(Point2f{ m_Position.x, m_Position.y }, Rectf{ 64, 0, m_Size, m_Size });
		break;
	default:
		break;
	}
}

void WoodTile::DrawBorder() const
{
	if (m_DrawBorder[int(Direction::UP)]) m_pTexture->Draw(Point2f{ m_Position.x, m_Position.y + 28 }, Rectf{ 0, 256, m_Size, m_Size });
	if (m_DrawBorder[int(Direction::DOWN)]) m_pTexture->Draw(Point2f{ m_Position.x, m_Position.y - 32 }, Rectf{ 64, 256, m_Size, m_Size });
	if (m_DrawBorder[int(Direction::LEFT)])	m_pTexture->Draw(Point2f{ m_Position.x - 32, m_Position.y }, Rectf{ 192, 256, m_Size, m_Size });
	if (m_DrawBorder[int(Direction::RIGHT)]) m_pTexture->Draw(Point2f{ m_Position.x + 32, m_Position.y }, Rectf{ 128, 256, m_Size, m_Size });
}

void WoodTile::DrawItem() const
{
	Tile::DrawItem();
}