Ver Fonte

* better new hero initialization
* faster pathfinder

mateuszb há 17 anos atrás
pai
commit
2f6ec1f7eb
4 ficheiros alterados com 74 adições e 72 exclusões
  1. 64 70
      CPathfinder.cpp
  2. 1 1
      CPathfinder.h
  3. 3 1
      hch/CObjectHandler.cpp
  4. 6 0
      mapHandler.cpp

+ 64 - 70
CPathfinder.cpp

@@ -49,149 +49,143 @@ CPath * CPathfinder::getPath(int3 src, int3 dest, const CGHeroInstance * hero, u
 		graph[i].resize(CGI->ac->map.height);
 		for(int j=0; j<graph[i].size(); ++j)
 		{
-			graph[i][j] = new CPathNode;
-			graph[i][j]->accesible = !CGI->mh->ttiles[i][j][src.z].blocked;
+			graph[i][j].accesible = !CGI->mh->ttiles[i][j][src.z].blocked;
 			if(i==dest.x && j==dest.y && CGI->mh->ttiles[i][j][src.z].visitable)
-				graph[i][j]->accesible = true; //for allowing visiting objects
-			graph[i][j]->dist = -1;
-			graph[i][j]->theNodeBefore = NULL;
-			graph[i][j]->visited = false;
-			graph[i][j]->coord.x = i;
-			graph[i][j]->coord.y = j;
-			graph[i][j]->coord.z = dest.z;
+				graph[i][j].accesible = true; //for allowing visiting objects
+			graph[i][j].dist = -1;
+			graph[i][j].theNodeBefore = NULL;
+			graph[i][j].visited = false;
+			graph[i][j].coord.x = i;
+			graph[i][j].coord.y = j;
+			graph[i][j].coord.z = dest.z;
 			if (CGI->mh->ttiles[i][j][src.z].terType==EterrainType::rock)
-				graph[i][j]->accesible = false;
+				graph[i][j].accesible = false;
 			if ((blockLandSea) && (CGI->mh->ttiles[i][j][src.z].terType==EterrainType::water))
-				graph[i][j]->accesible = false;
+				graph[i][j].accesible = false;
 			else if ((!blockLandSea) && (CGI->mh->ttiles[i][j][src.z].terType!=EterrainType::water))
-				graph[i][j]->accesible = false;
+				graph[i][j].accesible = false;
 		}
 	}
 
 	//graph initialized
 
-	graph[src.x][src.y]->dist = 0;
+	graph[src.x][src.y].dist = 0;
 
-	std::queue<CPathNode *> mq;
+	std::queue<CPathNode> mq;
 	mq.push(graph[src.x][src.y]);
 
 	unsigned int curDist = 4000000000;
 
 	while(!mq.empty())
 	{
-		CPathNode * cp = mq.front();
+		CPathNode cp = mq.front();
 		mq.pop();
-		if ((cp->coord.x == dest.x) && (cp->coord.y==dest.y))
+		if ((cp.coord.x == dest.x) && (cp.coord.y==dest.y))
 		{
-			if (cp->dist < curDist)
-				curDist=cp->dist;
+			if (cp.dist < curDist)
+				curDist=cp.dist;
 		}
 		else
 		{
-			if (cp->dist > curDist)
+			if (cp.dist > curDist)
 				continue;
 		}
-		if(cp->coord.x>0)
+		if(cp.coord.x>0)
 		{
-			CPathNode * dp = graph[cp->coord.x-1][cp->coord.y];
-			if((dp->dist==-1 || (dp->dist > cp->dist + CGI->mh->getCost(int3(cp->coord.x, cp->coord.y, src.z), int3(cp->coord.x-1, cp->coord.y, src.z), hero))) && dp->accesible)
+			CPathNode & dp = graph[cp.coord.x-1][cp.coord.y];
+			if((dp.dist==-1 || (dp.dist > cp.dist + CGI->mh->getCost(int3(cp.coord.x, cp.coord.y, src.z), int3(cp.coord.x-1, cp.coord.y, src.z), hero))) && dp.accesible)
 			{
-				dp->dist = cp->dist + CGI->mh->getCost(int3(cp->coord.x, cp->coord.y, src.z), int3(cp->coord.x-1, cp->coord.y, src.z), hero);
-				dp->theNodeBefore = cp;
+				dp.dist = cp.dist + CGI->mh->getCost(int3(cp.coord.x, cp.coord.y, src.z), int3(cp.coord.x-1, cp.coord.y, src.z), hero);
+				dp.theNodeBefore = &graph[cp.coord.x][cp.coord.y];
 				mq.push(dp);
 			}
 		}
-		if(cp->coord.y>0)
+		if(cp.coord.y>0)
 		{
-			CPathNode * dp = graph[cp->coord.x][cp->coord.y-1];
-			if((dp->dist==-1 || (dp->dist > cp->dist + CGI->mh->getCost(int3(cp->coord.x, cp->coord.y, src.z), int3(cp->coord.x, cp->coord.y-1, src.z), hero))) && dp->accesible)
+			CPathNode & dp = graph[cp.coord.x][cp.coord.y-1];
+			if((dp.dist==-1 || (dp.dist > cp.dist + CGI->mh->getCost(int3(cp.coord.x, cp.coord.y, src.z), int3(cp.coord.x, cp.coord.y-1, src.z), hero))) && dp.accesible)
 			{
-				dp->dist = cp->dist + CGI->mh->getCost(int3(cp->coord.x, cp->coord.y, src.z), int3(cp->coord.x-1, cp->coord.y, src.z), hero);
-				dp->theNodeBefore = cp;
+				dp.dist = cp.dist + CGI->mh->getCost(int3(cp.coord.x, cp.coord.y, src.z), int3(cp.coord.x-1, cp.coord.y, src.z), hero);
+				dp.theNodeBefore = &graph[cp.coord.x][cp.coord.y];
 				mq.push(dp);
 			}
 		}
-		if(cp->coord.x>0 && cp->coord.y>0)
+		if(cp.coord.x>0 && cp.coord.y>0)
 		{
-			CPathNode * dp = graph[cp->coord.x-1][cp->coord.y-1];
-			if((dp->dist==-1 || (dp->dist > cp->dist + CGI->mh->getCost(int3(cp->coord.x, cp->coord.y, src.z), int3(cp->coord.x-1, cp->coord.y-1, src.z), hero))) && dp->accesible)
+			CPathNode & dp = graph[cp.coord.x-1][cp.coord.y-1];
+			if((dp.dist==-1 || (dp.dist > cp.dist + CGI->mh->getCost(int3(cp.coord.x, cp.coord.y, src.z), int3(cp.coord.x-1, cp.coord.y-1, src.z), hero))) && dp.accesible)
 			{
-				dp->dist = cp->dist + CGI->mh->getCost(int3(cp->coord.x, cp->coord.y, src.z), int3(cp->coord.x-1, cp->coord.y-1, src.z), hero);
-				dp->theNodeBefore = cp;
+				dp.dist = cp.dist + CGI->mh->getCost(int3(cp.coord.x, cp.coord.y, src.z), int3(cp.coord.x-1, cp.coord.y-1, src.z), hero);
+				dp.theNodeBefore = &graph[cp.coord.x][cp.coord.y];
 				mq.push(dp);
 			}
 		}
-		if(cp->coord.x<graph.size()-1)
+		if(cp.coord.x<graph.size()-1)
 		{
-			CPathNode * dp = graph[cp->coord.x+1][cp->coord.y];
-			if((dp->dist==-1 || (dp->dist > cp->dist + CGI->mh->getCost(int3(cp->coord.x, cp->coord.y, src.z), int3(cp->coord.x+1, cp->coord.y, src.z), hero))) && dp->accesible)
+			CPathNode & dp = graph[cp.coord.x+1][cp.coord.y];
+			if((dp.dist==-1 || (dp.dist > cp.dist + CGI->mh->getCost(int3(cp.coord.x, cp.coord.y, src.z), int3(cp.coord.x+1, cp.coord.y, src.z), hero))) && dp.accesible)
 			{
-				dp->dist = cp->dist + CGI->mh->getCost(int3(cp->coord.x, cp->coord.y, src.z), int3(cp->coord.x+1, cp->coord.y, src.z), hero);
-				dp->theNodeBefore = cp;
+				dp.dist = cp.dist + CGI->mh->getCost(int3(cp.coord.x, cp.coord.y, src.z), int3(cp.coord.x+1, cp.coord.y, src.z), hero);
+				dp.theNodeBefore = &graph[cp.coord.x][cp.coord.y];
 				mq.push(dp);
 			}
 		}
-		if(cp->coord.y<graph[0].size()-1)
+		if(cp.coord.y<graph[0].size()-1)
 		{
-			CPathNode * dp = graph[cp->coord.x][cp->coord.y+1];
-			if((dp->dist==-1 || (dp->dist > cp->dist + CGI->mh->getCost(int3(cp->coord.x, cp->coord.y, src.z), int3(cp->coord.x, cp->coord.y+1, src.z), hero))) && dp->accesible)
+			CPathNode & dp = graph[cp.coord.x][cp.coord.y+1];
+			if((dp.dist==-1 || (dp.dist > cp.dist + CGI->mh->getCost(int3(cp.coord.x, cp.coord.y, src.z), int3(cp.coord.x, cp.coord.y+1, src.z), hero))) && dp.accesible)
 			{
-				dp->dist = cp->dist + CGI->mh->getCost(int3(cp->coord.x, cp->coord.y, src.z), int3(cp->coord.x, cp->coord.y+1, src.z), hero);
-				dp->theNodeBefore = cp;
+				dp.dist = cp.dist + CGI->mh->getCost(int3(cp.coord.x, cp.coord.y, src.z), int3(cp.coord.x, cp.coord.y+1, src.z), hero);
+				dp.theNodeBefore = &graph[cp.coord.x][cp.coord.y];
 				mq.push(dp);
 			}
 		}
-		if(cp->coord.x<graph.size()-1 && cp->coord.y<graph[0].size()-1)
+		if(cp.coord.x<graph.size()-1 && cp.coord.y<graph[0].size()-1)
 		{
-			CPathNode * dp = graph[cp->coord.x+1][cp->coord.y+1];
-			if((dp->dist==-1 || (dp->dist > cp->dist + CGI->mh->getCost(int3(cp->coord.x, cp->coord.y, src.z), int3(cp->coord.x+1, cp->coord.y+1, src.z), hero))) && dp->accesible)
+			CPathNode & dp = graph[cp.coord.x+1][cp.coord.y+1];
+			if((dp.dist==-1 || (dp.dist > cp.dist + CGI->mh->getCost(int3(cp.coord.x, cp.coord.y, src.z), int3(cp.coord.x+1, cp.coord.y+1, src.z), hero))) && dp.accesible)
 			{
-				dp->dist = cp->dist + CGI->mh->getCost(int3(cp->coord.x, cp->coord.y, src.z), int3(cp->coord.x+1, cp->coord.y+1, src.z), hero);
-				dp->theNodeBefore = cp;
+				dp.dist = cp.dist + CGI->mh->getCost(int3(cp.coord.x, cp.coord.y, src.z), int3(cp.coord.x+1, cp.coord.y+1, src.z), hero);
+				dp.theNodeBefore = &graph[cp.coord.x][cp.coord.y];
 				mq.push(dp);
 			}
 		}
-		if(cp->coord.x>0 && cp->coord.y<graph[0].size()-1)
+		if(cp.coord.x>0 && cp.coord.y<graph[0].size()-1)
 		{
-			CPathNode * dp = graph[cp->coord.x-1][cp->coord.y+1];
-			if((dp->dist==-1 || (dp->dist > cp->dist + CGI->mh->getCost(int3(cp->coord.x, cp->coord.y, src.z), int3(cp->coord.x-1, cp->coord.y+1, src.z), hero))) && dp->accesible)
+			CPathNode & dp = graph[cp.coord.x-1][cp.coord.y+1];
+			if((dp.dist==-1 || (dp.dist > cp.dist + CGI->mh->getCost(int3(cp.coord.x, cp.coord.y, src.z), int3(cp.coord.x-1, cp.coord.y+1, src.z), hero))) && dp.accesible)
 			{
-				dp->dist = cp->dist + CGI->mh->getCost(int3(cp->coord.x, cp->coord.y, src.z), int3(cp->coord.x-1, cp->coord.y+1, src.z), hero);
-				dp->theNodeBefore = cp;
+				dp.dist = cp.dist + CGI->mh->getCost(int3(cp.coord.x, cp.coord.y, src.z), int3(cp.coord.x-1, cp.coord.y+1, src.z), hero);
+				dp.theNodeBefore = &graph[cp.coord.x][cp.coord.y];
 				mq.push(dp);
 			}
 		}
-		if(cp->coord.x<graph.size()-1 && cp->coord.y>0)
+		if(cp.coord.x<graph.size()-1 && cp.coord.y>0)
 		{
-			CPathNode * dp = graph[cp->coord.x+1][cp->coord.y-1];
-			if((dp->dist==-1 || (dp->dist > cp->dist + CGI->mh->getCost(int3(cp->coord.x, cp->coord.y, src.z), int3(cp->coord.x+1, cp->coord.y-1, src.z), hero))) && dp->accesible)
+			CPathNode & dp = graph[cp.coord.x+1][cp.coord.y-1];
+			if((dp.dist==-1 || (dp.dist > cp.dist + CGI->mh->getCost(int3(cp.coord.x, cp.coord.y, src.z), int3(cp.coord.x+1, cp.coord.y-1, src.z), hero))) && dp.accesible)
 			{
-				dp->dist = cp->dist + CGI->mh->getCost(int3(cp->coord.x, cp->coord.y, src.z), int3(cp->coord.x+1, cp->coord.y-1, src.z), hero);
-				dp->theNodeBefore = cp;
+				dp.dist = cp.dist + CGI->mh->getCost(int3(cp.coord.x, cp.coord.y, src.z), int3(cp.coord.x+1, cp.coord.y-1, src.z), hero);
+				dp.theNodeBefore = &graph[cp.coord.x][cp.coord.y];
 				mq.push(dp);
 			}
 		}
 	}
 
-	CPathNode * curNode = graph[dest.x][dest.y];
-	if(!curNode->theNodeBefore)
+	CPathNode curNode = graph[dest.x][dest.y];
+	if(!curNode.theNodeBefore)
 		return NULL;
 
 	CPath * ret = new CPath;
 
-	while(curNode!=graph[src.x][src.y] && curNode != NULL)
+	while(curNode.coord!=graph[src.x][src.y].coord)
 	{
-		ret->nodes.push_back(*curNode);
-		curNode = curNode->theNodeBefore;
+		ret->nodes.push_back(curNode);
+		curNode = *(curNode.theNodeBefore);
 	}
 
-	ret->nodes.push_back(*graph[src.x][src.y]);
+	ret->nodes.push_back(graph[src.x][src.y]);
 
-	for(int i=0; i<graph.size(); ++i)
-	{
-		for(int j=0; j<graph[0].size(); ++j)
-			delete graph[i][j];
-	}
 	return ret;
 }
 

+ 1 - 1
CPathfinder.h

@@ -27,7 +27,7 @@ struct CPath
 class CPathfinder
 {
 private:
-	std::vector< std::vector<CPathNode *> > graph;
+	std::vector< std::vector<CPathNode> > graph;
 public:
 	CPath * getPath(int3 src, int3 dest, const CGHeroInstance * hero, unsigned char type=0); //calculates path between src and dest; returns pointer to CPath or NULL if path does not exists; type - type of calculation: 0 - positions are normal positions of hero; 1 - given places are tiles blocked by hero
 	CPath * getPath(const int3 & src, const int3 & dest, const CGHeroInstance * hero, int (*getDist)(int3 & a, int3 & b), unsigned char type=0); //calculates path between src and dest; returns pointer to CPath or NULL if path does not exists; uses getDist to calculate distance; type - type of calculation: 0 - positions are normal positions of hero; 1 - given places are tiles blocked by hero

+ 3 - 1
hch/CObjectHandler.cpp

@@ -262,7 +262,9 @@ CGObjectInstance::~CGObjectInstance()
 CGHeroInstance::CGHeroInstance()
 {
 	level = exp = -1;
-	moveDir=4;
+	isStanding = true;
+	moveDir = 4;
+	mana = 0;
 }
 
 CGHeroInstance::~CGHeroInstance()

+ 6 - 0
mapHandler.cpp

@@ -1416,6 +1416,12 @@ CGObjectInstance * CMapHandler::createObject(int id, int subid, int3 pos, int ow
 			nobj->artifWorn.resize(20);
 			nobj->artifacts.resize(20);
 			nobj->artifWorn[16] = &CGI->arth->artifacts[3];
+			nobj->primSkills.resize(4);
+			nobj->primSkills[0] = nobj->type->heroClass->initialAttack;
+			nobj->primSkills[1] = nobj->type->heroClass->initialDefence;
+			nobj->primSkills[2] = nobj->type->heroClass->initialPower;
+			nobj->primSkills[3] = nobj->type->heroClass->initialKnowledge;
+			nobj->mana = 10 * nobj->primSkills[3];
 			return nobj;
 		}
 	case 98: //town