浏览代码

* some stuff with pathfinding (some functions need to be written, maybe someone help me?)
* CGI is now defined in global.h
* some code improvements

mateuszb 18 年之前
父节点
当前提交
8cc7e103bd
共有 16 个文件被更改,包括 224 次插入51 次删除
  1. 5 0
      CAdvmapInterface.cpp
  2. 2 3
      CAdvmapInterface.h
  3. 12 1
      CAmbarCendamo.cpp
  4. 15 2
      CHeroHandler.cpp
  5. 7 1
      CHeroHandler.h
  6. 0 1
      CMessage.cpp
  7. 1 1
      CMessage.h
  8. 0 2
      CObjectHandler.cpp
  9. 133 32
      CPathfinder.cpp
  10. 4 6
      CPathfinder.h
  11. 二进制
      CPreGame.cpp
  12. 0 2
      CTownHandler.cpp
  13. 2 0
      global.h
  14. 40 0
      mapHandler.cpp
  15. 2 0
      mapHandler.h
  16. 1 0
      stdafx.h

+ 5 - 0
CAdvmapInterface.cpp

@@ -1,6 +1,11 @@
 #include "stdafx.h"
 #include "CAdvmapInterface.h"
+
 extern TTF_Font * TNRB16, *TNR, *GEOR13, *GEORXX; //fonts
+
+using namespace boost::logic;
+using namespace CSDL_Ext;
+
 CAdvMapInt::~CAdvMapInt()
 {
 	SDL_FreeSurface(bg);

+ 2 - 3
CAdvmapInterface.h

@@ -8,9 +8,8 @@
 #include "CGameInfo.h"
 #include "SDL_Extensions.h"
 #include <boost/logic/tribool.hpp>
-using namespace boost::logic;
-#define CGI (CGameInfo::mainObj)
-using namespace CSDL_Ext;
+#include "global.h"
+
 class AdventureMapButton 
 	: public ClickableL, public ClickableR, public Hoverable, public KeyInterested, public CButtonBase
 {

+ 12 - 1
CAmbarCendamo.cpp

@@ -9,7 +9,6 @@
 #include <set>
 #include <iomanip>
 #include <sstream>
-#define CGI (CGameInfo::mainObj)
 
 unsigned int intPow(unsigned int a, unsigned int b)
 {
@@ -782,6 +781,18 @@ void CAmbarCendamo::deh3m()
 				}
 				i+=16;
 				nobj->info = spec;
+				//////creating CHeroInstance
+				CHeroInstance * nhi = new CHeroInstance;
+				nhi->exp = spec->experience;
+				nhi->level = CGI->heroh->level(nhi->exp);
+				nhi->mana = spec->knowledge * 10;
+				nhi->movement = -1;
+				nhi->name = spec->name;
+				nhi->owner = spec->player;
+				nhi->pos = nobj->pos;
+				nhi->type = spec->type;
+				nhi->army = spec->garrison;
+				CGI->heroh->heroInstances.push_back(nhi);
 				break;
 			}
 		case CREATURES_DEF:

+ 15 - 2
CHeroHandler.cpp

@@ -5,8 +5,6 @@
 #include "CGameInfo.h"
 #include "CGeneralTextHandler.h"
 
-#define CGI (CGameInfo::mainObj)
-
 CHeroHandler::~CHeroHandler()
 {
 	for (int j=0;j<heroes.size();j++)
@@ -320,3 +318,18 @@ void CHeroHandler::initHeroClasses()
 		heroes[gg]->heroClass = heroClasses[heroes[gg]->heroType];
 	}
 }
+
+unsigned int CHeroInstance::getTileCost(EterrainType & ttype, Eroad & rdtype, Eriver & rvtype)
+{
+	return 100; //TODO: finish it
+}
+
+unsigned int CHeroHandler::level(unsigned int experience)
+{
+	return 0; //TODO: finish it
+}
+
+unsigned int CHeroInstance::getLowestCreatureSpeed()
+{
+	return 1; //TODO: finish it
+}

+ 7 - 1
CHeroHandler.h

@@ -44,7 +44,7 @@ class CHeroInstance
 {
 public:
 	int owner;
-	CHero type;
+	CHero * type;
 	int exp; //experience point
 	int level; //current level of hero
 	std::string name; //may be custom
@@ -54,6 +54,10 @@ public:
 	CCreatureSet army; //army
 	int mana; // remaining spell points
 	int movement; //remaining movement points
+	unsigned int getTileCost(EterrainType & ttype, Eroad & rdtype, Eriver & rvtype);
+	unsigned int getLowestCreatureSpeed();
+	unsigned int getAdditiveMoveBonus();
+	unsigned float getMultiplicativeMoveBonus();
 	//TODO: artifacts, primary and secondary skills, known spells, commander, blessings, curses, morale/luck special modifiers
 };
 
@@ -62,6 +66,8 @@ class CHeroHandler
 public:
 	std::vector<CHero*> heroes; //by³o nodrze
 	std::vector<CHeroClass *> heroClasses;
+	std::vector<CHeroInstance *> heroInstances;
+	unsigned int level(unsigned int experience);
 	void loadHeroes();
 	void loadSpecialAbilities();
 	void loadBiographies();

+ 0 - 1
CMessage.cpp

@@ -5,7 +5,6 @@
 #include "CDefHandler.h"
 #include "CGameInfo.h"
 #include "SDL_Extensions.h"
-#define CGI (CGameInfo::mainObj)
 
 SDL_Color tytulowy, tlo, zwykly ;
 SDL_Rect genRect(int hh, int ww, int xx, int yy);

+ 1 - 1
CMessage.h

@@ -1,6 +1,7 @@
 #ifndef CMESSAGE_H
 #define CMESSAGE_H
 
+#include "global.h"
 #include "SDL_TTF.h"
 #include "SDL.h"
 #include "CSemiDefHandler.h"
@@ -8,7 +9,6 @@
 #include "CGameInterface.h"
 #include "CGameInfo.h"
 #include "SDL_Extensions.h"
-#define CGI (CGameInfo::mainObj)
 enum EWindowType {infoOnly, infoOK, yesOrNO};
 class CPreGame;
 class MapSel;

+ 0 - 2
CObjectHandler.cpp

@@ -3,8 +3,6 @@
 #include "CGameInfo.h"
 #include "CGeneralTextHandler.h"
 
-#define CGI (CGameInfo::mainObj)
-
 void CObjectHandler::loadObjects()
 {
 	int ID=0;

+ 133 - 32
CPathfinder.cpp

@@ -2,9 +2,7 @@
 #include "global.h"
 #include "CPathfinder.h"
 
-#define CGI (CGameInfo::mainObj)
-
-CPath * CPathfinder::getPath(int3 &src, int3 &dest)
+CPath * CPathfinder::getPath(int3 &src, int3 &dest, CHeroInstance * hero) //TODO: test it (seems to be finished, but relies on unwritten functions :()
 {
 	if(src.z!=dest.z) //first check
 		return NULL;
@@ -16,50 +14,153 @@ CPath * CPathfinder::getPath(int3 &src, int3 &dest)
 		graph[i].resize(CGI->ac->map.height);
 		for(int j=0; j<graph[i].size(); ++j)
 		{
-			graph[i][j].accesible = true;
-			graph[i][j].dist = -1;
-			graph[i][j].theNodeBefore = NULL;
-			graph[i][j].x = i;
-			graph[i][j].y = j;
+			graph[i][j] = new CPathNode;
+			graph[i][j]->accesible = !CGI->mh->ttiles[i][j][src.z].blocked;
+			graph[i][j]->dist = -1;
+			graph[i][j]->theNodeBefore = NULL;
+			graph[i][j]->visited = false;
+			graph[i][j]->x = i;
+			graph[i][j]->y = j;
 		}
 	}
 
-	for(int h=0; h<CGI->objh->objInstances.size(); ++h)
+	//graph initialized
+
+	graph[src.x][src.y]->dist = 0;
+
+	std::queue<CPathNode *> mq;
+	mq.push(graph[src.x][src.y]);
+	while(!mq.empty())
 	{
-		if(CGI->objh->objInstances[h]->pos.z == src.z)
+		CPathNode * cp = mq.front();
+		mq.pop();
+		if(cp->x>0)
+		{
+			CPathNode * dp = graph[cp->x-1][cp->y];
+			if(!dp->visited)
+			{
+				if(dp->dist==-1 || (dp->dist > cp->dist + CGI->mh->getCost(int3(cp->x, cp->y, src.z), int3(cp->x-1, cp->y, src.z), hero)))
+				{
+					dp->dist = cp->dist + CGI->mh->getCost(int3(cp->x, cp->y, src.z), int3(cp->x-1, cp->y, src.z), hero);
+					dp->theNodeBefore = cp;
+					mq.push(dp);
+				}
+			}
+		}
+		if(cp->y>0)
+		{
+			CPathNode * dp = graph[cp->x][cp->y-1];
+			if(!dp->visited)
+			{
+				if(dp->dist==-1 || (dp->dist > cp->dist + CGI->mh->getCost(int3(cp->x, cp->y, src.z), int3(cp->x, cp->y-1, src.z), hero)))
+				{
+					dp->dist = cp->dist + CGI->mh->getCost(int3(cp->x, cp->y, src.z), int3(cp->x-1, cp->y, src.z), hero);
+					dp->theNodeBefore = cp;
+					mq.push(dp);
+					dp->visited = true;
+				}
+			}
+		}
+		if(cp->x>0 && cp->y>0)
+		{
+			CPathNode * dp = graph[cp->x-1][cp->y-1];
+			if(!dp->visited)
+			{
+				if(dp->dist==-1 || (dp->dist > cp->dist + CGI->mh->getCost(int3(cp->x, cp->y, src.z), int3(cp->x-1, cp->y-1, src.z), hero)))
+				{
+					dp->dist = cp->dist + CGI->mh->getCost(int3(cp->x, cp->y, src.z), int3(cp->x-1, cp->y-1, src.z), hero);
+					dp->theNodeBefore = cp;
+					mq.push(dp);
+					dp->visited = true;
+				}
+			}
+		}
+		if(cp->x<graph.size()-1)
+		{
+			CPathNode * dp = graph[cp->x+1][cp->y];
+			if(!dp->visited)
+			{
+				if(dp->dist==-1 || (dp->dist > cp->dist + CGI->mh->getCost(int3(cp->x, cp->y, src.z), int3(cp->x+1, cp->y, src.z), hero)))
+				{
+					dp->dist = cp->dist + CGI->mh->getCost(int3(cp->x, cp->y, src.z), int3(cp->x+1, cp->y, src.z), hero);
+					dp->theNodeBefore = cp;
+					mq.push(dp);
+					dp->visited = true;
+				}
+			}
+		}
+		if(cp->y<graph[0].size()-1)
 		{
-			unsigned char blockMap[6];
-			std::string ourName = CGI->ac->map.defy[CGI->objh->objInstances[h]->defNumber].name;
-			std::transform(ourName.begin(), ourName.end(), ourName.begin(), (int(*)(int))toupper);
-			for(int y=0; y<CGI->dobjinfo->objs.size(); ++y)
+			CPathNode * dp = graph[cp->x][cp->y+1];
+			if(!dp->visited)
 			{
-				std::string cName = CGI->dobjinfo->objs[y].defName;
-				std::transform(cName.begin(), cName.end(), cName.begin(), (int(*)(int))toupper);
-				if(cName==ourName)
+				if(dp->dist==-1 || (dp->dist > cp->dist + CGI->mh->getCost(int3(cp->x, cp->y, src.z), int3(cp->x, cp->y+1, src.z), hero)))
 				{
-					for(int u=0; u<6; ++u)
-					{
-						blockMap[u] = CGI->dobjinfo->objs[y].blockMap[u];
-					}
-					break;
+					dp->dist = cp->dist + CGI->mh->getCost(int3(cp->x, cp->y, src.z), int3(cp->x, cp->y+1, src.z), hero);
+					dp->theNodeBefore = cp;
+					mq.push(dp);
+					dp->visited = true;
 				}
 			}
-			for(int i=0; i<6; ++i)
+		}
+		if(cp->x<graph.size() && cp->y<graph[0].size())
+		{
+			CPathNode * dp = graph[cp->x+1][cp->y+1];
+			if(!dp->visited)
 			{
-				for(int j=0; j<8; ++j)
+				if(dp->dist==-1 || (dp->dist > cp->dist + CGI->mh->getCost(int3(cp->x, cp->y, src.z), int3(cp->x+1, cp->y+1, src.z), hero)))
 				{
-					int cPosX = CGI->objh->objInstances[h]->pos.x - j;
-					int cPosY = CGI->objh->objInstances[h]->pos.y - i;
-					if(cPosX>0 && cPosY>0)
-					{
-						graph[cPosX][cPosY].accesible = blockMap[i] & (128 >> j);
-					}
+					dp->dist = cp->dist + CGI->mh->getCost(int3(cp->x, cp->y, src.z), int3(cp->x+1, cp->y+1, src.z), hero);
+					dp->theNodeBefore = cp;
+					mq.push(dp);
+					dp->visited = true;
+				}
+			}
+		}
+		if(cp->x>0 && cp->y<graph[0].size())
+		{
+			CPathNode * dp = graph[cp->x-1][cp->y+1];
+			if(!dp->visited)
+			{
+				if(dp->dist==-1 || (dp->dist > cp->dist + CGI->mh->getCost(int3(cp->x, cp->y, src.z), int3(cp->x-1, cp->y+1, src.z), hero)))
+				{
+					dp->dist = cp->dist + CGI->mh->getCost(int3(cp->x, cp->y, src.z), int3(cp->x-1, cp->y+1, src.z), hero);
+					dp->theNodeBefore = cp;
+					mq.push(dp);
+					dp->visited = true;
+				}
+			}
+		}
+		if(cp->x<graph.size() && cp->y>0)
+		{
+			CPathNode * dp = graph[cp->x+1][cp->y-1];
+			if(!dp->visited)
+			{
+				if(dp->dist==-1 || (dp->dist > cp->dist + CGI->mh->getCost(int3(cp->x, cp->y, src.z), int3(cp->x+1, cp->y-1, src.z), hero)))
+				{
+					dp->dist = cp->dist + CGI->mh->getCost(int3(cp->x, cp->y, src.z), int3(cp->x+1, cp->y-1, src.z), hero);
+					dp->theNodeBefore = cp;
+					mq.push(dp);
+					dp->visited = true;
 				}
 			}
 		}
 	}
-	//graph initialized
 
+	CPathNode * curNode = graph[dest.x][dest.y];
+	CPath * ret = new CPath;
+
+	while(curNode!=graph[src.x][src.y] && curNode != NULL)
+	{
+		ret->nodes.push(*curNode);
+		curNode = curNode->theNodeBefore;
+	}
+
+	for(int i=0; i<graph.size(); ++i)
+	{
+		for(int j=0; j<graph[0].size(); ++i)
+			delete graph[i][j];
+	}
 
-	return NULL;
+	return ret;
 }

+ 4 - 6
CPathfinder.h

@@ -7,13 +7,11 @@
 
 struct CPathNode
 {
-	bool v1, v2, v3,
-		 v4,     v5,
-		 v6, v7, v8; //true if we can pass, false if not
 	bool accesible; //true if a hero can be on this node
 	int dist; //distance from the first node of searching; -1 is infinity
 	CPathNode * theNodeBefore;
 	int x, y; //coordiantes
+	bool visited;
 };
 
 struct CPath
@@ -27,10 +25,10 @@ struct CPath
 class CPathfinder
 {
 private:
-	std::vector< std::vector<CPathNode> > graph;
+	std::vector< std::vector<CPathNode *> > graph;
 public:
-	CPath * getPath(int3 & src, int3 & dest); //calculates path between src and dest; returns pointer to CPath or NULL if path does not exists
-	CPath * getPath(int3 & src, int3 & dest, int (*getDist)(int3 & a, int3 b)); //calculates path between src and dest; returns pointer to CPath or NULL if path does not exists; uses getDist to calculate distance
+	CPath * getPath(int3 & src, int3 & dest, CHeroInstance * hero); //calculates path between src and dest; returns pointer to CPath or NULL if path does not exists
+	CPath * getPath(int3 & src, int3 & dest, CHeroInstance * hero, int (*getDist)(int3 & a, int3 b)); //calculates path between src and dest; returns pointer to CPath or NULL if path does not exists; uses getDist to calculate distance
 };
 
 #endif //CPATHFINDER_H

二进制
CPreGame.cpp


+ 0 - 2
CTownHandler.cpp

@@ -2,8 +2,6 @@
 #include "CTownHandler.h"
 #include "CGameInfo.h"
 #include <sstream>
-#define CGI (CGameInfo::mainObj)
-
 
 CTownHandler::CTownHandler()
 {

+ 2 - 0
global.h

@@ -36,6 +36,8 @@ const int HEROES_QUANTITY=156;
 #define MARK_BLOCKED_POSITIONS false
 #define MARK_VISITABLE_POSITIONS false
 
+#define CGI (CGameInfo::mainObj)
+
 
 
 #define DEFBYPASS

+ 40 - 0
mapHandler.cpp

@@ -824,3 +824,43 @@ char & CMapHandler::undVisAccess(int x, int y)
 {
 	return undVisibility[x+Woff][y+Hoff];
 }
+
+int CMapHandler::getCost(int3 &a, int3 &b, CHeroInstance *hero)
+{
+	int ret = 1500; //basic value
+	switch(hero->getLowestCreatureSpeed())
+	{
+	case 0: case 1: case 2: case 3: case 4:
+		{
+			ret+=0;
+			break;
+		}
+	case 5:
+		{
+			ret+=100;
+			break;
+		}
+	case 6: case 7:
+		{
+			ret+=200;
+			break;
+		}
+	case 8:
+		{
+			ret+=300;
+			break;
+		}
+	case 9: case 10:
+		{
+			ret+=400;
+			break;
+		}
+	default:
+		{
+			ret+=500;
+			break;
+		}
+	}
+
+	return ret; //TODO: finish it
+}

+ 2 - 0
mapHandler.h

@@ -55,6 +55,8 @@ public:
 	char & undVisAccess(int x, int y);
 	SDL_Surface mirrorImage(SDL_Surface *src); //what is this??
 	SDL_Surface * getVisBitmap(int x, int y, std::vector< std::vector<char> > & visibility);
+
+	int getCost(int3 & a, int3 & b, CHeroInstance * hero);
 	void init();
 };
 

+ 1 - 0
stdafx.h

@@ -12,4 +12,5 @@
 #include <vector>
 #include <algorithm>
 #include <fstream>
+#include "global.h"
 // TODO: reference additional headers your program requires here