|
@@ -1,12 +1,38 @@
|
|
|
#include "Cell.h"
|
|
|
-#include "unit.h"
|
|
|
+#include <assert.h>
|
|
|
+#include <string>
|
|
|
+#include <string.h>
|
|
|
+//#include "unit.h"
|
|
|
#include <queue>
|
|
|
#include <vector>
|
|
|
|
|
|
-Cell::Cell(Unit * character) {
|
|
|
+class Unit{
|
|
|
+public:
|
|
|
+ bool CanMoveForDistance(int distance){
|
|
|
+ return true;
|
|
|
+ }
|
|
|
+ /*
|
|
|
+ template<std::string AttackType>
|
|
|
+ bool CanAttackForDistance(int distance){
|
|
|
+ return true;
|
|
|
+ }
|
|
|
+ bool CanAttackForDistance<"Melee">(int distance){
|
|
|
+ return true;
|
|
|
+ }
|
|
|
+ bool CanAttackForDistance<"Range">(int distance){
|
|
|
+ return true;
|
|
|
+ }*/
|
|
|
+};
|
|
|
+
|
|
|
+class EffectsForCell{
|
|
|
+public:
|
|
|
+ void OperateOnCell(Cell*){}
|
|
|
+};
|
|
|
+
|
|
|
+Cell::Cell(Unit* character) {
|
|
|
leftUp_ = left_ = leftDown_ = nullptr;
|
|
|
rightUp_ = right_ = rightDown_ = nullptr;
|
|
|
- character_ = &character;
|
|
|
+ character_ = character;
|
|
|
clearCell_();
|
|
|
AddedToQuery_ = true;
|
|
|
}
|
|
@@ -17,42 +43,36 @@ Cell * Cell::getleftUp() {
|
|
|
void Cell::setleftUp(Cell * t) {
|
|
|
leftUp_ = t;
|
|
|
}
|
|
|
-
|
|
|
Cell * Cell::getleft() {
|
|
|
return left_;
|
|
|
}
|
|
|
void Cell::setleft(Cell * t) {
|
|
|
left_ = t;
|
|
|
}
|
|
|
-
|
|
|
Cell * Cell::getleftDown() {
|
|
|
return leftDown_;
|
|
|
}
|
|
|
void Cell::setleftDown(Cell * t) {
|
|
|
leftDown_ = t;
|
|
|
}
|
|
|
-
|
|
|
Cell * Cell::getrightUp() {
|
|
|
return rightUp_;
|
|
|
}
|
|
|
void Cell::setrightUp(Cell * t) {
|
|
|
rightUp_ = t;
|
|
|
}
|
|
|
-
|
|
|
Cell * Cell::getright() {
|
|
|
return right_;
|
|
|
}
|
|
|
void Cell::setright(Cell * t) {
|
|
|
right_ = t;
|
|
|
}
|
|
|
-
|
|
|
Cell * Cell::getrightDown() {
|
|
|
return rightDown_;
|
|
|
}
|
|
|
void Cell::setrightDown(Cell * t) {
|
|
|
rightDown_ = t;
|
|
|
}
|
|
|
-
|
|
|
Unit * Cell::getCharacter() {
|
|
|
return character_;
|
|
|
}
|
|
@@ -60,45 +80,122 @@ void Cell::setCharacter(Unit * t) {
|
|
|
character_ = t;
|
|
|
}
|
|
|
|
|
|
-bool Cell::getisMoveable() {
|
|
|
- return isMoveable_;
|
|
|
+int Cell::getdistance_barrier(){
|
|
|
+ return distance_barrier_;
|
|
|
}
|
|
|
-void Cell::setisMoveable(bool t) {
|
|
|
- isMoveable_ = t;
|
|
|
+void Cell::setdistance_barrier(int distance_barrier){
|
|
|
+ distance_barrier_ = distance_barrier;
|
|
|
}
|
|
|
-
|
|
|
-bool Cell::getisAttackable() {
|
|
|
- return isAttackable_;
|
|
|
+int Cell::getdistance_through(){
|
|
|
+ return distance_through_;
|
|
|
}
|
|
|
-void Cell::setisAttackable(bool t) {
|
|
|
- isAttackable_ = t;
|
|
|
+void Cell::setdistance_through(int distance_through){
|
|
|
+ distance_through_ = distance_through;
|
|
|
}
|
|
|
|
|
|
-int Cell::getDistance() {
|
|
|
- return distance_;
|
|
|
+bool Cell::getisMoveAble(){
|
|
|
+ return isMoveAble_;
|
|
|
+}
|
|
|
+void Cell::setisMoveAble(bool isMoveAble){
|
|
|
+ isMoveAble_ = isMoveAble;
|
|
|
+}
|
|
|
+bool Cell::getisMeleeAttackAble(){
|
|
|
+ return isMeleeAttackAble_;
|
|
|
}
|
|
|
-void Cell::setDistance(int t) {
|
|
|
- distance_ = t;
|
|
|
+void Cell::setisMeleeAttackAble(bool isMeleeAttackAble){
|
|
|
+ isMeleeAttackAble_ = isMeleeAttackAble;
|
|
|
+}
|
|
|
+bool Cell::getisRangeAttackAble(){
|
|
|
+ return isRangeAttackAble_;
|
|
|
+}
|
|
|
+void Cell::setisRangeAttackAble(bool isRangeAttackAble){
|
|
|
+ isRangeAttackAble_ = isRangeAttackAble;
|
|
|
}
|
|
|
|
|
|
bool Cell::isEmpty() {
|
|
|
return character_ == NULL;
|
|
|
}
|
|
|
|
|
|
+void Cell::recalculateAllEffectsList(){
|
|
|
+ for(std::vector<EffectsForCell*>::iterator it = beginIteratorEffectsList();
|
|
|
+ it != endIteratorEffectsList();++it){
|
|
|
+ (*it)->OperateOnCell(this);
|
|
|
+ }
|
|
|
+}
|
|
|
+void Cell::add(EffectsForCell* effect){
|
|
|
+ effects_list_.push_back(effect);
|
|
|
+}
|
|
|
+void Cell::remove(std::vector<EffectsForCell*>::iterator it){
|
|
|
+ if(beginIteratorEffectsList() <= it && it < endIteratorEffectsList()){
|
|
|
+ effects_list_.erase(it);
|
|
|
+ }
|
|
|
+}
|
|
|
+void Cell::remove(EffectsForCell* effect){
|
|
|
+ for(std::vector<EffectsForCell*>::iterator it = beginIteratorEffectsList();
|
|
|
+ it != endIteratorEffectsList();++it){
|
|
|
+ if((*it) == effect){
|
|
|
+ remove(it);
|
|
|
+ return;
|
|
|
+ }
|
|
|
+ }
|
|
|
+}
|
|
|
+std::vector<EffectsForCell*>::iterator Cell::beginIteratorEffectsList(){
|
|
|
+ return effects_list_.begin();
|
|
|
+}
|
|
|
+std::vector<EffectsForCell*>::iterator Cell::endIteratorEffectsList(){
|
|
|
+ return effects_list_.end();
|
|
|
+}
|
|
|
+
|
|
|
+void Cell::RecalculateTableWithCenterThisPoint() {
|
|
|
+ clearTable_();
|
|
|
+ std::queue<Cell*> qWithoutMoveable;
|
|
|
+ updateMoveableCells_(qWithoutMoveable);
|
|
|
+ updateUnMovealeCells_(qWithoutMoveable);
|
|
|
+}
|
|
|
+std::vector <Cell*> Cell::actualPath(Cell* to) {
|
|
|
+ if (!to || !to->getisMoveAble())return std::vector<Cell*>();
|
|
|
+ auto ret = std::vector<Cell*>(1, to);
|
|
|
+ while (to != this) {
|
|
|
+ Cell * parent = nullptr;
|
|
|
+ auto f = [&parent](Cell * TestParent, Cell * Now) {
|
|
|
+ if (TestParent && TestParent->getdistance_barrier() + 1 == Now->getdistance_barrier()
|
|
|
+ && TestParent->getisMoveAble()) {
|
|
|
+ parent = TestParent;
|
|
|
+ }
|
|
|
+ };
|
|
|
+ assert(parent != nullptr);
|
|
|
+ f(to->getleftUp(), to);
|
|
|
+ f(to->getleft(), to);
|
|
|
+ f(to->getleftDown(), to);
|
|
|
+ f(to->getrightUp(), to);
|
|
|
+ f(to->getright(), to);
|
|
|
+ f(to->getrightDown(), to);
|
|
|
+ to = parent;
|
|
|
+ ret.push_back(to);
|
|
|
+ }
|
|
|
+ return ret;
|
|
|
+}
|
|
|
+
|
|
|
void Cell::clearCell_() {
|
|
|
- setisMoveable(false);
|
|
|
- setisAttackable(false);
|
|
|
- setDistance(-1);
|
|
|
+ setdistance_barrier(-1);
|
|
|
+ setdistance_through(-1);
|
|
|
+ setisMeleeAttackAble(false);
|
|
|
+ setisMoveAble(false);
|
|
|
+ setisRangeAttackAble(false);
|
|
|
}
|
|
|
|
|
|
void Cell::clearTable_() {
|
|
|
std::queue<Cell*> q;
|
|
|
q.push(this);
|
|
|
clearCell_();
|
|
|
+ setdistance_through(0);
|
|
|
this->AddedToQuery_ = false;
|
|
|
- auto f = [&q](Cell * t) {
|
|
|
+ auto f = [&q](Cell * t, Cell * parent) {
|
|
|
if (t && t->AddedToQuery_ == true) {
|
|
|
q.push(t);
|
|
|
+ t->setdistance_through(
|
|
|
+ parent->getdistance_through() + 1
|
|
|
+ );
|
|
|
t->AddedToQuery_ = false;
|
|
|
}
|
|
|
};
|
|
@@ -106,40 +203,55 @@ void Cell::clearTable_() {
|
|
|
Cell * Now = q.front();
|
|
|
q.pop();
|
|
|
Now->clearCell_();
|
|
|
- f(Now->getleftUp());
|
|
|
- f(Now->getleft());
|
|
|
- f(Now->getleftDown());
|
|
|
- f(Now->getrightUp());
|
|
|
- f(Now->getright());
|
|
|
- f(Now->getrightDown());
|
|
|
+ f(Now->getleftUp(), Now);
|
|
|
+ f(Now->getleft(), Now);
|
|
|
+ f(Now->getleftDown(), Now);
|
|
|
+ f(Now->getrightUp(), Now);
|
|
|
+ f(Now->getright(), Now);
|
|
|
+ f(Now->getrightDown(), Now);
|
|
|
}
|
|
|
}
|
|
|
|
|
|
-void Cell::handleAllMoveableCellsAndUnmoveableCells_(std::queue<Cell*> & Q) {
|
|
|
+void Cell::recalcAttackable_(Cell * Now){
|
|
|
+ if(Now == nullptr)return;
|
|
|
+ if (!isEmpty() && !Now->isEmpty() &&
|
|
|
+ getCharacter()->CanAttackForDistance<"Melee">(Now->getdistance_barrier())
|
|
|
+ ) {
|
|
|
+ Now->setisMeleeAttackAble(true);
|
|
|
+ }
|
|
|
+ if (!isEmpty() && !Now->isEmpty() &&
|
|
|
+ getCharacter()->CanAttackForDistance<"Range">(Now->getdistance_barrier())
|
|
|
+ ) {
|
|
|
+ Now->setisRangeAttackAble(true);
|
|
|
+ }
|
|
|
+}
|
|
|
+
|
|
|
+void Cell::recalcMoveable_(Cell * Now){
|
|
|
+ if(Now == nullptr || Now->isEmpty() || isEmpty())return;
|
|
|
+ getCharacter()->CanMoveForDistance()
|
|
|
+}
|
|
|
+
|
|
|
+void Cell::updateMoveableCells_(std::queue<Cell*> & Q) {
|
|
|
std::queue<Cell*> q;
|
|
|
q.push(this);
|
|
|
- setDistance(0);
|
|
|
+ setdistance_barrier(0);
|
|
|
auto f = [&q, &Q](Cell * t, Cell * parent) {
|
|
|
if (t && !t->AddedToQuery_) {
|
|
|
t->AddedToQuery_ = true;
|
|
|
if (t->getCharacter() != NULL) {
|
|
|
- t->setisMoveable(false);
|
|
|
Q.push(t);
|
|
|
return;
|
|
|
}
|
|
|
q.push(t);
|
|
|
- t->setDistance(parent->getDistance() + 1);
|
|
|
+ t->setdistance_barrier(
|
|
|
+ parent->getdistance_barrier() + 1
|
|
|
+ );
|
|
|
}
|
|
|
};
|
|
|
while (!q.empty()) {
|
|
|
Cell * Now = q.front();
|
|
|
- Now->setisMoveable(true);
|
|
|
- if (getCharacter() != NULL && getCharacter()->СanAttack(Now->getDistance())) {
|
|
|
- Now->setisAttackable(true);
|
|
|
- }
|
|
|
- else {
|
|
|
- Now->setisAttackable(false);
|
|
|
- }
|
|
|
+ Now->setisMoveAble();
|
|
|
+ recalcAttackable_(Now);
|
|
|
q.pop();
|
|
|
f(Now->getleftUp(), Now);
|
|
|
f(Now->getleft(), Now);
|
|
@@ -150,7 +262,7 @@ void Cell::handleAllMoveableCellsAndUnmoveableCells_(std::queue<Cell*> & Q) {
|
|
|
}
|
|
|
}
|
|
|
|
|
|
-void Cell::handleAllUnmoveableCells_(std::queue<Cell*> & Q) {
|
|
|
+void Cell::updateUnMovealeCells_(std::queue<Cell*> & Q) {
|
|
|
auto f = [&Q](Cell * t, Cell * parent) {
|
|
|
if (t && !t->AddedToQuery_) {
|
|
|
t->AddedToQuery_ = true;
|
|
@@ -170,32 +282,3 @@ void Cell::handleAllUnmoveableCells_(std::queue<Cell*> & Q) {
|
|
|
f(Now->getrightDown(), Now);
|
|
|
}
|
|
|
}
|
|
|
-
|
|
|
-void Cell::RecalculateTableWithCenterThisPoint() {
|
|
|
- clearTable_();
|
|
|
- std::queue<Cell*> qWithoutMoveable;
|
|
|
- handleAllMoveableCellsAndUnmoveableCells_(qWithoutMoveable);
|
|
|
- handleAllUnmoveableCells_(qWithoutMoveable);
|
|
|
-}
|
|
|
-
|
|
|
-std::vector <Cell*> Cell::actualPath(Cell* to) {//std::vector<Cell*> âêëþ÷àåòñÿ â ñåáÿ è this, è end
|
|
|
- if (!to || !to->getisMoveable())return std::vector<Cell*>();
|
|
|
- auto ret = std::vector<Cell*>(1, to);
|
|
|
- while (to != this) {
|
|
|
- Cell * parent = NULL;
|
|
|
- auto f = [&parent](Cell * TestParent, Cell * Now) {
|
|
|
- if (TestParent && TestParent->getDistance() + 1 == Now->getDistance() && TestParent->getisMoveable()) {
|
|
|
- parent = TestParent;
|
|
|
- }
|
|
|
- };
|
|
|
- f(to->getleftUp(), to);
|
|
|
- f(to->getleft(), to);
|
|
|
- f(to->getleftDown(), to);
|
|
|
- f(to->getrightUp(), to);
|
|
|
- f(to->getright(), to);
|
|
|
- f(to->getrightDown(), to);
|
|
|
- to = parent;
|
|
|
- ret.push_back(to);
|
|
|
- }
|
|
|
- return ret;
|
|
|
-}
|