瀏覽代碼

Preliminary distribution of hero specials. Sir Mullich actually works fine.

DjWarmonger 15 年之前
父節點
當前提交
742e80b168
共有 6 個文件被更改,包括 354 次插入4 次删除
  1. 176 0
      config/specials.txt
  2. 24 2
      hch/CHeroHandler.cpp
  3. 7 0
      hch/CHeroHandler.h
  4. 134 0
      hch/CObjectHandler.cpp
  5. 1 1
      hch/CObjectHandler.h
  6. 12 1
      lib/HeroBonus.h

+ 176 - 0
config/specials.txt

@@ -0,0 +1,176 @@
+Hero ID	Bonus Type	Val	Subtype	Additional Info
+0	2	1	0	5
+1	1	2	0	0
+2	1	4	0	0
+3	2	5	1	2
+4	2	13	0	5
+5	1	6	0	0
+6	1	146	0	0
+7	1	10	0	0
+8	2	27	0	5
+9	6	41	0	3
+10	8	45	0	0
+11	3	20	0	3
+12	1	8	0	0
+13	2	11	0	5
+14	8	48	0	0
+15	10	350	6	0
+16	2	23	0	5
+17	1	16	0	0
+18	10	350	6	0
+19	1	22	0	0
+20	2	26	0	5
+21	1	18	0	0
+22	1	24	0	0
+23	2	2	0	5
+24	8	55	1	0
+25	3	37	0	3
+26	2	24	0	5
+27	2	27	0	5
+28	2	11	0	5
+29	7	51	0	0
+30	3	16	0	3
+31	1	20	0	0
+32	1	30	0	0
+33	1	36	0	0
+34	1	32	0	0
+35	2	23	0	5
+36	1	146	0	0
+37	1	38	0	0
+38	10	1	1	0
+39	1	36	0	0
+40	3	60	0	3
+41	2	8	1	5
+42	2	11	0	5
+43	7	51	0	0
+44	1	34	0	0
+45	3	19	0	3
+46	8	53	0	0
+47	10	350	6	0
+48	1	46	0	0
+49	1	52	0	0
+50	1	48	0	0
+51	1	42	0	0
+52	10	350	6	0
+53	1	42	0	0
+54	1	146	0	0
+55	1	50	0	0
+56	2	24	0	5
+57	3	22	0	3
+58	2	8	1	5
+59	8	45	0	0
+60	10	1	3	0
+61	8	43	0	0
+62	2	25	0	5
+63	3	21	0	3
+64	1	58	0	0
+65	1	62	0	0
+66	1	64	0	0
+67	1	60	0	0
+68	1	66	0	0
+69	2	12	0	5
+70	10	350	6	0
+71	1	56	0	0
+72	3	24	0	3
+73	3	23	0	3
+74	2	25	0	5
+75	2	11	1	5
+76	3	39	0	3
+77	8	46	0	0
+78	2	12	0	5
+79	10	350	6	0
+80	1	72	0	0
+81	1	146	0	0
+82	1	78	0	0
+83	1	74	0	0
+84	10	350	6	0
+85	2	2	0	5
+86	1	80	0	0
+87	1	70	0	0
+88	3	38	0	3
+89	2	8	1	5
+90	2	25	0	5
+91	3	38	0	3
+92	2	11	1	5
+93	3	23	0	3
+94	10	1	4	0
+95	8	46	0	0
+96	1	94	0	0
+97	1	146	0	0
+98	1	88	0	0
+99	1	92	0	0
+101	1	84	0	0
+102	1	90	0	0
+103	2	22	0	5
+104	1	86	0	0
+105	2	25	0	5
+106	1	90	0	0
+107	2	2	0	5
+108	8	53	0	0
+109	8	44	0	0
+110	2	25	0	5
+111	2	11	1	5
+112	10	1	5	0
+113	1	106	0	0
+114	1	98	0	0
+115	1	100	0	0
+116	2	23	0	5
+117	1	102	0	0
+118	1	104	0	0
+119	1	146	0	0
+120	1	108	0	0
+121	2	8	1	5
+122	2	5	1	2
+123	2	27	0	5
+124	8	46	0	0
+125	2	25	0	5
+126	2	24	0	5
+127	2	11	1	5
+128	4	120	1	3
+128	4	120	2	3
+129	4	113	1	2
+129	4	113	1	1
+129	4	113	4	5
+130	4	114	1	1
+130	4	114	1	2
+130	4	114	3	2
+131	4	115	1	2
+132	4	120	1	3
+132	4	120	2	3
+133	4	113	1	2
+133	4	113	1	1
+133	4	113	4	5
+134	4	114	1	1
+134	4	114	1	2
+134	4	114	3	2
+135	4	115	1	2
+136	5	13	0	100
+137	8	53	0	0
+138	5	15	0	50
+139	8	46	0	0
+140	8	43	0	0
+141	8	47	0	0
+142	10	350	6	0
+143	10	350	6	0
+144	12	2	0	0
+145	11	14	0	0
+146	1	4	0	0
+147	9	8	0	136
+147	9	34	0	136
+148	9	2	0	137
+148	9	18	0	137
+149	4	96	1	5
+149	4	96	2	5
+149	4	96	3	10
+150	4	66	1	5
+150	4	66	2	5
+150	4	66	3	10
+151	13	1	1	5
+151	13	1	2	5
+152	1	4	0	0
+153	13	1	1	5
+153	13	1	1	5
+154	1	90	0	0
+155	4	54	1	4
+155	4	54	2	2
+155	4	54	5	1

+ 24 - 2
hch/CHeroHandler.cpp

@@ -1,14 +1,16 @@
 #define VCMI_DLL
 #include "../stdafx.h"
 #include "CHeroHandler.h"
-#include <sstream>
 #include "CLodHandler.h"
 #include "../lib/VCMI_Lib.h"
 #include <iomanip>
+#include <sstream>
+#include <fstream>
+#include <boost/spirit.hpp>
+using namespace boost::spirit;
 
 extern CLodHandler * bitmaph;
 void loadToIt(std::string &dest, const std::string &src, int &iter, int mode);
-
 /*
  * CHeroHandler.cpp, part of VCMI engine
  *
@@ -350,6 +352,7 @@ void CHeroHandler::loadHeroes()
 			iss >> hid >> sid;
 			heroes[hid]->startingSpell = sid;
 		}
+		inp.close();
 	}
 	loadHeroClasses();
 	initHeroClasses();
@@ -404,6 +407,25 @@ void CHeroHandler::loadHeroes()
 		}
 		ballistics.push_back(bli);
 	}
+	{
+		it = 0;
+		std::ifstream inp;
+		dump.clear();
+		inp.open(DATA_DIR "/config/specials.txt"); //loading hero specials
+		specialInfo dummy;
+		si32 hid;
+		inp.ignore(100, '\n');
+		for (int i = 0; i < 174; ++i)
+		{
+			inp >> hid;
+			inp >> dummy.type;
+			inp >> dummy.val;
+			inp >> dummy.subtype;
+			inp >> dummy.additionalinfo;
+			heroes[hid]->spec.push_back(dummy); //put a copy of dummy
+		}
+		inp.close();
+	}
 }
 void CHeroHandler::loadHeroClasses()
 {

+ 7 - 0
hch/CHeroHandler.h

@@ -19,6 +19,12 @@ class CHeroClass;
 class CDefHandler;
 class CGameInfo;
 class CGHeroInstance;
+struct specialInfo
+{	si32 type;
+	si32 val;
+	si32 subtype;
+	si32 additionalinfo;
+};
 class DLL_EXPORT CHero
 {
 public:
@@ -33,6 +39,7 @@ public:
 	CHeroClass * heroClass;
 	EHeroClasses heroType; //hero class
 	std::vector<std::pair<ui8,ui8> > secSkillsInit; //initial secondary skills; first - ID of skill, second - level of skill (1 - basic, 2 - adv., 3 - expert)
+	std::vector<specialInfo> spec;
 	si32 startingSpell; //-1 if none
 	//bool operator<(CHero& drugi){if (ID < drugi.ID) return true; else return false;}
 

+ 134 - 0
hch/CObjectHandler.cpp

@@ -923,6 +923,138 @@ const std::string & CGHeroInstance::getBiography() const
 void CGHeroInstance::initObj()
 {
 	blockVisit = true;
+	speciality.growthsWithLevel = false;
+	Bonus bonus;
+	for (std::vector<specialInfo>::iterator it = type->spec.begin(); it != type->spec.end(); it++)
+	{
+		bonus.val = it->val;
+		bonus.id = id; //from the hero, speciality has no unique id
+		bonus.duration = Bonus::PERMANENT;
+		bonus.source = Bonus::HERO_SPECIAL;
+		switch (it->type)
+		{
+			case 1:// creature speciality
+				speciality.growthsWithLevel = true;
+				bonus.type = Bonus::SPECIAL_CREATURE;
+				bonus.valType = Bonus::ADDITIVE_VALUE;
+				bonus.subtype = 1; //attack
+				bonus.additionalInfo = level/VLC->creh->creatures[it->val]->level * VLC->creh->creatures[it->val]->attack;
+				speciality.bonuses.push_back (bonus);
+				bonus.subtype = 2; //defense
+				bonus.additionalInfo = level/VLC->creh->creatures[it->val]->level * VLC->creh->creatures[it->val]->defence;
+				speciality.bonuses.push_back (bonus);
+				bonus.subtype = 5;
+				bonus.additionalInfo = 1; //+1 speed
+				speciality.bonuses.push_back (bonus);
+				for (std::set<ui32>::iterator i = VLC->creh->creatures[it->val]->upgrades.begin();
+					i != VLC->creh->creatures[it->val]->upgrades.end(); i++)
+				{
+					bonus.val = *i; // for all direct upgrades of that creature
+					bonus.subtype = 1; //attack
+					bonus.additionalInfo = level/VLC->creh->creatures[*i]->level * VLC->creh->creatures[*i]->attack;
+					speciality.bonuses.push_back (bonus);
+					bonus.subtype = 2; //defense
+					bonus.additionalInfo = level/VLC->creh->creatures[*i]->level * VLC->creh->creatures[*i]->defence;
+					speciality.bonuses.push_back (bonus);
+					bonus.subtype = 5;
+					bonus.additionalInfo = 1; //+1 speed
+					speciality.bonuses.push_back (bonus);
+				}
+				break;
+			case 2://secondary skill
+				speciality.growthsWithLevel = true;
+				bonus.type = Bonus::SECONDARY_SKILL;
+				bonus.subtype = it->val; //skill id
+				bonus.val = it->additionalinfo * level; //actual value, screwed mapping :/
+				switch (it->subtype)
+				{
+					case 0: //normal
+						bonus.valType = Bonus::PERCENT_TO_BASE;
+						break;
+					case 1: //when it's navigation or there's no 'base' at all
+						bonus.valType = Bonus::PERCENT_TO_ALL;
+						break;
+				}
+				speciality.bonuses.push_back (bonus);
+				break;
+			case 3://spell damage bonus, level dependant
+				speciality.growthsWithLevel = true;
+				bonus.type = Bonus::SPECIAL_SPELL_LEV;
+				bonus.subtype = it->subtype;
+				bonus.additionalInfo = it->additionalinfo;
+				speciality.bonuses.push_back (bonus);
+				break;
+			case 4://creature stat boost
+				bonus.type = Bonus::SPECIAL_CREATURE;
+				bonus.valType = Bonus::ADDITIVE_VALUE;
+				bonus.subtype = it->subtype;
+				bonus.additionalInfo = it->additionalinfo;
+				speciality.bonuses.push_back (bonus);
+				break;
+			case 5://spell damage bonus in percent
+				bonus.type = Bonus::SPECIFIC_SPELL_DAMAGE;
+				bonus.valType = Bonus::PERCENT_TO_ALL;
+				bonus.additionalInfo = it->additionalinfo;
+				speciality.bonuses.push_back (bonus);
+				break;
+			case 6://damage bonus for bless (Adela)
+				bonus.type = Bonus::SPECIAL_BLESS_DAMAGE;
+				bonus.additionalInfo = it->additionalinfo; //damage factor
+				speciality.bonuses.push_back (bonus);
+				break;
+			case 7://maxed mastery for spell
+				bonus.type = Bonus::MAXED_SPELL;
+				bonus.val = it->val; //spell id
+				speciality.bonuses.push_back (bonus);
+				break;
+			case 8://peculiar spells - enchantments
+				bonus.type = Bonus::SPECIAL_PECULIAR_ENCHANT;
+				bonus.val = it->val; //spell id
+				bonus.subtype = it->subtype; //0, 1 for Coronius
+				speciality.bonuses.push_back (bonus);
+			case 9://upgrade creatures
+				bonus.type = Bonus::SPECIAL_UPGRADE;
+				bonus.additionalInfo = it->additionalinfo;
+				speciality.bonuses.push_back (bonus);
+				for (std::set<ui32>::iterator i = VLC->creh->creatures[it->val]->upgrades.begin();
+					i != VLC->creh->creatures[it->val]->upgrades.end(); i++)
+				{
+					bonus.val = *i;
+					speciality.bonuses.push_back (bonus); //propagate for regular upgrades of base creature
+				}
+				break;
+			case 10://resource generation
+				bonus.type = Bonus::GENERATE_RESOURCE;
+				bonus.subtype = it->subtype;
+				speciality.bonuses.push_back (bonus);
+				break;
+			case 11://starting skill with mastery (Adrienne)
+				cb->changeSecSkill (id, it->val, it->additionalinfo); //simply give it and forget
+				break;
+			case 12://army speed
+				bonus.type = Bonus::STACKS_SPEED;
+				bonus.val = it->val;
+				speciality.bonuses.push_back (bonus);
+				break;
+			case 13://Dragon bonuses (Mutare)
+				bonus.type = Bonus::SPECIAL_CREATURE;
+				bonus.valType = Bonus::ADDITIVE_VALUE;
+				bonus.additionalInfo = it->additionalinfo; //value
+				bonus.subtype = it->subtype; //which stat it is
+				for (std::vector<CCreature*>::iterator i = VLC->creh->creatures.begin(); i != VLC->creh->creatures.end(); i++)
+				{ //TODO: what if creature changes type during the game (Dragon Eye Ring?)
+					if ((*i)->hasBonusOfType(Bonus::DRAGON_NATURE)) //TODO: implement it!
+					{
+						bonus.val = (*i)->idNumber; //for 
+						speciality.bonuses.push_back (bonus);
+					}
+				}
+			default:
+				tlog2 << "Unexpected hero speciality " << type <<'\n';
+		}
+	}
+	if (speciality.growthsWithLevel)
+		speciality.recalculateSpecials();
 }
 
 void CGHeroInstance::setPropertyDer( ui8 what, ui32 val )
@@ -1175,6 +1307,8 @@ void CGHeroInstance::getParents(TCNodes &out, const CBonusSystemNode *root /*= N
 
 	if((root == this || contains(static_cast<const CStackInstance *>(root))) &&  visitedTown)
 		out.insert(visitedTown);
+
+	out.insert (&speciality);
 }
 
 void CGHeroInstance::pushPrimSkill(int which, int val)

+ 1 - 1
hch/CObjectHandler.h

@@ -305,7 +305,7 @@ public:
 	struct DLL_EXPORT HeroSpecial : CBonusSystemNode
 	{
 		bool growthsWithLevel;
-		void RecalculateSpecials(){};
+		void recalculateSpecials(){};
 		template <typename Handler> void serialize(Handler &h, const int version)
 		{
 			h & static_cast<CBonusSystemNode&>(*this);

+ 12 - 1
lib/HeroBonus.h

@@ -147,7 +147,17 @@ namespace PrimarySkill
 	BONUS_NAME(NOT_ACTIVE)								\
 	BONUS_NAME(NO_LUCK) /*eg. when fighting on cursed ground*/	\
 	BONUS_NAME(NO_MORALE) /*eg. when fighting on cursed ground*/ \
-	BONUS_NAME(DARKNESS) /*val = radius */
+	BONUS_NAME(DARKNESS) /*val = radius */ \
+	BONUS_NAME(SPECIAL_CREATURE_LEV) /*val = base id*/ \
+	BONUS_NAME(SPECIAL_SECONDARY_SKILL) /*val = id, additionalInfo = value per level in percent*/ \
+	BONUS_NAME(SPECIAL_SPELL_LEV) /*val = id, additionalInfo = value per level in percent*/\
+	BONUS_NAME(SPECIAL_CREATURE) /*val = base id, subtype = stat, additionalInfo = value*/\
+	BONUS_NAME(SPECIFIC_SPELL_DAMAGE) /*val = id of spell, additionalInfo = value*/\
+	BONUS_NAME(SPECIAL_BLESS_DAMAGE) /*val = spell (bless), additionalInfo = value per level in percent*/\
+	BONUS_NAME(MAXED_SPELL) /*val = id*/\
+	BONUS_NAME(SPECIAL_PECULIAR_ENCHANT) /*blesses and curses with id = val dependent on unit's level, subtype = 0 or 1 for Coronius*/\
+	BONUS_NAME(SPECIAL_UPGRADE) /*val = base, additionalInfo = target */\
+	BONUS_NAME(DRAGON_NATURE) /*TODO: implement it!*/
 
 struct DLL_EXPORT Bonus
 {
@@ -180,6 +190,7 @@ struct DLL_EXPORT Bonus
 		TOWN_STRUCTURE,
 		HERO_BASE_SKILL,
 		SECONDARY_SKILL,
+		HERO_SPECIAL,
 		ARMY
 	};