瀏覽代碼

- Removed integer parameters from CCreature, all stats are now handled by Bonus System Only
- Parsing for creature format http://wiki.vcmi.eu/index.php?title=Creature_Format
Needs rearrangement of some info to work

DjWarmonger 13 年之前
父節點
當前提交
31f82cade0
共有 8 個文件被更改,包括 140 次插入32 次删除
  1. 5 5
      client/CCastleInterface.cpp
  2. 2 1
      client/CCreatureWindow.cpp
  3. 10 17
      lib/CCreatureHandler.cpp
  4. 7 7
      lib/CCreatureHandler.h
  5. 112 0
      lib/CModHandler.cpp
  6. 1 0
      lib/CModHandler.h
  7. 2 2
      lib/CObjectHandler.cpp
  8. 1 0
      lib/JsonNode.h

+ 5 - 5
client/CCastleInterface.cpp

@@ -1597,15 +1597,15 @@ CFortScreen::RecruitArea::RecruitArea(int posX, int posY, const CGTownInstance *
 	creatureAnim = new CCreaturePic(159, 4, creature, false);
 
 	Rect sizes(287, 4, 96, 18);
-	values.push_back(new LabeledValue(sizes, CGI->generaltexth->allTexts[190], CGI->generaltexth->fcommands[0], creature->attack));
+	values.push_back(new LabeledValue(sizes, CGI->generaltexth->allTexts[190], CGI->generaltexth->fcommands[0], creature->Attack()));
 	sizes.y+=20;
-	values.push_back(new LabeledValue(sizes, CGI->generaltexth->allTexts[191], CGI->generaltexth->fcommands[1], creature->defence));
+	values.push_back(new LabeledValue(sizes, CGI->generaltexth->allTexts[191], CGI->generaltexth->fcommands[1], creature->Defense()));
 	sizes.y+=21;
-	values.push_back(new LabeledValue(sizes, CGI->generaltexth->allTexts[199], CGI->generaltexth->fcommands[2], creature->damageMin, creature->damageMax));
+	values.push_back(new LabeledValue(sizes, CGI->generaltexth->allTexts[199], CGI->generaltexth->fcommands[2], creature->getMinDamage(), creature->getMaxDamage()));
 	sizes.y+=20;
-	values.push_back(new LabeledValue(sizes, CGI->generaltexth->allTexts[388], CGI->generaltexth->fcommands[3], creature->hitPoints));
+	values.push_back(new LabeledValue(sizes, CGI->generaltexth->allTexts[388], CGI->generaltexth->fcommands[3], creature->MaxHealth()));
 	sizes.y+=21;
-	values.push_back(new LabeledValue(sizes, CGI->generaltexth->allTexts[193], CGI->generaltexth->fcommands[4], creature->speed));
+	values.push_back(new LabeledValue(sizes, CGI->generaltexth->allTexts[193], CGI->generaltexth->fcommands[4], creature->valOfBonuses(Bonus::STACKS_SPEED)));
 	sizes.y+=20;
 	values.push_back(new LabeledValue(sizes, CGI->generaltexth->allTexts[194], CGI->generaltexth->fcommands[5], town->creatureGrowth(level)));
 

+ 2 - 1
client/CCreatureWindow.cpp

@@ -501,7 +501,8 @@ void CCreatureWindow::recreateSkillList(int Pos)
 	for (n = numSkills; n < bonusItems.size(); ++n)
 	{
 		bonusItems[n]->visible = false;
-		selectableBonuses[n]->deactivate();
+		if (n < selectableBonuses.size())
+			selectableBonuses[n]->deactivate();
 	}
 }
 

+ 10 - 17
lib/CCreatureHandler.cpp

@@ -5,7 +5,6 @@
 #include "Filesystem/CResourceLoader.h"
 #include "VCMI_Lib.h"
 #include "CGameState.h"
-#include "JsonNode.h"
 #include "CHeroHandler.h"
 #include "CModHandler.h"
 
@@ -317,22 +316,16 @@ void CCreatureHandler::loadCreatures()
 		ncre.growth = readNumber(befi, i, andame, buf);
 		ncre.hordeGrowth = readNumber(befi, i, andame, buf);
 
-		ncre.hitPoints = readNumber(befi, i, andame, buf);
-		ncre.addBonus(ncre.hitPoints, Bonus::STACK_HEALTH);
-		ncre.speed = readNumber(befi, i, andame, buf);
-		ncre.addBonus(ncre.speed, Bonus::STACKS_SPEED);
-		ncre.attack = readNumber(befi, i, andame, buf);
-		ncre.addBonus(ncre.attack, Bonus::PRIMARY_SKILL, PrimarySkill::ATTACK);
-		ncre.defence = readNumber(befi, i, andame, buf);
-		ncre.addBonus(ncre.defence, Bonus::PRIMARY_SKILL, PrimarySkill::DEFENSE);
-		ncre.damageMin = readNumber(befi, i, andame, buf); //not used anymore?
-		ncre.addBonus(ncre.damageMin, Bonus::CREATURE_DAMAGE, 1);
-		ncre.damageMax = readNumber(befi, i, andame, buf);
-		ncre.addBonus(ncre.damageMax, Bonus::CREATURE_DAMAGE, 2);
-
-		ncre.shots = readNumber(befi, i, andame, buf);
-		ncre.addBonus(ncre.shots, Bonus::SHOTS);
-		ncre.spells = readNumber(befi, i, andame, buf);
+		ncre.addBonus(readNumber(befi, i, andame, buf), Bonus::STACK_HEALTH);
+		ncre.addBonus(readNumber(befi, i, andame, buf), Bonus::STACKS_SPEED);
+		ncre.addBonus(readNumber(befi, i, andame, buf), Bonus::PRIMARY_SKILL, PrimarySkill::ATTACK);
+		ncre.addBonus(readNumber(befi, i, andame, buf), Bonus::PRIMARY_SKILL, PrimarySkill::DEFENSE);
+		ncre.addBonus(readNumber(befi, i, andame, buf), Bonus::CREATURE_DAMAGE, 1);
+		ncre.addBonus(readNumber(befi, i, andame, buf), Bonus::CREATURE_DAMAGE, 2);
+		ncre.addBonus(readNumber(befi, i, andame, buf), Bonus::SHOTS);
+
+		//spells - not used?
+		readNumber(befi, i, andame, buf);
 		ncre.ammMin = readNumber(befi, i, andame, buf);
 		ncre.ammMax = readNumber(befi, i, andame, buf);
 

+ 7 - 7
lib/CCreatureHandler.h

@@ -1,10 +1,11 @@
 #pragma once
 
 
-#include "../lib/HeroBonus.h"
-#include "../lib/ConstTransitivePtr.h"
+#include "HeroBonus.h"
+#include "ConstTransitivePtr.h"
 #include "ResourceSet.h"
 #include "GameConstants.h"
+#include "JsonNode.h"
 
 /*
  * CCreatureHandler.h, part of VCMI engine
@@ -26,9 +27,8 @@ public:
 	std::string namePl, nameSing, nameRef; //name in singular and plural form; and reference name
 	TResources cost; //cost[res_id] - amount of that resource
 	std::set<ui32> upgrades; // IDs of creatures to which this creature can be upgraded
-	ui32 hitPoints, speed, attack, defence;
-	ui32 fightValue, AIValue, growth, hordeGrowth, shots, spells;
-	ui32 damageMin, damageMax;
+	//damage, hp. etc are handled by Bonuses
+	ui32 fightValue, AIValue, growth, hordeGrowth;
 	ui32 ammMin, ammMax;
 	ui8 level; // 0 - unknown
 	std::string abilityText; //description of abilities
@@ -77,8 +77,8 @@ public:
 		h & static_cast<CBonusSystemNode&>(*this);
 		h & namePl & nameSing & nameRef
 			& cost & upgrades 
-			& fightValue & AIValue & growth & hordeGrowth & hitPoints & speed & attack & defence & shots & spells
-			& damageMin & damageMax & ammMin & ammMax & level
+			& fightValue & AIValue & growth & hordeGrowth
+			& ammMin & ammMax & level
 			& abilityText & abilityRefs & animDefName
 			& idNumber & faction
 

+ 112 - 0
lib/CModHandler.cpp

@@ -75,6 +75,118 @@ void CModHandler::saveConfigToFile (std::string name)
 	std::ofstream file(CResourceHandler::get()->getResourceName(ResourceID("config/" + name +".json")), std::ofstream::trunc);
 	//file << savedConf;
 }
+
+CCreature * CModHandler::loadCreature (const JsonNode &node)
+{
+	CCreature * cre = new CCreature();
+	cre->idNumber = creatures.size();
+	const JsonNode *value; //optional value
+
+	//TODO: ref name
+	auto name = node["name"];
+	cre->nameSing = name["singular"].String();
+	cre->namePl = name["plural"].String();
+	//TODO: map name->id
+
+	auto cost = node["cost"];
+	if (cost.getType() == JsonNode::DATA_FLOAT) //gold
+	{
+		cre->cost[Res::GOLD] = cost.Float();
+	}
+	else
+	{
+		int i = 0;
+		BOOST_FOREACH (auto val, cost.Vector())
+		{
+			cre->cost[i++] = val.Float();
+		}
+	}
+
+	cre->level = node["level"].Float();
+	cre->faction = -1; //TODO: node["faction"].String() to id or just node["faction"].Float();
+	cre->fightValue = node["fightValue"].Float();
+	cre->AIValue = node["aiValue"].Float();
+	cre->growth = node["growth"].Float();
+
+	cre->addBonus(node["hitPoints"].Float(), Bonus::STACK_HEALTH);
+	cre->addBonus(node["speed"].Float(), Bonus::STACKS_SPEED);
+	cre->addBonus(node["attack"].Float(), Bonus::PRIMARY_SKILL, PrimarySkill::ATTACK);
+	cre->addBonus(node["defense"].Float(), Bonus::PRIMARY_SKILL, PrimarySkill::DEFENSE);
+	auto vec = node["damage"].Vector();
+	cre->addBonus(vec[0].Float(), Bonus::CREATURE_DAMAGE, 1);
+	cre->addBonus(vec[1].Float(), Bonus::CREATURE_DAMAGE, 2);
+
+	//optional
+	value = &node["shots"];
+	if (!value->isNull())
+		cre->addBonus(value->Float(), Bonus::SHOTS);
+
+	value = &node["spellPoints"];
+	if (!value->isNull())
+		cre->addBonus(value->Float(), Bonus::CASTS);
+
+	value = &node["doubleWide"];
+	if (!value->isNull())
+		cre->doubleWide = value->Bool();
+	else
+		cre->doubleWide = false;
+
+	value = &node["abilities"];
+	if (!value->isNull())
+	{
+		BOOST_FOREACH (const JsonNode &bonus, value->Vector())
+		{
+			cre->addNewBonus(ParseBonus(bonus));
+		}
+	}
+	//graphics
+
+	auto graphics = node["graphics"];
+	cre->animDefName = graphics["animation"].String();
+	cre->timeBetweenFidgets = graphics["timeBetweenFidgets"].Float();
+	cre->troopCountLocationOffset = graphics["troopCountLocationOffset"].Float();
+	cre->attackClimaxFrame = graphics["attackClimaxFrame"].Float();
+
+	auto animationTime = graphics["animationTime"];
+	cre->walkAnimationTime = animationTime["walk"].Float();
+	cre->attackAnimationTime = animationTime["attack"].Float();
+	cre->flightAnimationDistance = animationTime["flight"].Float(); //?
+	//TODO: background?
+	auto missle = graphics["missle"];
+	auto offsets = missle["offset"];
+	cre->upperRightMissleOffsetX = offsets["upperX"].Float();
+	cre->upperRightMissleOffsetY = offsets["upperY"].Float();
+	cre->rightMissleOffsetX = offsets["middleX"].Float();
+	cre->rightMissleOffsetY = offsets["middleY"].Float();
+	cre->lowerRightMissleOffsetX = offsets["lowerX"].Float();
+	cre->lowerRightMissleOffsetY = offsets["lowerY"].Float();
+	int i = 0;
+	BOOST_FOREACH (auto angle, missle["frameAngles"].Vector())
+	{
+		cre->missleFrameAngles[i++] = angle.Float();
+	}
+	//we need to know creature id to add it
+	VLC->creh->idToProjectile[cre->idNumber] = value->String();
+
+	//TODO: sounds
+	//how to pass info to Client?
+	auto sounds = node["sound"];
+	//CreaturesBattleSounds cbs;
+	//cbs.attack = sounds["attack"].String();
+	//cbs.defend = sounds["defend"].String();
+	//cbs.killed = sounds["killed"].String(); // was killed or died
+	//cbs.move = sounds["move"].String();
+	//cbs.shoot = sounds["shoot"].String(); // range attack
+	//cbs.wince = sounds["wince"].String(); // attacked but did not die
+	//cbs.ext1 = "";  // creature specific extension
+	//cbs.ext2 = "";  // creature specific extension
+	//cbs.startMoving = sounds["moveStart"].String(); // usually same as ext1
+	//cbs.endMoving = sounds["moveEnd"].String();	// usually same as ext2
+	//CCS->soundh->CBattleSounds.push_back(cbs);
+
+	creatures.push_back(cre);
+	return cre;
+}
 void CModHandler::recreateHandlers()
 {
 	//TODO: consider some template magic to unify all handlers?

+ 1 - 0
lib/CModHandler.h

@@ -75,6 +75,7 @@ public:
 
 	void loadConfigFromFile (std::string name);
 	void saveConfigToFile (std::string name);
+	CCreature * loadCreature (const JsonNode &node); //TODO: handler collections now use ModHandler vector index. Should they be aligned according to mods actually used??
 	void recreateHandlers();
 
 	struct DLL_LINKAGE hardcodedFeatures

+ 2 - 2
lib/CObjectHandler.cpp

@@ -1148,10 +1148,10 @@ void CGHeroInstance::UpdateSpeciality()
 					switch (it->subtype)
 					{
 						case PrimarySkill::ATTACK:
-							param = creatures[it->additionalInfo]->attack;
+							param = creatures[it->additionalInfo]->Attack();
 							break;
 						case PrimarySkill::DEFENSE:
-							param = creatures[it->additionalInfo]->defence;
+							param = creatures[it->additionalInfo]->Defense();
 							break;
 						default:
 							assert(0);

+ 1 - 0
lib/JsonNode.h

@@ -199,3 +199,4 @@ public:
 };
 
 DLL_LINKAGE Bonus * ParseBonus (const JsonVector &ability_vec);
+DLL_LINKAGE Bonus * ParseBonus (const JsonNode &bonus);