mirror of
https://github.com/MaaAssistantArknights/MaaAssistantArknights.git
synced 2026-07-18 02:10:21 +08:00
feat.初步集成地图格子识别
This commit is contained in:
230
3rdparty/include/Arknights-Tile-Pos/TileCalc.hpp
vendored
Normal file
230
3rdparty/include/Arknights-Tile-Pos/TileCalc.hpp
vendored
Normal file
@@ -0,0 +1,230 @@
|
||||
#pragma once
|
||||
|
||||
#include <string>
|
||||
#include <vector>
|
||||
#include <cmath>
|
||||
#include <fstream>
|
||||
#include <iostream>
|
||||
|
||||
#include <opencv2/core.hpp>
|
||||
#include <meojson/json.hpp>
|
||||
|
||||
namespace Map
|
||||
{
|
||||
struct Tile
|
||||
{
|
||||
int heightType = 0;
|
||||
int buildableType = 0;
|
||||
};
|
||||
|
||||
class Level
|
||||
{
|
||||
public:
|
||||
Level(const json::value& data);
|
||||
int get_width() const { return width; }
|
||||
int get_height() const { return height; }
|
||||
Tile get_item(int y, int x) const { return tiles[y][x]; }
|
||||
int view = 0;
|
||||
std::string stageId;
|
||||
std::string code;
|
||||
std::string levelId;
|
||||
std::string name;
|
||||
private:
|
||||
int height = 0;
|
||||
int width = 0;
|
||||
std::vector<std::vector<Tile>> tiles;
|
||||
};
|
||||
class TileCalc
|
||||
{
|
||||
public:
|
||||
TileCalc(int width, int height, const std::string& dir);
|
||||
bool run(const std::string& code_or_name, bool side, std::vector<std::vector<cv::Point2d>>& out_pos, std::vector<std::vector<Tile>>& out_tiles) const;
|
||||
private:
|
||||
int width = 0;
|
||||
int height = 0;
|
||||
const double degree = atan(1.0) * 4 / 180;
|
||||
std::vector<Level> levels;
|
||||
cv::Mat MatrixP = cv::Mat(4, 4, CV_64F);
|
||||
cv::Mat MatrixX = cv::Mat(4, 4, CV_64F);
|
||||
cv::Mat MatrixY = cv::Mat(4, 4, CV_64F);
|
||||
bool adapter(double& x, double& y) const;
|
||||
};
|
||||
|
||||
inline void InitMat4x4(cv::Mat& m, double(*num)[4])
|
||||
{
|
||||
for (int i = 0; i < m.rows; i++)
|
||||
for (int j = 0; j < m.cols; j++)
|
||||
m.at<double>(i, j) = num[i][j];
|
||||
}
|
||||
|
||||
Level::Level(const json::value& data)
|
||||
{
|
||||
Level::stageId = data.at("stageId").as_string();
|
||||
Level::code = data.at("code").as_string();
|
||||
Level::levelId = data.at("levelId").as_string();
|
||||
Level::name = data.get("name", "null");
|
||||
Level::height = data.at("height").as_integer();
|
||||
Level::width = data.at("width").as_integer();
|
||||
Level::view = data.at("view").as_integer();
|
||||
for (const json::value& row : data.at("tiles").as_array()) {
|
||||
std::vector<Tile> tmp(Level::width);
|
||||
for (const json::value& tile : row.as_array()) {
|
||||
tmp.emplace_back(Tile{ tile.at("heightType").as_integer(), tile.at("buildableType").as_integer() });
|
||||
}
|
||||
tiles.emplace_back(std::move(tmp));
|
||||
}
|
||||
}
|
||||
|
||||
TileCalc::TileCalc(int width, int height, const std::string& dir)
|
||||
{
|
||||
TileCalc::width = width;
|
||||
TileCalc::height = height;
|
||||
double ratio = static_cast<double>(height) / width;
|
||||
double matrixP[4][4]{
|
||||
{ ratio / tan(20 * degree), 0, 0, 0},
|
||||
{ 0, 1 / tan(20 * degree), 0, 0},
|
||||
{ 0, 0, -(1000 + 0.3) / (1000 - 0.3), -(1000 * 0.3 * 2) / (1000 - 0.3)},
|
||||
{ 0, 0, -1, 0 }
|
||||
};
|
||||
InitMat4x4(TileCalc::MatrixP, matrixP);
|
||||
double matrixX[4][4]{
|
||||
{ 1, 0, 0, 0},
|
||||
{ 0, cos(30 * degree), -sin(30 * degree), 0},
|
||||
{ 0, -sin(30 * degree), -cos(30 * degree), 0},
|
||||
{ 0, 0, 0, 1}
|
||||
};
|
||||
InitMat4x4(TileCalc::MatrixX, matrixX);
|
||||
double matrixY[4][4]{
|
||||
{ cos(10 * degree), 0, sin(10 * degree), 0},
|
||||
{ 0, 1, 0, 0},
|
||||
{ -sin(10 * degree), 0, cos(10 * degree), 0},
|
||||
{ 0, 0, 0, 1}
|
||||
};
|
||||
InitMat4x4(TileCalc::MatrixY, matrixY);
|
||||
std::ifstream ifs(dir, std::ios::in);
|
||||
if (!ifs.is_open()) {
|
||||
std::cerr << "Read resource failed" << std::endl;
|
||||
throw "Read resource failed";
|
||||
}
|
||||
std::stringstream iss;
|
||||
iss << ifs.rdbuf();
|
||||
ifs.close();
|
||||
std::string content = iss.str();
|
||||
auto ret = json::parse(content);
|
||||
if (!ret) {
|
||||
std::cerr << "Parsing failed" << std::endl;
|
||||
throw "Parsing failed";
|
||||
}
|
||||
for (const json::value& item : ret.value().as_array()) {
|
||||
TileCalc::levels.emplace_back(item);
|
||||
}
|
||||
}
|
||||
|
||||
bool TileCalc::adapter(double& x, double& y) const
|
||||
{
|
||||
const double fromRatio = 9.0 / 16;
|
||||
const double toRatio = 3.0 / 4;
|
||||
double ratio = static_cast<double>(height) / width;
|
||||
if (ratio < fromRatio - 0.00001) {
|
||||
x = 0;
|
||||
y = 0;
|
||||
return false;
|
||||
}
|
||||
double t = (ratio - fromRatio) / (toRatio - fromRatio);
|
||||
x = -1.4 * t;
|
||||
y = -2.8 * t;
|
||||
return true;
|
||||
}
|
||||
|
||||
bool TileCalc::run(const std::string& code_or_name, bool side, std::vector<std::vector<cv::Point2d>>& out_pos, std::vector<std::vector<Tile>>& out_tiles) const
|
||||
{
|
||||
bool runned = false;
|
||||
double x = 0, y = 0, z = 0;
|
||||
for (const Map::Level& level : TileCalc::levels) {
|
||||
if (level.code == code_or_name || level.name == code_or_name) {
|
||||
switch (level.view) {
|
||||
case 0:
|
||||
x = 0;
|
||||
y = -4.81;
|
||||
z = -7.76;
|
||||
if (side) {
|
||||
x += 0.5975104570388794;
|
||||
y -= 0.5;
|
||||
z -= 0.882108688354492;
|
||||
}
|
||||
break;
|
||||
case 1:
|
||||
x = 0;
|
||||
y = -5.60;
|
||||
z = -8.92;
|
||||
if (side) {
|
||||
x += 0.7989424467086792;
|
||||
y -= 0.5;
|
||||
z -= 0.86448486328125;
|
||||
}
|
||||
break;
|
||||
case 2:
|
||||
x = 0;
|
||||
y = -5.08;
|
||||
z = -8.04;
|
||||
if (side) {
|
||||
x += 0.6461319923400879;
|
||||
y -= 0.5;
|
||||
z -= 0.877854309082031;
|
||||
}
|
||||
break;
|
||||
default:
|
||||
x = 0;
|
||||
y = -6.1;
|
||||
z = -9.78;
|
||||
if (side) {
|
||||
x += 0.948279857635498;
|
||||
y -= 0.5;
|
||||
z -= 0.85141918182373;
|
||||
}
|
||||
break;
|
||||
}
|
||||
double adapter_y = 0, adapter_z = 0;
|
||||
TileCalc::adapter(adapter_y, adapter_z);
|
||||
double matrix[4][4]{
|
||||
{ 1, 0, 0, -x},
|
||||
{ 0, 1, 0, -y - adapter_y},
|
||||
{ 0, 0, 1, -z - adapter_z},
|
||||
{ 0, 0, 0, 1}
|
||||
};
|
||||
auto raw = cv::Mat(cv::Size(4, 4), CV_64F);
|
||||
auto Finall_Matrix = cv::Mat(cv::Size(4, 4), CV_64F);
|
||||
InitMat4x4(raw, matrix);
|
||||
if (side) {
|
||||
Finall_Matrix = TileCalc::MatrixP * TileCalc::MatrixX * TileCalc::MatrixY * raw;
|
||||
}
|
||||
else {
|
||||
Finall_Matrix = TileCalc::MatrixP * TileCalc::MatrixX * raw;
|
||||
}
|
||||
int h = level.get_height();
|
||||
int w = level.get_width();
|
||||
auto map_point = cv::Mat(cv::Size(1, 4), CV_64F);
|
||||
map_point.at<double>(3, 0) = 1;
|
||||
auto tmp_pos = std::vector<cv::Point2d>(w);
|
||||
auto tmp_tiles = std::vector<Tile>(w);
|
||||
for (int i = 0; i < h; i++) {
|
||||
for (int j = 0; j < w; j++) {
|
||||
tmp_tiles[j] = level.get_item(i, j);
|
||||
map_point.at<double>(0, 0) = j - (w - 1) / 2.0;
|
||||
map_point.at<double>(1, 0) = (h - 1) / 2.0 - i;
|
||||
map_point.at<double>(2, 0) = tmp_tiles[j].heightType * -0.4;
|
||||
cv::Mat view_point = Finall_Matrix * map_point;
|
||||
view_point = view_point / view_point.at<double>(3, 0);
|
||||
view_point = (view_point + 1) / 2;
|
||||
tmp_pos[j] = cv::Point2d(view_point.at<double>(0, 0) * TileCalc::width, (1 - view_point.at<double>(1, 0)) * TileCalc::height);
|
||||
}
|
||||
out_pos.emplace_back(tmp_pos);
|
||||
out_tiles.emplace_back(tmp_tiles);
|
||||
}
|
||||
runned = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
return runned;
|
||||
}
|
||||
}
|
||||
@@ -163,6 +163,7 @@ Yes, but there are few supported features, please refer to [this link](resource/
|
||||
- WPF控件库:[HandyControl](https://github.com/HandyOrg/HandyControl)
|
||||
- C# JSON库: [Newtonsoft.Json](https://github.com/JamesNK/Newtonsoft.Json)
|
||||
- 下载器:[aria2](https://github.com/aria2/aria2)
|
||||
- 明日方舟地图格子识别: [Arknights-Tile-Pos](https://github.com/yuanyan3060/Arknights-Tile-Pos)
|
||||
|
||||
### 数据源
|
||||
|
||||
|
||||
@@ -3127,6 +3127,18 @@
|
||||
"ClueGiveTo1stConfirm"
|
||||
]
|
||||
},
|
||||
"BattleStageName": {
|
||||
"algorithm": "OcrDetect",
|
||||
"text": [
|
||||
|
||||
],
|
||||
"roi": [
|
||||
255,
|
||||
263,
|
||||
785,
|
||||
328
|
||||
]
|
||||
},
|
||||
"BattleUseOper": {
|
||||
"algorithm": "JustReturn",
|
||||
"preDelay": 500,
|
||||
|
||||
@@ -697,9 +697,9 @@ bool asst::Controller::screencap(const std::string & cmd, DecodeFunc decode_func
|
||||
}
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
cv::Mat asst::Controller::get_resized_image() const
|
||||
}
|
||||
|
||||
cv::Mat asst::Controller::get_resized_image() const
|
||||
{
|
||||
const static cv::Size dsize(m_scale_size.first, m_scale_size.second);
|
||||
|
||||
@@ -710,7 +710,7 @@ cv::Mat asst::Controller::get_resized_image() const
|
||||
}
|
||||
cv::Mat resized_mat;
|
||||
cv::resize(m_cache_image, resized_mat, dsize);
|
||||
return resized_mat;
|
||||
return resized_mat;
|
||||
}
|
||||
|
||||
int asst::Controller::click(const Point & p, bool block)
|
||||
@@ -831,13 +831,13 @@ cv::Mat asst::Controller::get_image()
|
||||
}
|
||||
|
||||
return get_resized_image();
|
||||
}
|
||||
|
||||
std::vector<uchar> asst::Controller::get_image_encode()
|
||||
}
|
||||
|
||||
std::vector<uchar> asst::Controller::get_image_encode()
|
||||
{
|
||||
cv::Mat img = get_resized_image();
|
||||
std::vector<uchar> buf;
|
||||
cv::imencode(".png", img, buf);
|
||||
|
||||
return buf;
|
||||
return buf;
|
||||
}
|
||||
|
||||
@@ -68,6 +68,7 @@
|
||||
<ClInclude Include="TaskData.h" />
|
||||
<ClInclude Include="MatchImageAnalyzer.h" />
|
||||
<ClInclude Include="TemplResource.h" />
|
||||
<ClInclude Include="TilePack.h" />
|
||||
<ClInclude Include="UserConfiger.h" />
|
||||
<ClInclude Include="Version.h" />
|
||||
<ClInclude Include="Controller.h" />
|
||||
@@ -124,6 +125,7 @@
|
||||
<ClCompile Include="TaskData.cpp" />
|
||||
<ClCompile Include="MatchImageAnalyzer.cpp" />
|
||||
<ClCompile Include="TemplResource.cpp" />
|
||||
<ClCompile Include="TilePack.cpp" />
|
||||
<ClCompile Include="UserConfiger.cpp" />
|
||||
<ClCompile Include="Controller.cpp" />
|
||||
</ItemGroup>
|
||||
|
||||
@@ -252,6 +252,9 @@
|
||||
<ClInclude Include="RoguelikeFormationTaskPlugin.h">
|
||||
<Filter>头文件\TaskPlugin</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="TilePack.h">
|
||||
<Filter>头文件\Resource</Filter>
|
||||
</ClInclude>
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<ClCompile Include="Controller.cpp">
|
||||
@@ -413,6 +416,9 @@
|
||||
<ClCompile Include="RoguelikeFormationTask.cpp">
|
||||
<Filter>源文件\TaskPlugin</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="TilePack.cpp">
|
||||
<Filter>源文件\Resource</Filter>
|
||||
</ClCompile>
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<None Include="..\..\resource\config.json">
|
||||
|
||||
@@ -16,9 +16,10 @@ bool asst::Resource::load(const std::string& dir)
|
||||
constexpr static const char* RecruitCfgFilename = "recruit.json";
|
||||
constexpr static const char* ItemCfgFilename = "item_index.json";
|
||||
constexpr static const char* InfrastCfgFilename = "infrast.json";
|
||||
constexpr static const char* UserCfgFilename = "..\\user.json";
|
||||
constexpr static const char* UserCfgFilename = "../user.json";
|
||||
constexpr static const char* OcrResourceFilename = "PaddleOCR";
|
||||
constexpr static const char* PenguinResourceFilename = "penguin-stats-recognize";
|
||||
constexpr static const char* TilesCalcResourceFilename = "Arknights-Tile-Pos";
|
||||
|
||||
/* 加载各个Json配置文件 */
|
||||
if (!m_general_cfg_unique_ins.load(dir + GeneralCfgFilename)) {
|
||||
@@ -77,5 +78,11 @@ bool asst::Resource::load(const std::string& dir)
|
||||
return false;
|
||||
}
|
||||
|
||||
/* 加载地图格子识别库所需要的资源 */
|
||||
if (!m_tile_pack_unique_ins.load(dir + TilesCalcResourceFilename)) {
|
||||
m_last_error = std::string(TilesCalcResourceFilename) + ": " + m_tile_pack_unique_ins.get_last_error();
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -14,6 +14,7 @@
|
||||
#include "TaskData.h"
|
||||
#include "TemplResource.h"
|
||||
#include "UserConfiger.h"
|
||||
#include "TilePack.h"
|
||||
|
||||
namespace asst
|
||||
{
|
||||
@@ -62,6 +63,10 @@ namespace asst
|
||||
{
|
||||
return m_penguin_pack_unique_ins;
|
||||
}
|
||||
TilePack& tile() noexcept
|
||||
{
|
||||
return m_tile_pack_unique_ins;
|
||||
}
|
||||
|
||||
const TemplResource& templ() const noexcept
|
||||
{
|
||||
@@ -95,6 +100,10 @@ namespace asst
|
||||
{
|
||||
return m_penguin_pack_unique_ins;
|
||||
}
|
||||
const TilePack& tile() const noexcept
|
||||
{
|
||||
return m_tile_pack_unique_ins;
|
||||
}
|
||||
|
||||
Resource& operator=(const Resource&) = delete;
|
||||
Resource& operator=(Resource&&) noexcept = delete;
|
||||
@@ -110,6 +119,7 @@ namespace asst
|
||||
UserConfiger m_user_cfg_unique_ins;
|
||||
OcrPack m_ocr_pack_unique_ins;
|
||||
PenguinPack m_penguin_pack_unique_ins;
|
||||
TilePack m_tile_pack_unique_ins;
|
||||
};
|
||||
|
||||
//static auto& resource = Resource::get_instance();
|
||||
|
||||
@@ -5,6 +5,8 @@
|
||||
#include "Controller.h"
|
||||
#include "TaskData.h"
|
||||
#include "ProcessTask.h"
|
||||
#include "OcrImageAnalyzer.h"
|
||||
#include "Resource.h"
|
||||
|
||||
bool asst::RoguelikeBattleTaskPlugin::verify(AsstMsg msg, const json::value& details) const
|
||||
{
|
||||
@@ -23,11 +25,9 @@ bool asst::RoguelikeBattleTaskPlugin::verify(AsstMsg msg, const json::value& det
|
||||
|
||||
bool asst::RoguelikeBattleTaskPlugin::_run()
|
||||
{
|
||||
m_used_opers = false;
|
||||
m_pre_hp = 0;
|
||||
m_home_cache.clear();
|
||||
clear();
|
||||
|
||||
speed_up();
|
||||
get_stage_info();
|
||||
|
||||
while (!need_exit()) {
|
||||
// 不在战斗场景,且已使用过了干员,说明已经打完了,就结束循环
|
||||
@@ -39,6 +39,38 @@ bool asst::RoguelikeBattleTaskPlugin::_run()
|
||||
return true;
|
||||
}
|
||||
|
||||
bool asst::RoguelikeBattleTaskPlugin::get_stage_info()
|
||||
{
|
||||
const auto& tile = Resrc.tile();
|
||||
bool calced = false;
|
||||
for (int i = 0; i != m_retry_times; ++i) {
|
||||
OcrImageAnalyzer name_analyzer(Ctrler.get_image());
|
||||
name_analyzer.set_task_info("BattleStageName");
|
||||
name_analyzer.analyze();
|
||||
|
||||
for (const auto& tr : name_analyzer.get_result()) {
|
||||
auto normal_info = tile.calc(tr.text, false);
|
||||
if (normal_info.empty()) {
|
||||
continue;
|
||||
}
|
||||
auto side_info = tile.calc(tr.text, true);
|
||||
if (side_info.empty()) {
|
||||
continue;
|
||||
}
|
||||
|
||||
m_tile_info = std::move(normal_info);
|
||||
m_side_tile_info = std::move(side_info);
|
||||
calced = true;
|
||||
break;
|
||||
}
|
||||
if (calced) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
return calced;
|
||||
}
|
||||
|
||||
bool asst::RoguelikeBattleTaskPlugin::auto_battle()
|
||||
{
|
||||
using Role = asst::BattleImageAnalyzer::Role;
|
||||
@@ -191,3 +223,12 @@ bool asst::RoguelikeBattleTaskPlugin::use_skill(const asst::Rect& rect)
|
||||
ProcessTask task(*this, { "BattleUseSkill" });
|
||||
return task.run();
|
||||
}
|
||||
|
||||
void asst::RoguelikeBattleTaskPlugin::clear()
|
||||
{
|
||||
m_used_opers = false;
|
||||
m_pre_hp = 0;
|
||||
m_home_cache.clear();
|
||||
m_tile_info.clear();
|
||||
m_side_tile_info.clear();
|
||||
}
|
||||
|
||||
@@ -2,6 +2,7 @@
|
||||
|
||||
#include "AbstractTaskPlugin.h"
|
||||
#include "AsstDef.h"
|
||||
#include "TilePack.h"
|
||||
|
||||
namespace asst
|
||||
{
|
||||
@@ -16,12 +17,17 @@ namespace asst
|
||||
protected:
|
||||
virtual bool _run() override;
|
||||
|
||||
bool get_stage_info();
|
||||
bool auto_battle();
|
||||
bool speed_up();
|
||||
bool use_skill(const Rect& rect);
|
||||
void clear();
|
||||
|
||||
std::vector<Rect> m_home_cache;
|
||||
bool m_used_opers = false;
|
||||
int m_pre_hp = 0;
|
||||
|
||||
std::vector<asst::TilePack::TileInfo> m_tile_info;
|
||||
std::vector<asst::TilePack::TileInfo> m_side_tile_info;
|
||||
};
|
||||
}
|
||||
|
||||
57
src/MeoAssistant/TilePack.cpp
Normal file
57
src/MeoAssistant/TilePack.cpp
Normal file
@@ -0,0 +1,57 @@
|
||||
#include "TilePack.h"
|
||||
|
||||
#include <Arknights-Tile-Pos/TileCalc.hpp>
|
||||
|
||||
#include "Logger.hpp"
|
||||
|
||||
asst::TilePack::~TilePack() = default;
|
||||
|
||||
bool asst::TilePack::load(const std::string & dir)
|
||||
{
|
||||
LogTraceFunction;
|
||||
|
||||
constexpr static const char* filename = "/levels.json";
|
||||
|
||||
try {
|
||||
m_tile_calculator = std::make_unique<Map::TileCalc>(
|
||||
WindowWidthDefault, WindowHeightDefault, dir + filename);
|
||||
}
|
||||
catch (std::exception& e) {
|
||||
m_last_error = e.what();
|
||||
return false;
|
||||
}
|
||||
return m_tile_calculator != nullptr;
|
||||
}
|
||||
|
||||
std::vector<asst::TilePack::TileInfo> asst::TilePack::calc(const std::string & stage_code, bool side) const
|
||||
{
|
||||
LogTraceFunction;
|
||||
|
||||
std::vector<std::vector<cv::Point2d>> pos;
|
||||
std::vector<std::vector<Map::Tile>> tiles;
|
||||
|
||||
bool ret = m_tile_calculator->run(stage_code, side, pos, tiles);
|
||||
|
||||
Log.trace("After tiles cacl run");
|
||||
if (!ret) {
|
||||
Log.info("Tiles calc error!");
|
||||
return std::vector<TileInfo>();
|
||||
}
|
||||
|
||||
std::vector<TileInfo> dst;
|
||||
|
||||
for (size_t y = 0; y < pos.size(); ++y) {
|
||||
for (size_t x = 0; x < pos[y].size(); ++x) {
|
||||
const auto& cv_p = pos[y][x];
|
||||
const auto& tile = tiles[y][x];
|
||||
|
||||
dst.emplace_back(
|
||||
TileInfo{
|
||||
static_cast<BuildableType>(tile.buildableType),
|
||||
static_cast<HeightType>(tile.heightType),
|
||||
Point(static_cast<int>(cv_p.x), static_cast<int>(cv_p.y))
|
||||
});
|
||||
}
|
||||
}
|
||||
return dst;
|
||||
}
|
||||
49
src/MeoAssistant/TilePack.h
Normal file
49
src/MeoAssistant/TilePack.h
Normal file
@@ -0,0 +1,49 @@
|
||||
#pragma once
|
||||
|
||||
#include "AbstractResource.h"
|
||||
#include "AsstDef.h"
|
||||
|
||||
#include <memory>
|
||||
|
||||
namespace Map
|
||||
{
|
||||
class TileCalc;
|
||||
}
|
||||
|
||||
namespace asst
|
||||
{
|
||||
class TilePack final : public AbstractResource
|
||||
{
|
||||
public:
|
||||
enum class BuildableType
|
||||
{
|
||||
Invaild = -1,
|
||||
None = 0,
|
||||
Melee = 1,
|
||||
Ranged = 2,
|
||||
All = 3
|
||||
};
|
||||
enum class HeightType
|
||||
{
|
||||
Invaild = -1,
|
||||
Highland = 0,
|
||||
Floor = 1
|
||||
};
|
||||
struct TileInfo
|
||||
{
|
||||
BuildableType buildable = BuildableType::Invaild;
|
||||
HeightType height = HeightType::Invaild;
|
||||
Point pos;
|
||||
};
|
||||
public:
|
||||
using AbstractResource::AbstractResource;
|
||||
virtual ~TilePack();
|
||||
|
||||
virtual bool load(const std::string& dir) override;
|
||||
|
||||
std::vector<TileInfo> calc(const std::string& stage_code, bool side) const;
|
||||
|
||||
private:
|
||||
std::shared_ptr<Map::TileCalc> m_tile_calculator = nullptr;
|
||||
};
|
||||
}
|
||||
Reference in New Issue
Block a user