383 lines
11 KiB
C++
383 lines
11 KiB
C++
#include "precompile.h"
|
|
|
|
#include "gridservice.h"
|
|
#include "human.h"
|
|
#include "bullet.h"
|
|
|
|
GridService::GridService()
|
|
{
|
|
|
|
}
|
|
|
|
GridService::~GridService()
|
|
{
|
|
|
|
}
|
|
|
|
void GridService::Init(int width, int height, int cell_width)
|
|
{
|
|
map_width_ = width;
|
|
map_height_ = height;
|
|
cell_width_ = cell_width;
|
|
|
|
cell_count_per_row_ = (map_height_ / cell_width + 1) + 2;
|
|
cell_count_per_col_ = (map_width_ / cell_width + 1) + 2;
|
|
max_grid_id_ = cell_count_per_row_ * cell_count_per_col_;
|
|
cells_ = new GridCell[max_grid_id_ + 1];
|
|
|
|
grid_offset_arr_[0] = -(cell_count_per_row_ - 1);
|
|
grid_offset_arr_[1] = -cell_count_per_row_;
|
|
grid_offset_arr_[2] = -(cell_count_per_row_ + 1);
|
|
|
|
grid_offset_arr_[3] = -1;
|
|
grid_offset_arr_[4] = 0;
|
|
grid_offset_arr_[5] = 1;
|
|
|
|
grid_offset_arr_[6] = cell_count_per_row_ - 1;
|
|
grid_offset_arr_[7] = cell_count_per_row_;
|
|
grid_offset_arr_[8] = cell_count_per_row_ + 1;
|
|
|
|
min_x_ = cell_width_ * 1;
|
|
min_y_ = cell_width_ * 1;
|
|
max_x_ = cell_width_ * (cell_count_per_row_ - 1);
|
|
max_y_ = cell_width_ * (cell_count_per_col_ - 1);
|
|
}
|
|
|
|
void GridService::UnInit()
|
|
{
|
|
if (cells_) {
|
|
delete[] cells_;
|
|
cells_ = nullptr;
|
|
}
|
|
}
|
|
|
|
bool GridService::BroderOverFlow(int x, int y)
|
|
{
|
|
return x <= min_x_ || x >= max_x_ || y <= min_y_ || y >= max_y_;
|
|
}
|
|
|
|
void GridService::GetAllCells(int grid_id, std::set<GridCell*>& grid_list)
|
|
{
|
|
for (size_t i = 1; i <= 9; ++i) {
|
|
GetGridList(grid_id, i, grid_list);
|
|
}
|
|
}
|
|
|
|
void GridService::GetAllCellsByXy(int x, int y, std::set<GridCell*>& grid_list)
|
|
{
|
|
int new_x = x + cell_width_;
|
|
int new_y = y + cell_width_;
|
|
int new_grid_id = new_x/cell_width_ + (new_y/cell_width_) * cell_count_per_row_;
|
|
if (BroderOverFlow(new_x, new_y)) {
|
|
abort();
|
|
}
|
|
GetAllCells(new_grid_id, grid_list);
|
|
}
|
|
|
|
void GridService::Get123(int grid_id, std::set<GridCell*>& grid_list)
|
|
{
|
|
GetGridList(grid_id, 1, grid_list);
|
|
GetGridList(grid_id, 2, grid_list);
|
|
GetGridList(grid_id, 3, grid_list);
|
|
}
|
|
|
|
void GridService::Get456(int grid_id, std::set<GridCell*>& grid_list)
|
|
{
|
|
GetGridList(grid_id, 4, grid_list);
|
|
GetGridList(grid_id, 5, grid_list);
|
|
GetGridList(grid_id, 6, grid_list);
|
|
}
|
|
|
|
void GridService::Get789(int grid_id, std::set<GridCell*>& grid_list)
|
|
{
|
|
GetGridList(grid_id, 7, grid_list);
|
|
GetGridList(grid_id, 8, grid_list);
|
|
GetGridList(grid_id, 9, grid_list);
|
|
}
|
|
|
|
void GridService::Get147(int grid_id, std::set<GridCell*>& grid_list)
|
|
{
|
|
GetGridList(grid_id, 1, grid_list);
|
|
GetGridList(grid_id, 4, grid_list);
|
|
GetGridList(grid_id, 7, grid_list);
|
|
}
|
|
|
|
void GridService::Get258(int grid_id, std::set<GridCell*>& grid_list)
|
|
{
|
|
GetGridList(grid_id, 2, grid_list);
|
|
GetGridList(grid_id, 5, grid_list);
|
|
GetGridList(grid_id, 8, grid_list);
|
|
}
|
|
|
|
void GridService::Get369(int grid_id, std::set<GridCell*>& grid_list)
|
|
{
|
|
GetGridList(grid_id, 3, grid_list);
|
|
GetGridList(grid_id, 6, grid_list);
|
|
GetGridList(grid_id, 9, grid_list);
|
|
}
|
|
|
|
void GridService::AddHuman(Human* hum)
|
|
{
|
|
int x = (int)hum->pos.x + cell_width_;
|
|
int y = (int)hum->pos.y + cell_width_;
|
|
if (BroderOverFlow(x, y)) {
|
|
abort();
|
|
}
|
|
hum->grid_id = x/cell_width_ + (y/cell_width_) * cell_count_per_row_;
|
|
if (hum->grid_id == 0 || hum->grid_id > max_grid_id_) {
|
|
abort();
|
|
}
|
|
cells_[hum->grid_id].human_list.insert(hum);
|
|
GetAllCells(hum->grid_id, hum->grid_list);
|
|
}
|
|
|
|
void GridService::MoveHuman(Human* hum)
|
|
{
|
|
int new_x = (int)hum->pos.x + cell_width_;
|
|
int new_y = (int)hum->pos.y + cell_width_;
|
|
int new_grid_id = new_x/cell_width_ + (new_y/cell_width_) * cell_count_per_row_;
|
|
if (BroderOverFlow(new_x, new_y)) {
|
|
abort();
|
|
}
|
|
if (new_grid_id == 0 || new_grid_id > max_grid_id_) {
|
|
abort();
|
|
}
|
|
if (new_grid_id != hum->grid_id) {
|
|
std::set<GridCell*> inc_grid_list;
|
|
std::set<GridCell*> dec_grid_list;
|
|
std::set<GridCell*> old_grid_list = hum->grid_list;
|
|
ComputeDiff(hum->grid_id, new_grid_id,
|
|
hum->grid_list,
|
|
inc_grid_list,
|
|
dec_grid_list);
|
|
cells_[hum->grid_id].human_list.erase(hum);
|
|
cells_[new_grid_id].human_list.insert(hum);
|
|
hum->grid_id = new_grid_id;
|
|
hum->OnGridListChange(old_grid_list, inc_grid_list, dec_grid_list);
|
|
}
|
|
}
|
|
|
|
void GridService::AddBullet(Bullet* bullet)
|
|
{
|
|
int x = (int)bullet->pos.x + cell_width_;
|
|
int y = (int)bullet->pos.y + cell_width_;
|
|
if (BroderOverFlow(x, y)) {
|
|
abort();
|
|
}
|
|
bullet->grid_id = x/cell_width_ + (y/cell_width_) * cell_count_per_row_;
|
|
if (bullet->grid_id == 0 || bullet->grid_id > max_grid_id_) {
|
|
abort();
|
|
}
|
|
cells_[bullet->grid_id].bullet_list.insert(bullet);
|
|
GetAllCells(bullet->grid_id, bullet->grid_list);
|
|
}
|
|
|
|
void GridService::MoveBullet(Bullet* bullet)
|
|
{
|
|
int new_x = (int)bullet->pos.x + cell_width_;
|
|
int new_y = (int)bullet->pos.y + cell_width_;
|
|
int new_grid_id = new_x/cell_width_ + (new_y/cell_width_) * cell_count_per_row_;
|
|
if (BroderOverFlow(new_x, new_y)) {
|
|
abort();
|
|
}
|
|
if (new_grid_id == 0 || new_grid_id > max_grid_id_) {
|
|
abort();
|
|
}
|
|
if (new_grid_id != bullet->grid_id) {
|
|
std::set<GridCell*> inc_grid_list;
|
|
std::set<GridCell*> dec_grid_list;
|
|
std::set<GridCell*> old_grid_list = bullet->grid_list;
|
|
ComputeDiff(bullet->grid_id, new_grid_id,
|
|
bullet->grid_list,
|
|
inc_grid_list,
|
|
dec_grid_list);
|
|
cells_[bullet->grid_id].bullet_list.erase(bullet);
|
|
cells_[new_grid_id].bullet_list.insert(bullet);
|
|
bullet->grid_id = new_grid_id;
|
|
}
|
|
}
|
|
|
|
void GridService::DelBullet(Bullet* bullet)
|
|
{
|
|
GridCell& cell = cells_[bullet->grid_id];
|
|
cell.bullet_list.erase(bullet);
|
|
}
|
|
|
|
void GridService::AddEntity(Entity* entity)
|
|
{
|
|
assert(entity->entity_type != ET_Player);
|
|
int x = (int)entity->pos.x + cell_width_;
|
|
int y = (int)entity->pos.y + cell_width_;
|
|
if (BroderOverFlow(x, y)) {
|
|
abort();
|
|
}
|
|
entity->grid_id = x/cell_width_ + (y/cell_width_) * cell_count_per_row_;
|
|
if (entity->grid_id == 0 || entity->grid_id > max_grid_id_) {
|
|
abort();
|
|
}
|
|
cells_[entity->grid_id].entity_list.insert(entity);
|
|
}
|
|
|
|
void GridService::DelEntity(Entity* entity)
|
|
{
|
|
GridCell& cell = cells_[entity->grid_id];
|
|
cell.entity_list.erase(entity);
|
|
}
|
|
|
|
bool GridService::HumanInGridList(Human* hum, std::set<GridCell*>& grid_list)
|
|
{
|
|
for (auto& cell : grid_list) {
|
|
if (cell->human_list.find(hum) != cell->human_list.end()) {
|
|
return true;
|
|
}
|
|
}
|
|
return false;
|
|
}
|
|
|
|
bool GridService::EntityInGridList(Entity* entity, std::set<GridCell*>& grid_list)
|
|
{
|
|
for (auto& cell : grid_list) {
|
|
if (cell->entity_list.find(entity) != cell->entity_list.end()) {
|
|
return true;
|
|
}
|
|
}
|
|
return false;
|
|
}
|
|
|
|
bool GridService::InView(int a_grid, int b_grid)
|
|
{
|
|
return a_grid + grid_offset_arr_[0] == b_grid ||
|
|
a_grid + grid_offset_arr_[1] == b_grid ||
|
|
a_grid + grid_offset_arr_[2] == b_grid ||
|
|
a_grid + grid_offset_arr_[3] == b_grid ||
|
|
a_grid + grid_offset_arr_[4] == b_grid ||
|
|
a_grid + grid_offset_arr_[5] == b_grid ||
|
|
a_grid + grid_offset_arr_[6] == b_grid ||
|
|
a_grid + grid_offset_arr_[7] == b_grid ||
|
|
a_grid + grid_offset_arr_[8] == b_grid;
|
|
}
|
|
|
|
void GridService::RemoveFromGridList(std::set<GridCell*>& grid_list, Entity* entity)
|
|
{
|
|
for (auto& grid : grid_list) {
|
|
switch (entity->entity_type) {
|
|
case ET_Player:
|
|
{
|
|
grid->human_list.erase((Human*)entity);
|
|
}
|
|
break;
|
|
case ET_Bullet:
|
|
{
|
|
grid->bullet_list.erase((Bullet*)entity);
|
|
}
|
|
break;
|
|
default:
|
|
{
|
|
grid->entity_list.erase(entity);
|
|
}
|
|
break;
|
|
}
|
|
}
|
|
}
|
|
|
|
void GridService::GetGridList(int grid_id, int offset,
|
|
std::set<GridCell*>& grid_list)
|
|
{
|
|
if (offset <1 || offset > 9) {
|
|
abort();
|
|
}
|
|
if (grid_id <= 0 || grid_id >= max_grid_id_) {
|
|
return;
|
|
}
|
|
int tmp_grid_id = grid_id + grid_offset_arr_[offset - 1];
|
|
if (tmp_grid_id > 0) {
|
|
grid_list.insert(&cells_[tmp_grid_id]);
|
|
}
|
|
}
|
|
|
|
void GridService::ComputeDiff(int old_grid_id, int new_grid_id,
|
|
std::set<GridCell*>& grid_list,
|
|
std::set<GridCell*>& inc_grid_list,
|
|
std::set<GridCell*>& dec_grid_list)
|
|
{
|
|
int diff_grid = new_grid_id - old_grid_id;
|
|
#if 1
|
|
{
|
|
std::set<GridCell*> new_grid_list;
|
|
GetAllCells(new_grid_id, new_grid_list);
|
|
for (auto& cell : new_grid_list) {
|
|
if (grid_list.find(cell) == grid_list.end()) {
|
|
inc_grid_list.insert(cell);
|
|
}
|
|
}
|
|
for (auto& cell : grid_list) {
|
|
if (new_grid_list.find(cell) == new_grid_list.end()) {
|
|
dec_grid_list.insert(cell);
|
|
}
|
|
}
|
|
}
|
|
#else
|
|
if (diff_grid == 1) {
|
|
Get369(new_grid_id, inc_grid_list);
|
|
Get147(old_grid_id, dec_grid_list);
|
|
} else if (diff_grid == -1) {
|
|
Get147(new_grid_id, inc_grid_list);
|
|
Get369(old_grid_id, dec_grid_list);
|
|
} else if (diff_grid == cell_count_per_row_) {
|
|
Get789(new_grid_id, inc_grid_list);
|
|
Get123(old_grid_id, dec_grid_list);
|
|
} else if (diff_grid + cell_count_per_row_ == 0) {
|
|
Get123(new_grid_id, inc_grid_list);
|
|
Get789(old_grid_id, dec_grid_list);
|
|
} else if (diff_grid + cell_count_per_row_ == 1) {
|
|
Get123(new_grid_id, inc_grid_list);
|
|
GetGridList(new_grid_id, 6, inc_grid_list);
|
|
GetGridList(new_grid_id, 9, inc_grid_list);
|
|
|
|
GetGridList(old_grid_id, 1, dec_grid_list);
|
|
GetGridList(old_grid_id, 4, dec_grid_list);
|
|
Get789(old_grid_id, dec_grid_list);
|
|
} else if (diff_grid + cell_count_per_row_ == -1) {
|
|
Get123(new_grid_id, inc_grid_list);
|
|
GetGridList(new_grid_id, 4, inc_grid_list);
|
|
GetGridList(new_grid_id, 7, inc_grid_list);
|
|
|
|
GetGridList(old_grid_id, 6, dec_grid_list);
|
|
GetGridList(old_grid_id, 9, dec_grid_list);
|
|
Get789(old_grid_id, dec_grid_list);
|
|
} else if (diff_grid == cell_count_per_row_ + 1) {
|
|
Get789(new_grid_id, inc_grid_list);
|
|
GetGridList(new_grid_id, 3, inc_grid_list);
|
|
GetGridList(new_grid_id, 6, inc_grid_list);
|
|
|
|
GetGridList(old_grid_id, 4, dec_grid_list);
|
|
GetGridList(old_grid_id, 7, dec_grid_list);
|
|
Get123(old_grid_id, dec_grid_list);
|
|
} else if (diff_grid == cell_count_per_row_ - 1) {
|
|
Get789(new_grid_id, inc_grid_list);
|
|
GetGridList(new_grid_id, 1, inc_grid_list);
|
|
GetGridList(new_grid_id, 4, inc_grid_list);
|
|
|
|
GetGridList(old_grid_id, 6, dec_grid_list);
|
|
GetGridList(old_grid_id, 9, dec_grid_list);
|
|
Get123(old_grid_id, dec_grid_list);
|
|
} else {
|
|
std::set<GridCell*> new_grid_list;
|
|
GetAllCells(new_grid_id, new_grid_list);
|
|
for (auto& cell : new_grid_list) {
|
|
if (grid_list.find(cell) == grid_list.end()) {
|
|
inc_grid_list.insert(cell);
|
|
}
|
|
}
|
|
for (auto& cell : grid_list) {
|
|
if (new_grid_list.find(cell) == new_grid_list.end()) {
|
|
dec_grid_list.insert(cell);
|
|
}
|
|
}
|
|
}
|
|
#endif
|
|
|
|
grid_list.clear();
|
|
GetAllCells(new_grid_id, grid_list);
|
|
}
|