Forráskód Böngészése

Merge pull request #1176 from IvanSavenko/tower_shooter_icons

Tower shooter icons fix
Andrii Danylchenko 2 éve
szülő
commit
82179a9cdb

BIN
Mods/vcmi/Sprites/vcmi/creatureIcons/towerLarge.png


BIN
Mods/vcmi/Sprites/vcmi/creatureIcons/towerSmall.png


+ 1 - 1
Mods/vcmi/mod.json

@@ -2,7 +2,7 @@
 	"name" : "VCMI essential files",
 	"description" : "Essential files required for VCMI to run correctly",
 
-	"version" : "0.99",
+	"version" : "1.0",
 	"author" : "VCMI Team",
 	"contact" : "http://forum.vcmi.eu/index.php",
 	"modType" : "Graphical",

+ 4 - 2
client/Graphics.cpp

@@ -429,11 +429,13 @@ void Graphics::loadErmuToPicture()
 	assert (etp_idx == 44);
 }
 
-void Graphics::addImageListEntry(size_t index, const std::string & listName, const std::string & imageName)
+void Graphics::addImageListEntry(size_t index, size_t group, const std::string & listName, const std::string & imageName)
 {
 	if (!imageName.empty())
 	{
 		JsonNode entry;
+		if (group != 0)
+			entry["group"].Integer() = group;
 		entry["frame"].Integer() = index;
 		entry["file"].String() = imageName;
 
@@ -443,7 +445,7 @@ void Graphics::addImageListEntry(size_t index, const std::string & listName, con
 
 void Graphics::addImageListEntries(const EntityService * service)
 {
-	auto cb = std::bind(&Graphics::addImageListEntry, this, _1, _2, _3);
+	auto cb = std::bind(&Graphics::addImageListEntry, this, _1, _2, _3, _4);
 
 	auto loopCb = [&](const Entity * entity, bool & stop)
 	{

+ 1 - 1
client/Graphics.h

@@ -38,7 +38,7 @@ enum EFonts
 /// Handles fonts, hero images, town images, various graphics
 class Graphics
 {
-	void addImageListEntry(size_t index, const std::string & listName, const std::string & imageName);
+	void addImageListEntry(size_t index, size_t group, const std::string & listName, const std::string & imageName);
 
 	void addImageListEntries(const EntityService * service);
 

+ 1 - 1
client/battle/CBattleInterface.cpp

@@ -156,7 +156,6 @@ CBattleInterface::CBattleInterface(const CCreatureSet *army1, const CCreatureSet
 
 		queue->moveTo(Point(pos.x, pos.y - queue->pos.h));
 	}
-	queue->update();
 
 	//preparing siege info
 	const CGTownInstance *town = curInt->cb->battleGetDefendedTown();
@@ -423,6 +422,7 @@ CBattleInterface::CBattleInterface(const CCreatureSet *army1, const CCreatureSet
 	currentAction = PossiblePlayerBattleAction::INVALID;
 	selectedAction = PossiblePlayerBattleAction::INVALID;
 	addUsedEvents(RCLICK | MOVE | KEYBOARD);
+	queue->update();
 	blockUI(true);
 }
 

+ 2 - 1
client/battle/CBattleInterface.h

@@ -59,6 +59,7 @@ struct ProjectileInfo;
 class CClickableHex;
 class CAnimation;
 class IImage;
+class CStackQueue;
 
 /// Small struct which contains information about the id of the attacked stack, the damage dealt,...
 struct StackAttackedInfo
@@ -396,7 +397,7 @@ public:
 	friend class CPlayerInterface;
 	friend class CButton;
 	friend class CInGameConsole;
-
+	friend class CStackQueue;
 	friend class CBattleResultWindow;
 	friend class CBattleHero;
 	friend class CEffectAnimation;

+ 17 - 2
client/battle/CBattleInterfaceClasses.cpp

@@ -763,7 +763,13 @@ void CStackQueue::update()
 		stackBoxes[boxIndex]->setUnit(nullptr);
 }
 
-CStackQueue::StackBox::StackBox(CStackQueue * owner)
+int32_t CStackQueue::getSiegeShooterIconID()
+{
+	return owner->siegeH->town->town->faction->index;
+}
+
+CStackQueue::StackBox::StackBox(CStackQueue * owner):
+	owner(owner)
 {
 	OBJECT_CONSTRUCTION_CAPTURING(255-DISPOSE);
 	background = std::make_shared<CPicture>(owner->embedded ? "StackQueueSmall" : "StackQueueLarge");
@@ -795,7 +801,16 @@ void CStackQueue::StackBox::setUnit(const battle::Unit * unit, size_t turn)
 	{
 		background->colorize(unit->unitOwner());
 		icon->visible = true;
-		icon->setFrame(unit->creatureIconIndex());
+
+		// temporary code for mod compatibility:
+		// first, set icon that should definitely exist (arrow tower icon in base vcmi mod)
+		// second, try to switch to icon that should be provided by mod
+		// if mod is not up to date and does have arrow tower icon yet - second setFrame call will fail and retain previously set image
+		// for 1.2 release & later next line should be moved into 'else' block
+		icon->setFrame(unit->creatureIconIndex(), 0);
+		if (unit->unitType()->idNumber == CreatureID::ARROW_TOWERS)
+			icon->setFrame(owner->getSiegeShooterIconID(), 1);
+
 		amount->setText(makeNumberShort(unit->getCount()));
 
 		if(stateIcon)

+ 2 - 0
client/battle/CBattleInterfaceClasses.h

@@ -157,6 +157,7 @@ class CStackQueue : public CIntObject
 {
 	class StackBox : public CIntObject
 	{
+		CStackQueue * owner;
 	public:
 		std::shared_ptr<CPicture> background;
 		std::shared_ptr<CAnimImage> icon;
@@ -175,6 +176,7 @@ class CStackQueue : public CIntObject
 	std::shared_ptr<CAnimation> icons;
 	std::shared_ptr<CAnimation> stateIcons;
 
+	int32_t getSiegeShooterIconID();
 public:
 	const bool embedded;
 

+ 2 - 0
config/creatures/special.json

@@ -123,6 +123,8 @@
 		},
 		"graphics" :
 		{
+			"iconSmall" : "vcmi/creatureIcons/towerSmall",
+			"iconLarge" : "vcmi/creatureIcons/towerLarge",
 			"animation": "CLCBOW.DEF" // needed to pass validation, never used
 		},
 		"sound": {}

+ 2 - 0
config/factions/castle.json

@@ -203,6 +203,8 @@
 			"siege" :
 			{
 				"shooter" : "archer",
+				"towerIconSmall" : "vcmi/creatureIcons/towerSmall",
+				"towerIconLarge" : "vcmi/creatureIcons/towerLarge",
 				"imagePrefix" : "SGCS",
 				"gate" :
 				{

+ 2 - 0
config/factions/conflux.json

@@ -210,6 +210,8 @@
 			"siege" :
 			{
 				"shooter" : "stormElemental",
+				"towerIconSmall" : "vcmi/creatureIcons/towerSmall",
+				"towerIconLarge" : "vcmi/creatureIcons/towerLarge",
 				"imagePrefix" : "SGEL",
 				"gate" :
 				{

+ 2 - 0
config/factions/dungeon.json

@@ -204,6 +204,8 @@
 			"siege" :
 			{
 				"shooter" : "medusa",
+				"towerIconSmall" : "vcmi/creatureIcons/towerSmall",
+				"towerIconLarge" : "vcmi/creatureIcons/towerLarge",
 				"imagePrefix" : "SGDN",
 				"gate" :
 				{

+ 2 - 0
config/factions/fortress.json

@@ -209,6 +209,8 @@
 			"siege" :
 			{
 				"shooter" : "lizardman",
+				"towerIconSmall" : "vcmi/creatureIcons/towerSmall",
+				"towerIconLarge" : "vcmi/creatureIcons/towerLarge",
 				"imagePrefix" : "SGFR",
 				"gate" :
 				{

+ 2 - 0
config/factions/inferno.json

@@ -204,6 +204,8 @@
 			"siege" :
 			{
 				"shooter" : "gog",
+				"towerIconSmall" : "vcmi/creatureIcons/towerSmall",
+				"towerIconLarge" : "vcmi/creatureIcons/towerLarge",
 				"imagePrefix" : "SGIN",
 				"gate" :
 				{

+ 2 - 0
config/factions/necropolis.json

@@ -214,6 +214,8 @@
 			"siege" :
 			{
 				"shooter" : "lich",
+				"towerIconSmall" : "vcmi/creatureIcons/towerSmall",
+				"towerIconLarge" : "vcmi/creatureIcons/towerLarge",
 				"imagePrefix" : "SGNC",
 				"gate" :
 				{

+ 2 - 0
config/factions/rampart.json

@@ -211,6 +211,8 @@
 			"siege" :
 			{
 				"shooter" : "woodElf",
+				"towerIconSmall" : "vcmi/creatureIcons/towerSmall",
+				"towerIconLarge" : "vcmi/creatureIcons/towerLarge",
 				"imagePrefix" : "SGRM",
 				"gate" :
 				{

+ 2 - 0
config/factions/stronghold.json

@@ -203,6 +203,8 @@
 			{
 				"shooter" : "orc",
 				"imagePrefix" : "SGST",
+				"towerIconSmall" : "vcmi/creatureIcons/towerSmall",
+				"towerIconLarge" : "vcmi/creatureIcons/towerLarge",
 				"gate" :
 				{
 					"arch" : { "x" : 478, "y" : 235 },

+ 2 - 0
config/factions/tower.json

@@ -202,6 +202,8 @@
 			"siege" :
 			{
 				"shooter" : "mage",
+				"towerIconSmall" : "vcmi/creatureIcons/towerSmall",
+				"towerIconLarge" : "vcmi/creatureIcons/towerLarge",
 				"imagePrefix" : "SGTW",
 				"gate" :
 				{

+ 11 - 0
config/schemas/townSiege.json

@@ -6,6 +6,7 @@
 	"description" : "Format used to define town siege screen in VCMI",
 	"required" : [
 		"gate", "imagePrefix", "moat", "shooter",
+		"towerIconLarge", "towerIconSmall",
 		"static", "towers", "walls"
 	 ],
 	
@@ -80,6 +81,16 @@
 			"type":"string",
 			"description" : "Identifier of creature that will be used as tower shooter"
 		},
+		"towerIconSmall": {
+			"type":"string",
+			"description": "Small icon for tower, used in battle queue",
+			"format" : "imageFile"
+		},
+		"towerIconLarge": {
+			"type":"string",
+			"description": "Large icon for tower, used in battle queue",
+			"format" : "imageFile"
+		},
 		"static": {
 			"type":"object",
 			"additionalProperties" : false,

+ 1 - 1
include/vcmi/Entity.h

@@ -17,7 +17,7 @@ class IBonusBearer;
 class DLL_LINKAGE Entity
 {
 public:
-	using IconRegistar = std::function<void(int32_t index, const std::string & listName, const std::string & imageName)>;
+	using IconRegistar = std::function<void(int32_t index, int32_t group, const std::string & listName, const std::string & imageName)>;
 
 	virtual ~Entity() = default;
 

+ 2 - 2
lib/CArtHandler.cpp

@@ -72,8 +72,8 @@ const std::string & CArtifact::getJsonKey() const
 
 void CArtifact::registerIcons(const IconRegistar & cb) const
 {
-	cb(getIconIndex(), "ARTIFACT", image);
-	cb(getIconIndex(), "ARTIFACTLARGE", large);
+	cb(getIconIndex(), 0, "ARTIFACT", image);
+	cb(getIconIndex(), 0, "ARTIFACTLARGE", large);
 }
 
 ArtifactID CArtifact::getId() const

+ 2 - 2
lib/CCreatureHandler.cpp

@@ -46,8 +46,8 @@ const std::string & CCreature::getJsonKey() const
 
 void CCreature::registerIcons(const IconRegistar & cb) const
 {
-	cb(getIconIndex(), "CPRSMALL", smallIconName);
-	cb(getIconIndex(), "TWCRPORT", largeIconName);
+	cb(getIconIndex(), 0, "CPRSMALL", smallIconName);
+	cb(getIconIndex(), 0, "TWCRPORT", largeIconName);
 }
 
 CreatureID CCreature::getId() const

+ 4 - 4
lib/CHeroHandler.cpp

@@ -59,10 +59,10 @@ HeroTypeID CHero::getId() const
 
 void CHero::registerIcons(const IconRegistar & cb) const
 {
-	cb(getIconIndex(), "UN32", iconSpecSmall);
-	cb(getIconIndex(), "UN44", iconSpecLarge);
-	cb(getIconIndex(), "PORTRAITSLARGE", portraitLarge);
-	cb(getIconIndex(), "PORTRAITSSMALL", portraitSmall);
+	cb(getIconIndex(), 0, "UN32", iconSpecSmall);
+	cb(getIconIndex(), 0, "UN44", iconSpecLarge);
+	cb(getIconIndex(), 0, "PORTRAITSLARGE", portraitLarge);
+	cb(getIconIndex(), 0, "PORTRAITSSMALL", portraitSmall);
 }
 
 void CHero::updateFrom(const JsonNode & data)

+ 3 - 3
lib/CSkillHandler.cpp

@@ -70,9 +70,9 @@ void CSkill::registerIcons(const IconRegistar & cb) const
 	{
 		int frame = 2 + level + 3 * id;
 		const LevelInfo & skillAtLevel = at(level);
-		cb(frame, "SECSK32", skillAtLevel.iconSmall);
-		cb(frame, "SECSKILL", skillAtLevel.iconMedium);
-		cb(frame, "SECSK82", skillAtLevel.iconLarge);
+		cb(frame, 0, "SECSK32", skillAtLevel.iconSmall);
+		cb(frame, 0, "SECSKILL", skillAtLevel.iconMedium);
+		cb(frame, 0, "SECSK82", skillAtLevel.iconLarge);
 	}
 }
 

+ 16 - 9
lib/CTownHandler.cpp

@@ -126,15 +126,19 @@ void CFaction::registerIcons(const IconRegistar & cb) const
 	if(town)
 	{
 		auto & info = town->clientInfo;
-		cb(info.icons[0][0], "ITPT", info.iconLarge[0][0]);
-		cb(info.icons[0][1], "ITPT", info.iconLarge[0][1]);
-		cb(info.icons[1][0], "ITPT", info.iconLarge[1][0]);
-		cb(info.icons[1][1], "ITPT", info.iconLarge[1][1]);
-
-		cb(info.icons[0][0] + 2, "ITPA", info.iconSmall[0][0]);
-		cb(info.icons[0][1] + 2, "ITPA", info.iconSmall[0][1]);
-		cb(info.icons[1][0] + 2, "ITPA", info.iconSmall[1][0]);
-		cb(info.icons[1][1] + 2, "ITPA", info.iconSmall[1][1]);
+		cb(info.icons[0][0], 0, "ITPT", info.iconLarge[0][0]);
+		cb(info.icons[0][1], 0, "ITPT", info.iconLarge[0][1]);
+		cb(info.icons[1][0], 0, "ITPT", info.iconLarge[1][0]);
+		cb(info.icons[1][1], 0, "ITPT", info.iconLarge[1][1]);
+
+		cb(info.icons[0][0] + 2, 0, "ITPA", info.iconSmall[0][0]);
+		cb(info.icons[0][1] + 2, 0, "ITPA", info.iconSmall[0][1]);
+		cb(info.icons[1][0] + 2, 0, "ITPA", info.iconSmall[1][0]);
+		cb(info.icons[1][1] + 2, 0, "ITPA", info.iconSmall[1][1]);
+
+		cb(index, 1, "CPRSMALL", info.towerIconSmall);
+		cb(index, 1, "TWCRPORT", info.towerIconLarge);
+
 	}
 }
 
@@ -755,6 +759,9 @@ CTown::ClientInfo::Point JsonToPoint(const JsonNode & node)
 void CTownHandler::loadSiegeScreen(CTown &town, const JsonNode & source)
 {
 	town.clientInfo.siegePrefix = source["imagePrefix"].String();
+	town.clientInfo.towerIconSmall = source["towerIconSmall"].String();
+	town.clientInfo.towerIconLarge = source["towerIconLarge"].String();
+
 	VLC->modh->identifiers.requestIdentifier("creature", source["shooter"], [&town](si32 creature)
 	{
 		auto crId = CreatureID(creature);

+ 4 - 0
lib/CTownHandler.h

@@ -303,6 +303,8 @@ public:
 		std::string siegePrefix;
 		std::vector<Point> siegePositions;
 		CreatureID siegeShooter; // shooter creature ID
+		std::string towerIconSmall;
+		std::string towerIconLarge;
 
 		template <typename Handler> void serialize(Handler &h, const int version)
 		{
@@ -321,6 +323,8 @@ public:
 			h & siegePrefix;
 			h & siegePositions;
 			h & siegeShooter;
+			h & towerIconSmall;
+			h & towerIconLarge;
 		}
 	} clientInfo;
 

+ 4 - 4
lib/spells/CSpellHandler.cpp

@@ -505,10 +505,10 @@ std::unique_ptr<spells::Mechanics> CSpell::battleMechanics(const spells::IBattle
 
 void CSpell::registerIcons(const IconRegistar & cb) const
 {
-	cb(getIndex(), "SPELLS", iconBook);
-	cb(getIndex()+1, "SPELLINT", iconEffect);
-	cb(getIndex(), "SPELLBON", iconScenarioBonus);
-	cb(getIndex(), "SPELLSCR", iconScroll);
+	cb(getIndex(), 0, "SPELLS", iconBook);
+	cb(getIndex()+1, 0, "SPELLINT", iconEffect);
+	cb(getIndex(), 0, "SPELLBON", iconScenarioBonus);
+	cb(getIndex(), 0, "SPELLSCR", iconScroll);
 }
 
 void CSpell::updateFrom(const JsonNode & data)

+ 4 - 2
mapeditor/graphics.cpp

@@ -310,11 +310,13 @@ std::shared_ptr<Animation> Graphics::getAnimation(const std::shared_ptr<const Ob
 	return ret;
 }
 
-void Graphics::addImageListEntry(size_t index, const std::string & listName, const std::string & imageName)
+void Graphics::addImageListEntry(size_t index, size_t group, const std::string & listName, const std::string & imageName)
 {
 	if (!imageName.empty())
 	{
 		JsonNode entry;
+		if(group != 0)
+			entry["group"].Integer() = group;
 		entry["frame"].Integer() = index;
 		entry["file"].String() = imageName;
 		
@@ -324,7 +326,7 @@ void Graphics::addImageListEntry(size_t index, const std::string & listName, con
 
 void Graphics::addImageListEntries(const EntityService * service)
 {
-	auto cb = std::bind(&Graphics::addImageListEntry, this, _1, _2, _3);
+	auto cb = std::bind(&Graphics::addImageListEntry, this, _1, _2, _3, _4);
 	
 	auto loopCb = [&](const Entity * entity, bool & stop)
 	{

+ 1 - 1
mapeditor/graphics.h

@@ -27,7 +27,7 @@ class JsonNode;
 /// Handles fonts, hero images, town images, various graphics
 class Graphics
 {
-	void addImageListEntry(size_t index, const std::string & listName, const std::string & imageName);
+	void addImageListEntry(size_t index, size_t group, const std::string & listName, const std::string & imageName);
 	
 	void addImageListEntries(const EntityService * service);