[Add] Some work on enemy AI.
This commit is contained in:
parent
35fd91c97a
commit
8b92224e72
@ -77,6 +77,7 @@ SOURCES += ../src/libUnuk/Engine/WorldManager.cpp \
|
|||||||
../src/libUnuk/LevelGen/LevelGen.cpp \
|
../src/libUnuk/LevelGen/LevelGen.cpp \
|
||||||
../src/libUnuk/LevelGen/MapEntities.cpp \
|
../src/libUnuk/LevelGen/MapEntities.cpp \
|
||||||
../src/libUnuk/LevelGen/MapElement.cpp \
|
../src/libUnuk/LevelGen/MapElement.cpp \
|
||||||
|
../src/libUnuk/LevelGen/MapTile.cpp \
|
||||||
../src/libUnuk/UI/EventHistory.cpp \
|
../src/libUnuk/UI/EventHistory.cpp \
|
||||||
../src/libUnuk/UI/Bar.cpp \
|
../src/libUnuk/UI/Bar.cpp \
|
||||||
../src/libUnuk/System/Vec2.cpp \
|
../src/libUnuk/System/Vec2.cpp \
|
||||||
|
@ -232,6 +232,10 @@
|
|||||||
RelativePath="..\..\..\src\libUnuk\LevelGen\MapEntities.h"
|
RelativePath="..\..\..\src\libUnuk\LevelGen\MapEntities.h"
|
||||||
>
|
>
|
||||||
</File>
|
</File>
|
||||||
|
<File
|
||||||
|
RelativePath="..\..\..\src\libUnuk\LevelGen\MapTile.cpp"
|
||||||
|
>
|
||||||
|
</File>
|
||||||
<File
|
<File
|
||||||
RelativePath="..\..\..\src\libUnuk\LevelGen\MapTile.h"
|
RelativePath="..\..\..\src\libUnuk\LevelGen\MapTile.h"
|
||||||
>
|
>
|
||||||
@ -316,6 +320,14 @@
|
|||||||
RelativePath="..\..\..\src\libUnuk\System\Timer.h"
|
RelativePath="..\..\..\src\libUnuk\System\Timer.h"
|
||||||
>
|
>
|
||||||
</File>
|
</File>
|
||||||
|
<File
|
||||||
|
RelativePath="..\..\..\src\libUnuk\System\Vec2.cpp"
|
||||||
|
>
|
||||||
|
</File>
|
||||||
|
<File
|
||||||
|
RelativePath="..\..\..\src\libUnuk\System\Vec2.h"
|
||||||
|
>
|
||||||
|
</File>
|
||||||
</Filter>
|
</Filter>
|
||||||
<Filter
|
<Filter
|
||||||
Name="Ui"
|
Name="Ui"
|
||||||
|
@ -32,6 +32,8 @@ const int Player::EXP_TABLE[MAX_LEVEL] = {
|
|||||||
Player::Player(LevelGen *mapArg) : Character(mapArg) {
|
Player::Player(LevelGen *mapArg) : Character(mapArg) {
|
||||||
_level = 1;
|
_level = 1;
|
||||||
_exp = 0;
|
_exp = 0;
|
||||||
|
_lastTileX = 0;
|
||||||
|
_lastTileY = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
Player::~Player(void) {
|
Player::~Player(void) {
|
||||||
@ -99,6 +101,15 @@ void Player::Update(void) {
|
|||||||
// For now The camera will be static.
|
// For now The camera will be static.
|
||||||
//SetCamera();
|
//SetCamera();
|
||||||
|
|
||||||
|
int tileX = x / TILE_WIDTH;
|
||||||
|
int tileY = y / TILE_HEIGHT;
|
||||||
|
if(tileX != _lastTileX || tileY != _lastTileY) {
|
||||||
|
_lastTileX = tileX;
|
||||||
|
_lastTileY = tileY;
|
||||||
|
|
||||||
|
map->GetWorld().OnPlayerMove(this);
|
||||||
|
}
|
||||||
|
|
||||||
_healthBar.SetProgress((float)GetHealth() / 100.0f);
|
_healthBar.SetProgress((float)GetHealth() / 100.0f);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -27,6 +27,8 @@ public:
|
|||||||
void SetExpLiteral(int exp) { _exp = exp; }
|
void SetExpLiteral(int exp) { _exp = exp; }
|
||||||
void SetHealthLiteral(int health) { _health = health; }
|
void SetHealthLiteral(int health) { _health = health; }
|
||||||
|
|
||||||
|
void SetXY(float xArg, float yArg) { x = xArg, y = yArg; _lastTileX = xArg / TILE_WIDTH; _lastTileY = yArg / TILE_HEIGHT; }
|
||||||
|
|
||||||
static const int MAX_LEVEL = 20;
|
static const int MAX_LEVEL = 20;
|
||||||
static const int EXP_TABLE[MAX_LEVEL];
|
static const int EXP_TABLE[MAX_LEVEL];
|
||||||
|
|
||||||
@ -41,4 +43,7 @@ private:
|
|||||||
string _name;
|
string _name;
|
||||||
int _level;
|
int _level;
|
||||||
int _exp;
|
int _exp;
|
||||||
|
|
||||||
|
int _lastTileX;
|
||||||
|
int _lastTileY;
|
||||||
};
|
};
|
||||||
|
@ -1,4 +1,5 @@
|
|||||||
#include "NPC.h"
|
#include "NPC.h"
|
||||||
|
#include "../Unuk/Player.h"
|
||||||
|
|
||||||
NPC::NPC(LevelGen* mapArg) : Character(mapArg) {
|
NPC::NPC(LevelGen* mapArg) : Character(mapArg) {
|
||||||
_moveTimer.Start();
|
_moveTimer.Start();
|
||||||
@ -61,3 +62,32 @@ void NPC::Move(void) {
|
|||||||
map->MoveIfPossible(this, xVel, yVel, false);
|
map->MoveIfPossible(this, xVel, yVel, false);
|
||||||
Character::HealthBarScroll();
|
Character::HealthBarScroll();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void NPC::OnPlayerMove(Player* player) {
|
||||||
|
MapTile& start = map->GetTile(x / TILE_WIDTH, y / TILE_HEIGHT);
|
||||||
|
MapTile& goal = map->GetTile(player->GetX() / TILE_WIDTH, player->GetY() / TILE_HEIGHT);
|
||||||
|
|
||||||
|
_astar.SetStartAndGoalStates(start, goal);
|
||||||
|
|
||||||
|
bool solutionFound = false;
|
||||||
|
|
||||||
|
// Dirty loop to calculate the path
|
||||||
|
while(true) {
|
||||||
|
_astar.SearchStep();
|
||||||
|
|
||||||
|
int state = _astar.GetState();
|
||||||
|
if(state == AStarSearch<MapTile>::SEARCH_STATE_SUCCEEDED) {
|
||||||
|
solutionFound = true;
|
||||||
|
break;
|
||||||
|
} else if(state == AStarSearch<MapTile>::SEARCH_STATE_SEARCHING) {
|
||||||
|
continue;
|
||||||
|
} else {
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if(solutionFound) {
|
||||||
|
x = _astar.GetSolutionEnd()->GetTileX();
|
||||||
|
y = _astar.GetSolutionEnd()->GetTileY();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
@ -1,6 +1,10 @@
|
|||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
#include "Character.h"
|
#include "Character.h"
|
||||||
|
#include "Pathfinding.h"
|
||||||
|
#include "../LevelGen/MapTile.h"
|
||||||
|
|
||||||
|
class Player;
|
||||||
|
|
||||||
class NPC : public Character {
|
class NPC : public Character {
|
||||||
public:
|
public:
|
||||||
@ -9,6 +13,8 @@ public:
|
|||||||
|
|
||||||
void Update(void);
|
void Update(void);
|
||||||
|
|
||||||
|
void OnPlayerMove(Player* player);
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
void Move(void);
|
void Move(void);
|
||||||
|
|
||||||
@ -22,4 +28,6 @@ private:
|
|||||||
bool _moving;
|
bool _moving;
|
||||||
|
|
||||||
Timer _moveTimer;
|
Timer _moveTimer;
|
||||||
|
|
||||||
|
AStarSearch<MapTile> _astar;
|
||||||
};
|
};
|
||||||
|
@ -37,7 +37,7 @@ public:
|
|||||||
float h; // Heuristic estimate of the distance of the goal.
|
float h; // Heuristic estimate of the distance of the goal.
|
||||||
float f; // Sum of cost and heuristic.
|
float f; // Sum of cost and heuristic.
|
||||||
|
|
||||||
Node(void) : parent(0), child(0), g(0.0f), h(0.0f), f(0.0) {}
|
Node(UserState userState) : parent(0), child(0), g(0.0f), h(0.0f), f(0.0), _userState(userState) {}
|
||||||
|
|
||||||
UserState _userState;
|
UserState _userState;
|
||||||
};
|
};
|
||||||
@ -68,14 +68,11 @@ public:
|
|||||||
void SetStartAndGoalStates(UserState& start, UserState& goal) {
|
void SetStartAndGoalStates(UserState& start, UserState& goal) {
|
||||||
_cancelRequest= false;
|
_cancelRequest= false;
|
||||||
|
|
||||||
_start = AllocateNode();
|
_start = AllocateNode(start);
|
||||||
_goal = AllocateNode();
|
_goal = AllocateNode(goal);
|
||||||
|
|
||||||
assert((_start != NULL && _goal != NULL));
|
assert((_start != NULL && _goal != NULL));
|
||||||
|
|
||||||
_start->_userState = _start;
|
|
||||||
_goal->_userState = _goal;
|
|
||||||
|
|
||||||
_state = SEARCH_STATE_SEARCHING;
|
_state = SEARCH_STATE_SEARCHING;
|
||||||
|
|
||||||
// Initialize the AStar specific parts of the start node.
|
// Initialize the AStar specific parts of the start node.
|
||||||
@ -245,7 +242,7 @@ public:
|
|||||||
// Call this to add a successor to a list of
|
// Call this to add a successor to a list of
|
||||||
// successors when expanding the seach frontier.
|
// successors when expanding the seach frontier.
|
||||||
bool AddSuccessor(UserState& state) {
|
bool AddSuccessor(UserState& state) {
|
||||||
Node* node = Allocate();
|
Node* node = AllocateNode(state);
|
||||||
|
|
||||||
if(node) {
|
if(node) {
|
||||||
node->_userState = state;
|
node->_userState = state;
|
||||||
@ -307,8 +304,8 @@ public:
|
|||||||
// Get the end node.
|
// Get the end node.
|
||||||
UserState* GetSolutionEnd(void) {
|
UserState* GetSolutionEnd(void) {
|
||||||
_currentSolutionNode = _goal;
|
_currentSolutionNode = _goal;
|
||||||
if(goal) {
|
if(_goal) {
|
||||||
return &goal->_userState;
|
return &_goal->_userState;
|
||||||
} else {
|
} else {
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
@ -470,8 +467,8 @@ private:
|
|||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
Node* AllocateNode(void) {
|
Node* AllocateNode(UserState& userState) {
|
||||||
Node *p = new Node;
|
Node *p = new Node(userState);
|
||||||
return p;
|
return p;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -185,3 +185,9 @@ void WorldManager::OnPlayerAttack(Player* player) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void WorldManager::OnPlayerMove(Player* player) {
|
||||||
|
for(std::list<NPC*>::iterator i = _npcs.begin(); i != _npcs.end(); ++i) {
|
||||||
|
(*i)->OnPlayerMove(player);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
@ -27,6 +27,7 @@ public:
|
|||||||
int GetNPCCount() { return _npcs.size(); }
|
int GetNPCCount() { return _npcs.size(); }
|
||||||
|
|
||||||
void OnPlayerAttack(Player* player);
|
void OnPlayerAttack(Player* player);
|
||||||
|
void OnPlayerMove(Player* player);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
LevelGen* _level;
|
LevelGen* _level;
|
||||||
|
@ -255,7 +255,7 @@ void LevelGen::Unload(void) {
|
|||||||
_entityTextures.Unload();
|
_entityTextures.Unload();
|
||||||
for(int x = 0; x < TILE_ARRAY_SIZE; x++) {
|
for(int x = 0; x < TILE_ARRAY_SIZE; x++) {
|
||||||
for(int y = 0; y < TILE_ARRAY_SIZE; y++) {
|
for(int y = 0; y < TILE_ARRAY_SIZE; y++) {
|
||||||
_tile[x][y] = MapTile();
|
_tile[x][y] = MapTile(this);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -411,17 +411,17 @@ void LevelGen::MoveIfPossible(Character* character, float xVel, float yVel, bool
|
|||||||
charRect.w = character->GetWidth();
|
charRect.w = character->GetWidth();
|
||||||
charRect.h = character->GetHeight() / 4;
|
charRect.h = character->GetHeight() / 4;
|
||||||
|
|
||||||
for(int x = 0; x < BOUNDARIES_X; x++) {
|
for(int i = 0; i < BOUNDARIES_X; i++) {
|
||||||
for(int y = 0; y < BOUNDARIES_Y; y++) {
|
for(int j = 0; j < BOUNDARIES_Y; j++) {
|
||||||
if(!_tile[x][y].GetEntitySolitity()) {
|
if(!_tile[i][j].GetEntitySolitity()) {
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
SDL_Rect entityRect;
|
SDL_Rect entityRect;
|
||||||
entityRect.x = _tile[x][y].GetEntityX();
|
entityRect.x = _tile[i][j].GetEntityX();
|
||||||
entityRect.y = _tile[x][y].GetEntityY();
|
entityRect.y = _tile[i][j].GetEntityY();
|
||||||
entityRect.w = _tile[x][y].GetEntityWidth();
|
entityRect.w = _tile[i][j].GetEntityWidth();
|
||||||
entityRect.h = _tile[x][y].GetEntityHeight();
|
entityRect.h = _tile[i][j].GetEntityHeight();
|
||||||
|
|
||||||
if(CheckCollisionRect(entityRect, charRect)) {
|
if(CheckCollisionRect(entityRect, charRect)) {
|
||||||
return;
|
return;
|
||||||
@ -448,6 +448,41 @@ void LevelGen::MoveIfPossible(Character* character, float xVel, float yVel, bool
|
|||||||
character->SetXY(targetX, targetY);
|
character->SetXY(targetX, targetY);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool LevelGen::CanMoveToPoint(int xArg, int yArg) {
|
||||||
|
if(xArg < 0 || xArg > SCREEN_WIDTH ||
|
||||||
|
yArg < 0 || yArg > SCREEN_HEIGHT) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
int tileX = xArg / TILE_WIDTH;
|
||||||
|
int tileY = yArg / TILE_HEIGHT;
|
||||||
|
|
||||||
|
if(_tile[tileX][tileY].GetTileSolidity()) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
for(int i = 0; i < BOUNDARIES_X; i++) {
|
||||||
|
for(int j = 0; j < BOUNDARIES_Y; j++) {
|
||||||
|
if(!_tile[i][j].GetEntitySolitity()) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
SDL_Rect entityRect;
|
||||||
|
entityRect.x = _tile[i][j].GetEntityX();
|
||||||
|
entityRect.y = _tile[i][j].GetEntityY();
|
||||||
|
entityRect.w = _tile[i][j].GetEntityWidth();
|
||||||
|
entityRect.h = _tile[i][j].GetEntityHeight();
|
||||||
|
|
||||||
|
if(xArg >= entityRect.x && xArg <= (entityRect.x + entityRect.w) &&
|
||||||
|
yArg >= entityRect.y && yArg <= (entityRect.y + entityRect.h)) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
string LevelGen::GetCurrentMap(void) {
|
string LevelGen::GetCurrentMap(void) {
|
||||||
return _currentMap;
|
return _currentMap;
|
||||||
}
|
}
|
||||||
@ -491,3 +526,7 @@ int LevelGen::GetEntityHeight(int xArg, int yArg) {
|
|||||||
int LevelGen::GetTileZLevel(int xArg, int yArg) {
|
int LevelGen::GetTileZLevel(int xArg, int yArg) {
|
||||||
return _tile[xArg + 1][yArg + 1].GetZLevel();
|
return _tile[xArg + 1][yArg + 1].GetZLevel();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
MapTile& LevelGen::GetTile(int xArg, int yArg) {
|
||||||
|
return _tile[xArg][yArg];
|
||||||
|
}
|
||||||
|
@ -32,6 +32,7 @@ public:
|
|||||||
|
|
||||||
void FindSpawnPoint(int& xArg, int& yArg, int objWidth, int objHeight);
|
void FindSpawnPoint(int& xArg, int& yArg, int objWidth, int objHeight);
|
||||||
void MoveIfPossible(Character* character, float xVel, float yVel, bool isPlayer = false);
|
void MoveIfPossible(Character* character, float xVel, float yVel, bool isPlayer = false);
|
||||||
|
bool CanMoveToPoint(int xArg, int yArg);
|
||||||
|
|
||||||
bool GetTileSolidity(int xArg, int yArg);
|
bool GetTileSolidity(int xArg, int yArg);
|
||||||
int GetTileX(int xArg, int yArg);
|
int GetTileX(int xArg, int yArg);
|
||||||
@ -45,6 +46,8 @@ public:
|
|||||||
|
|
||||||
int GetTileZLevel(int xArg, int yArg);
|
int GetTileZLevel(int xArg, int yArg);
|
||||||
|
|
||||||
|
MapTile& GetTile(int xArg, int yArg);
|
||||||
|
|
||||||
string GetCurrentMap(void);
|
string GetCurrentMap(void);
|
||||||
|
|
||||||
WorldManager& GetWorld(void) { return _world; }
|
WorldManager& GetWorld(void) { return _world; }
|
||||||
|
68
src/libUnuk/LevelGen/MapTile.cpp
Normal file
68
src/libUnuk/LevelGen/MapTile.cpp
Normal file
@ -0,0 +1,68 @@
|
|||||||
|
#include "MapTile.h"
|
||||||
|
#include "LevelGen.h"
|
||||||
|
|
||||||
|
MapTile::MapTile(const MapTile& source) {
|
||||||
|
_level = source._level;
|
||||||
|
_tile = source._tile;
|
||||||
|
_entity = source._entity;
|
||||||
|
_zLevel = source._zLevel;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool MapTile::IsSameState(MapTile& tile) {
|
||||||
|
return (tile.GetTileX() == _tile.GetX()) && (tile.GetTileY() == _tile.GetY());
|
||||||
|
}
|
||||||
|
|
||||||
|
bool MapTile::IsGoal(MapTile& tile) {
|
||||||
|
return IsSameState(tile);
|
||||||
|
}
|
||||||
|
|
||||||
|
float MapTile::GoalDistanceEstimate(MapTile& goal) {
|
||||||
|
Vec2 thisPos(_tile.GetX(), _tile.GetY());
|
||||||
|
Vec2 goalPos(goal.GetTileX(), goal.GetTileY());
|
||||||
|
return abs(Vec2::DistanceSquared(thisPos, goalPos));
|
||||||
|
}
|
||||||
|
|
||||||
|
float MapTile::GetCost(MapTile& goal) {
|
||||||
|
return 64.0f*64.0f;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool MapTile::GetSuccessors(AStarSearch<MapTile>* search, MapTile* parent) {
|
||||||
|
int tileX = _tile.GetX() / TILE_WIDTH;
|
||||||
|
int tileY = _tile.GetY() / TILE_HEIGHT;
|
||||||
|
|
||||||
|
// Add tile to the left if possible.
|
||||||
|
if(tileX > 0) {
|
||||||
|
MapTile& successor = _level->GetTile(tileX - 1, tileY);
|
||||||
|
if(successor.GetTileSolidity() || successor.GetEntitySolitity()) {
|
||||||
|
search->AddSuccessor(successor);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Add tile to the right if possible
|
||||||
|
// TODO: replace 64 with map width
|
||||||
|
if(tileX < 64) {
|
||||||
|
MapTile& successor = _level->GetTile(tileX + 1, tileY);
|
||||||
|
if(successor.GetTileSolidity() || successor.GetEntitySolitity()) {
|
||||||
|
search->AddSuccessor(successor);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Add tile to the bottom if possible
|
||||||
|
if(tileY > 0) {
|
||||||
|
MapTile& successor = _level->GetTile(tileX, tileY - 1);
|
||||||
|
if(successor.GetTileSolidity() || successor.GetEntitySolitity()) {
|
||||||
|
search->AddSuccessor(successor);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Add tile to the top if possible
|
||||||
|
// TODO: replace 64 with map height
|
||||||
|
if(tileY < 64) {
|
||||||
|
MapTile& successor = _level->GetTile(tileX, tileY + 1);
|
||||||
|
if(successor.GetTileSolidity() || successor.GetEntitySolitity()) {
|
||||||
|
search->AddSuccessor(successor);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
@ -7,11 +7,15 @@
|
|||||||
#include "../Sprite/ApplySurface.h"
|
#include "../Sprite/ApplySurface.h"
|
||||||
#include "../LevelGen/MapElement.h"
|
#include "../LevelGen/MapElement.h"
|
||||||
#include "../LevelGen/MapEntities.h"
|
#include "../LevelGen/MapEntities.h"
|
||||||
|
#include "../Engine/Pathfinding.h"
|
||||||
|
#include "../System/Vec2.h"
|
||||||
using namespace std;
|
using namespace std;
|
||||||
|
|
||||||
|
class LevelGen;
|
||||||
|
|
||||||
class MapTile {
|
class MapTile {
|
||||||
public:
|
public:
|
||||||
MapTile(void) { }
|
MapTile(LevelGen* level = NULL) : _level(level) { }
|
||||||
~MapTile(void) { }
|
~MapTile(void) { }
|
||||||
|
|
||||||
void Render(void) { _tile.Render(), _entity.Render(); }
|
void Render(void) { _tile.Render(), _entity.Render(); }
|
||||||
@ -48,7 +52,16 @@ public:
|
|||||||
void SetZLevel(int arg) { _zLevel = arg; }
|
void SetZLevel(int arg) { _zLevel = arg; }
|
||||||
int GetZLevel(void) { return _zLevel; }
|
int GetZLevel(void) { return _zLevel; }
|
||||||
|
|
||||||
|
// Pathfinding stuff.
|
||||||
|
MapTile(const MapTile& source);
|
||||||
|
bool IsSameState(MapTile& tile);
|
||||||
|
bool IsGoal(MapTile& tile);
|
||||||
|
float GoalDistanceEstimate(MapTile& goal);
|
||||||
|
float GetCost(MapTile& goal);
|
||||||
|
bool GetSuccessors(AStarSearch<MapTile>* search, MapTile* parent);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
LevelGen* _level;
|
||||||
MapElement _tile;
|
MapElement _tile;
|
||||||
MapEntityGeneric _entity;
|
MapEntityGeneric _entity;
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user