ソースを参照

* fixed mana limit info in the hero window
* added support for Scholar object
* possibly fixed problems with handling obstacles info

Michał W. Urbańczyk 16 年 前
コミット
e3222fd34f
6 ファイル変更88 行追加27 行削除
  1. 1 1
      CHeroWindow.cpp
  2. 78 2
      hch/CObjectHandler.cpp
  3. 5 7
      hch/CObjectHandler.h
  4. 1 0
      lib/VCMI_Lib.cpp
  5. 2 16
      map.cpp
  6. 1 1
      server/CGameHandler.cpp

+ 1 - 1
CHeroWindow.cpp

@@ -254,7 +254,7 @@ void CHeroWindow::setHero(const CGHeroInstance *Hero)
 	sprintf(bufor, CGI->generaltexth->allTexts[2].c_str(), hero->level, CGI->heroh->reqExp(hero->level+1), hero->exp);
 	expArea->text = std::string(bufor);
 
-	sprintf(bufor, CGI->generaltexth->allTexts[205].substr(1, CGI->generaltexth->allTexts[205].size()-2).c_str(), hero->name.c_str(), hero->mana, hero->getPrimSkillLevel(3)*10);
+	sprintf(bufor, CGI->generaltexth->allTexts[205].substr(1, CGI->generaltexth->allTexts[205].size()-2).c_str(), hero->name.c_str(), hero->mana, hero->manaLimit());
 	spellPointsArea->text = std::string(bufor);
 
 	for(size_t g=0; g<artWorn.size(); ++g)

+ 78 - 2
hch/CObjectHandler.cpp

@@ -363,7 +363,7 @@ ui8 CGHeroInstance::getSecSkillLevel(const int & ID) const
 }
 int CGHeroInstance::maxMovePoints(bool onLand) const
 {
-	int ret = std::max(2000, 1270+70*lowestSpeed(this)),
+	int ret = std::min(2000, 1270+70*lowestSpeed(this)),
 		bonus = valOfBonuses(HeroBonus::MOVEMENT) + (onLand ? valOfBonuses(HeroBonus::LAND_MOVEMENT) : valOfBonuses(HeroBonus::SEA_MOVEMENT));
 
 	double modifier = 0;
@@ -1206,6 +1206,7 @@ void CGCreature::endBattle( BattleResult *result ) const
 
 void CGCreature::initObj()
 {
+	blockVisit = true;
 	army.slots[0].first = subID;
 	si32 &amount = army.slots[0].second;
 	CCreature &c = VLC->creh->creatures[subID];
@@ -2028,4 +2029,79 @@ void CGSignBottle::onHeroVisit( const CGHeroInstance * h ) const
 	iw.player = h->getOwner();
 	iw.text << message;
 	cb->showInfoDialog(&iw);
-}
+}
+
+void CGScholar::giveAnyBonus( const CGHeroInstance * h ) const
+{
+
+}
+
+void CGScholar::onHeroVisit( const CGHeroInstance * h ) const
+{
+
+	int type = bonusType;
+	int bid = bonusID;
+	//check if the bonus if applicable, if not - give primary skill (always possible)
+	int ssl = h->getSecSkillLevel(bid); //current sec skill level, used if bonusType == 1
+	if((type == 1
+			&& ((ssl == 3)  ||  (!ssl  &&  h->secSkills.size() == SKILL_PER_HERO))) ////hero already has expert level in the skill or (don't know skill and doesn't have free slot)
+		|| (type == 2  &&  (!h->getArt(17) || vstd::contains(h->spells,bid)))) //hero doesn't have a spellbook or already knows the spell
+	{
+		type = 0;
+		bid = ran() % PRIMARY_SKILLS;
+	}
+
+
+	InfoWindow iw;
+	iw.player = h->getOwner();
+	iw.text.addTxt(MetaString::ADVOB_TXT,115);
+
+	switch (type)
+	{
+	case 0:
+		cb->changePrimSkill(h->id,bid,+1);
+		iw.components.push_back(Component(Component::PRIM_SKILL,bid,1,0));
+		break;
+	case 1:
+		{
+			cb->changeSecSkill(h->id,bid,ssl+1);
+			iw.components.push_back(Component(Component::SEC_SKILL,bid,ssl+1,0));
+		}
+		break;
+	case 2:
+		{
+			std::set<ui32> hlp;
+			hlp.insert(bid);
+			cb->changeSpells(h->id,true,hlp);
+			iw.components.push_back(Component(Component::SPELL,bid,0,0));
+		}
+		break;
+	default:
+		tlog1 << "Error: wrong bonustype (" << (int)type << ") for Scholar!\n";
+		return;
+	}
+
+	cb->showInfoDialog(&iw);
+	cb->removeObject(id);
+}
+
+void CGScholar::initObj()
+{
+	blockVisit = true;
+	if(bonusType == 255)
+	{
+		bonusType = ran()%3;
+		switch(bonusType)
+		{
+		case 0:
+			bonusID = ran() % PRIMARY_SKILLS;
+			break;
+		case 1:
+			bonusID = ran() % SKILL_QUANTITY;
+			break;
+		case 2:
+			bonusID = ran() % SPELLS_QUANTITY;
+			break;
+		}
+	}
+}

+ 5 - 7
hch/CObjectHandler.h

@@ -234,8 +234,6 @@ public:
 	bool needsLastStack()const;
 	unsigned int getTileCost(const TerrainTile &dest, const TerrainTile &from) const; //move cost - applying pathfinding skill, road and terrain modifiers. NOT includes diagonal move penalty, last move levelling
 	unsigned int getLowestCreatureSpeed() const;
-	unsigned int getAdditiveMoveBonus() const;
-	float getMultiplicativeMoveBonus() const;
 	int3 getPosition(bool h3m) const; //h3m=true - returns position of hero object; h3m=false - returns position of hero 'manifestation'
 	si32 manaLimit() const; //maximum mana value for this hero (basically 10*knowledge)
 	si32 manaRegain() const; //how many points of mana can hero regain "naturally" in one day
@@ -470,15 +468,15 @@ class DLL_EXPORT CGScholar : public CGObjectInstance
 {
 public:
 	ui8 bonusType; //255 - random, 0 - primary skill, 1 - secondary skill, 2 - spell
+	ui16 bonusID; //ID of skill/spell
 
-	ui8 r0type;
-	ui32 r1; //Ability ID
-	ui32 r2; //Spell ID
-
+	void giveAnyBonus(const CGHeroInstance * h) const;
+	void onHeroVisit(const CGHeroInstance * h) const;
+	void initObj();
 	template <typename Handler> void serialize(Handler &h, const int version)
 	{
 		h & static_cast<CGObjectInstance&>(*this);
-		h & bonusType & r0type & r1 & r2;
+		h & bonusType & id;
 	}
 };
 

+ 1 - 0
lib/VCMI_Lib.cpp

@@ -24,6 +24,7 @@ DLL_EXPORT std::ostream *logfile = NULL
 ;
 DLL_EXPORT void initDLL(CLodHandler *b, CConsoleHandler *Console, std::ostream *Logfile)
 {
+	srand(time(NULL));
 	console = Console;
 	logfile = Logfile;
 	bitmaph=b;

+ 2 - 16
map.cpp

@@ -1536,22 +1536,8 @@ void Mapa::readObjects( unsigned char * bufor, int &i)
 			{
 				CGScholar *sch = new CGScholar();
 				nobj = sch;
-				sch->bonusType = bufor[i]; ++i;
-				switch(sch->bonusType)
-				{
-				case 0xff:
-					++i;
-					break;
-				case 0:
-					sch->r0type = bufor[i]; ++i;
-					break;
-				case 1:
-					sch->r1 = bufor[i]; ++i;
-					break;
-				case 2:
-					sch->r2 = bufor[i]; ++i;
-					break;
-				}
+				sch->bonusType = bufor[i++];
+				sch->bonusID = bufor[i++];
 				i+=6;
 				break;
 			}

+ 1 - 1
server/CGameHandler.cpp

@@ -972,7 +972,7 @@ void CGameHandler::setupBattle( BattleInfo * curB, int3 tile, CCreatureSet &army
 
 	for(std::map<int, CObstacleInfo>::const_iterator g=VLC->heroh->obstacles.begin(); g!=VLC->heroh->obstacles.end(); ++g)
 	{
-		if(g->second.allowedTerrains[terType] == '1')
+		if(g->second.allowedTerrains[terType-1] == '1') //we need to take terType with -1 because terrain ids start from 1 and allowedTerrains array is indexed from 0
 		{
 			possibleObstacles.push_back(g->first);
 		}