mirror of
				https://github.com/vcmi/vcmi.git
				synced 2025-10-31 00:07:39 +02:00 
			
		
		
		
	Stack artifacts - part 1
This commit is contained in:
		| @@ -127,14 +127,50 @@ bool CCallback::dismissHero(const CGHeroInstance *hero) | ||||
| // 	return gs->players[player].serial; | ||||
| // } | ||||
|  | ||||
| bool CCallback::swapArtifacts(const CGHeroInstance * hero1, ui16 pos1, const CGHeroInstance * hero2, ui16 pos2) | ||||
| bool CCallback::swapArtifacts(const IArtifactSetBase * src, ui16 pos1, const IArtifactSetBase * dest, ui16 pos2) | ||||
| { | ||||
| 	if(player!=hero1->tempOwner && player!=hero2->tempOwner) | ||||
| 		return false; | ||||
| 	const CStackInstance * stack1 = dynamic_cast<const CStackInstance*>(src); | ||||
| 	const CStackInstance * stack2 = dynamic_cast<const CStackInstance*>(dest); | ||||
| 	const CGHeroInstance * hero1 = dynamic_cast<const CGHeroInstance*>(src); | ||||
| 	const CGHeroInstance * hero2 = dynamic_cast<const CGHeroInstance*>(dest); | ||||
|  | ||||
| 	ExchangeArtifacts ea(hero1->id, hero2->id, pos1, pos2); | ||||
| 	sendRequest(&ea); | ||||
| 	return true; | ||||
| 	ExchangeArtifacts ea; | ||||
|  | ||||
| 	if (hero1 && hero2) | ||||
| 	{ | ||||
| 		if(player!=hero1->tempOwner && player!=hero2->tempOwner) //player can exchange artifacts only between his own heroes | ||||
| 			return false; | ||||
| 		else | ||||
| 		{ | ||||
| 			ExchangeArtifacts ea(hero1->id, hero2->id, pos1, pos2); | ||||
| 			sendRequest(&ea); | ||||
| 			return true; | ||||
| 		} | ||||
| 	} | ||||
| 	else if (hero1 && stack2) //move artifact from hero to stack | ||||
| 	{ | ||||
| 		ea.hid1 = hero1->id; | ||||
| 		ea.s2 = StackLocation(stack2->armyObj, stack2->armyObj->findStack(stack2)); | ||||
| 		ea.slot1 = pos1; | ||||
| 		ea.slot2 = pos2; | ||||
| 		sendRequest(&ea); | ||||
| 		return true; | ||||
| 	} | ||||
| 	else if (stack1 && hero2) //move artifacts from stakc to hero | ||||
| 	{ | ||||
| 		ea.s1 = StackLocation(stack1->armyObj, stack1->armyObj->findStack(stack1)); | ||||
| 		ea.hid2 = hero2->id; | ||||
| 		ea.slot1 = pos1; | ||||
| 		ea.slot2 = pos2; | ||||
| 		sendRequest(&ea); | ||||
| 		return true; | ||||
| 	} | ||||
| 	else if (stack1 && stack2) | ||||
| 	{ | ||||
| 		//TODO: merge stacks? | ||||
| 	} | ||||
| 	else | ||||
| 		return false; | ||||
| } | ||||
|  | ||||
| /** | ||||
|   | ||||
| @@ -13,6 +13,7 @@ | ||||
|  * | ||||
|  */ | ||||
|  | ||||
| class IArtifactSetBase; | ||||
| class CGHeroInstance; | ||||
| class CGameState; | ||||
| struct CPath; | ||||
| @@ -60,7 +61,8 @@ public: | ||||
| 	virtual int swapCreatures(const CArmedInstance *s1, const CArmedInstance *s2, int p1, int p2)=0;//swaps creatures between two possibly different garrisons // TODO: AI-unsafe code - fix it! | ||||
| 	virtual int mergeStacks(const CArmedInstance *s1, const CArmedInstance *s2, int p1, int p2)=0;//joins first stack to the second (creatures must be same type) | ||||
| 	virtual int splitStack(const CArmedInstance *s1, const CArmedInstance *s2, int p1, int p2, int val)=0;//split creatures from the first stack | ||||
| 	virtual bool swapArtifacts(const CGHeroInstance * hero1, ui16 pos1, const CGHeroInstance * hero2, ui16 pos2)=0; //swaps artifacts between two given heroes | ||||
| 	//virtual bool swapArtifacts(const CGHeroInstance * hero1, ui16 pos1, const CGHeroInstance * hero2, ui16 pos2)=0; //swaps artifacts between two given heroes | ||||
| 	virtual bool swapArtifacts(const IArtifactSetBase * src, ui16 pos1, const IArtifactSetBase * dest, ui16 pos2)=0; | ||||
| 	virtual bool assembleArtifacts(const CGHeroInstance * hero, ui16 artifactSlot, bool assemble, ui32 assembleTo)=0; | ||||
| 	virtual bool dismissCreature(const CArmedInstance *obj, int stackPos)=0; | ||||
| 	virtual void endTurn()=0; | ||||
| @@ -117,7 +119,10 @@ public: | ||||
| 	int mergeStacks(const CArmedInstance *s1, const CArmedInstance *s2, int p1, int p2); //first goes to the second | ||||
| 	int splitStack(const CArmedInstance *s1, const CArmedInstance *s2, int p1, int p2, int val); | ||||
| 	bool dismissHero(const CGHeroInstance * hero); | ||||
| 	bool swapArtifacts(const CGHeroInstance * hero1, ui16 pos1, const CGHeroInstance * hero2, ui16 pos2); | ||||
| 	//bool swapArtifacts(const CGHeroInstance * hero1, ui16 pos1, const CGHeroInstance * hero2, ui16 pos2); | ||||
| 	bool swapArtifacts(const IArtifactSetBase * src, ui16 pos1, const IArtifactSetBase * dest, ui16 pos2); | ||||
| 	//bool moveArtifact(const CGHeroInstance * hero, ui16 src, const CStackInstance * stack, ui16 dest); // TODO: unify classes | ||||
| 	//bool moveArtifact(const CStackInstance * stack, ui16 src , const CGHeroInstance * hero, ui16 dest); // TODO: unify classes | ||||
| 	bool assembleArtifacts(const CGHeroInstance * hero, ui16 artifactSlot, bool assemble, ui32 assembleTo); | ||||
| 	bool buildBuilding(const CGTownInstance *town, si32 buildingID); | ||||
| 	void recruitCreatures(const CGObjectInstance *obj, ui32 ID, ui32 amount, si32 level=-1); | ||||
|   | ||||
| @@ -262,14 +262,33 @@ void CGarrisonSlot::clickLeft(tribool down, bool previousState) | ||||
| 				} | ||||
| 			} | ||||
| 		} | ||||
| 		else //highlight | ||||
| 		else //drop artifact or highlight | ||||
| 		{ | ||||
| 			if(creature) | ||||
| 			bool artSelected = false; | ||||
| 			if (CHeroWindow* chw = dynamic_cast<CHeroWindow*>(GH.topInt())) //dirty solution | ||||
| 			{ | ||||
| 				owner->highlighted = this; | ||||
| 				BOOST_FOREACH(CArtifactsOfHero *aoh, chw->artSets) // why they are multiple? | ||||
| 				{ | ||||
| 					if (const CArtifactInstance *art = aoh->commonInfo->src.art) | ||||
| 					{ | ||||
| 						artSelected = true; | ||||
| 						if (art->canBePutAt(ArtifactLocation(myStack, GameConstants::CREATURE_ART))) | ||||
| 						{ | ||||
| 							//TODO : move | ||||
| 							break; | ||||
| 						} | ||||
| 					} | ||||
| 				} | ||||
| 			} | ||||
| 			if (!artSelected) | ||||
| 			{ | ||||
| 				if(creature) | ||||
| 				{ | ||||
| 					owner->highlighted = this; | ||||
|  | ||||
| 				for(size_t i = 0; i<owner->splitButtons.size(); i++) | ||||
| 					owner->splitButtons[i]->block(false); | ||||
| 					for(size_t i = 0; i<owner->splitButtons.size(); i++) | ||||
| 						owner->splitButtons[i]->block(false); | ||||
| 				} | ||||
| 			} | ||||
| 			redraw(); | ||||
| 			refr = true; | ||||
| @@ -297,6 +316,7 @@ CGarrisonSlot::CGarrisonSlot(CGarrisonInt *Owner, int x, int y, int IID, int Upg | ||||
| { | ||||
| 	//assert(Creature == CGI->creh->creatures[Creature->idNumber]); | ||||
| 	active = false; | ||||
| 	highlight = false; | ||||
| 	upg = Upg; | ||||
| 	ID = IID; | ||||
| 	myStack = Creature; | ||||
| @@ -334,7 +354,11 @@ void CGarrisonSlot::showAll(SDL_Surface * to) | ||||
| 		if((owner->highlighted==this) | ||||
| 			|| (owner->splitting && owner->highlighted->creature == creature)) | ||||
| 		{ | ||||
| 			blitAt(imgs[-1],pos,to); | ||||
| 			highlight = true; | ||||
| 		} | ||||
| 		{ | ||||
| 			if (highlight) | ||||
| 				blitAt(imgs[-1],pos,to); | ||||
| 		} | ||||
| 	} | ||||
| 	else//empty slot | ||||
| @@ -2700,7 +2724,7 @@ void CTradeWindow::artifactSelected(CArtPlace *slot) | ||||
| { | ||||
| 	assert(mode == EMarketMode::ARTIFACT_RESOURCE); | ||||
| 	items[1][0]->setArtInstance(slot->ourArt); | ||||
| 	if(slot->ourArt) | ||||
| 	if(slot->ourArt && slot->ourArt->id >= 0) | ||||
| 		hLeft = items[1][0]; | ||||
| 	else | ||||
| 		hLeft = NULL; | ||||
| @@ -4813,6 +4837,21 @@ void CArtifactsOfHero::markPossibleSlots(const CArtifactInstance* art) | ||||
| 	BOOST_FOREACH(CArtifactsOfHero *aoh, commonInfo->participants) | ||||
| 		BOOST_FOREACH(CArtPlace *place, aoh->artWorn) | ||||
| 			place->marked = art->canBePutAt(ArtifactLocation(aoh->curHero, place->slotID), true); | ||||
| 	 | ||||
| 	if (CHeroWindow* chw = dynamic_cast<CHeroWindow*>(GH.topInt())) | ||||
| 	{ | ||||
| 		//FIXME: garrison window has two rows of cretaures :? | ||||
| 		BOOST_FOREACH (CGarrisonSlot *g, chw->garr->slotsDown) | ||||
| 		{ | ||||
| 			if (g->myStack) | ||||
| 				if (art->canBePutAt(ArtifactLocation(g->myStack, GameConstants::CREATURE_ART), false)); | ||||
| 					g->highlight = true; | ||||
| 		} | ||||
| 	} | ||||
| 	else if(CExchangeWindow* cew = dynamic_cast<CExchangeWindow*>(GH.topInt())) | ||||
| 	{ | ||||
| 		//TODO | ||||
| 	} | ||||
|  | ||||
| 	safeRedraw(); | ||||
| } | ||||
| @@ -5012,10 +5051,10 @@ void CArtifactsOfHero::safeRedraw() | ||||
|  | ||||
| void CArtifactsOfHero::realizeCurrentTransaction() | ||||
| { | ||||
| 	assert(commonInfo->src.AOH); | ||||
| 	assert(commonInfo->dst.AOH); | ||||
| 	LOCPLINT->cb->swapArtifacts(commonInfo->src.AOH->curHero, commonInfo->src.slotID, | ||||
| 								commonInfo->dst.AOH->curHero, commonInfo->dst.slotID); | ||||
| 	assert(commonInfo->src.AOH || commonInfo->src.CAS); | ||||
| 	assert(commonInfo->dst.AOH || commonInfo->dst.CAS); | ||||
| 	LOCPLINT->cb->swapArtifacts(commonInfo->src.AOH ? (IArtifactSetBase*)commonInfo->src.AOH->curHero : commonInfo->src.CAS, commonInfo->src.slotID, | ||||
| 								commonInfo->dst.AOH ? (IArtifactSetBase*)commonInfo->dst.AOH->curHero : commonInfo->dst.CAS, commonInfo->dst.slotID); | ||||
| } | ||||
|  | ||||
| void CArtifactsOfHero::artifactMoved(const ArtifactLocation &src, const ArtifactLocation &dst) | ||||
| @@ -6273,6 +6312,16 @@ void CArtifactsOfHero::SCommonPart::Artpos::setTo(const CArtPlace *place, bool d | ||||
| 		art = place->ourArt; | ||||
| } | ||||
|  | ||||
| IArtifactSetBase * CArtifactsOfHero::SCommonPart::Artpos::getArtHolder() | ||||
| { | ||||
| 	if (AOH) | ||||
| 		return (IArtifactSetBase*)AOH; | ||||
| 	if (CAS) | ||||
| 		return (IArtifactSetBase*)CAS; | ||||
| 	tlog2 <<"Warning! Artpos without source\n"; | ||||
| 	return NULL; | ||||
| } | ||||
|  | ||||
| bool CArtifactsOfHero::SCommonPart::Artpos::operator==(const ArtifactLocation &al) const | ||||
| { | ||||
| 	if(!AOH) | ||||
|   | ||||
| @@ -25,6 +25,7 @@ | ||||
|  */ | ||||
|  | ||||
| struct ArtifactLocation; | ||||
| class IArtifactSetBase; | ||||
| class CStackBasicDescriptor; | ||||
| class CBonusSystemNode; | ||||
| class CArtifact; | ||||
| @@ -62,6 +63,7 @@ class CPlayerInterface; | ||||
| class CHeroWindow; | ||||
| class CArtifact; | ||||
| class CArtifactsOfHero; | ||||
| class CCreatureArtifactSet; | ||||
| class CResDataBar; | ||||
| struct SPuzzleInfo; | ||||
| class CGGarrison; | ||||
| @@ -222,6 +224,7 @@ public: | ||||
| 	int count; //number of creatures | ||||
| 	int upg; //0 - up garrison, 1 - down garrison | ||||
| 	bool active; //TODO: comment me | ||||
| 	bool highlight; | ||||
|  | ||||
| 	virtual void hover (bool on); //call-in | ||||
| 	const CArmedInstance * getObj(); | ||||
| @@ -851,12 +854,14 @@ public: | ||||
| 		struct Artpos | ||||
| 		{ | ||||
| 			int slotID; | ||||
| 			const CArtifactsOfHero * AOH; | ||||
| 			const CArtifactsOfHero *AOH; | ||||
| 			const CCreatureArtifactSet *CAS; | ||||
| 			const CArtifactInstance *art; | ||||
|  | ||||
| 			Artpos(); | ||||
| 			void clear(); | ||||
| 			void setTo(const CArtPlace *place, bool dontTakeBackpack); | ||||
| 			IArtifactSetBase * getArtHolder(); // returns AOH or CAS | ||||
| 			bool valid(); | ||||
| 			bool operator==(const ArtifactLocation &al) const; | ||||
| 		} src, dst; | ||||
|   | ||||
| @@ -7,6 +7,7 @@ | ||||
| #include "../lib/VCMI_Lib.h" | ||||
| #include "CSpellHandler.h" | ||||
| #include "CObjectHandler.h" | ||||
| //#include "CCreatureSet.h" | ||||
| #include "NetPacks.h" | ||||
|  | ||||
| extern CLodHandler *bitmaph; | ||||
| @@ -195,7 +196,8 @@ CArtHandler::CArtHandler() | ||||
| 	// War machines are the default big artifacts. | ||||
| 	for (ui32 i = 3; i <= 6; i++) | ||||
| 		bigArtifacts.insert(i); | ||||
| 	//modableArtifacts = boost::assign::map_list_of(1, 1)(146,3)(147,3)(148,3)(150,3)(151,3)(152,3)(154,3)(156,2); | ||||
| 	if (GameConstants::STACK_ARTIFACT) | ||||
| 		creatureArtifacts += 141, 142, 143, 156; //basic Wog arts and Warlord's banner | ||||
| } | ||||
|  | ||||
| CArtHandler::~CArtHandler() | ||||
| @@ -225,23 +227,6 @@ void CArtHandler::loadArtifacts(bool onlyTxt) | ||||
| 	for (int i=0; i<GameConstants::ARTIFACTS_QUANTITY; i++) | ||||
| 	{ | ||||
| 		CArtifact *art = new CArtifact(); | ||||
| // 		if ((itr = modableArtifacts.find(i)) != modableArtifacts.end()) | ||||
| // 		{ | ||||
| // 			switch (itr->second) | ||||
| // 			{ | ||||
| // 			case 1: | ||||
| // 				art = new CScroll; | ||||
| // 				break; | ||||
| // 			case 2: | ||||
| // 				art = new CCustomizableArt; | ||||
| // 				break; | ||||
| // 			case 3: | ||||
| // 				art = new CCommanderArt; | ||||
| // 				break; | ||||
| // 			}; | ||||
| // 		} | ||||
| // 		else | ||||
| //			art = new CArtifact; | ||||
|  | ||||
| 		CArtifact &nart = *art; | ||||
| 		nart.id=i; | ||||
| @@ -941,19 +926,24 @@ int CArtifactInstance::firstBackpackSlot(const CGHeroInstance *h) const | ||||
|  | ||||
| bool CArtifactInstance::canBePutAt(const ArtifactLocation &al, bool assumeDestRemoved /*= false*/) const | ||||
| { | ||||
| 	if(al.slot >= GameConstants::BACKPACK_START) | ||||
| 	if (al.hero) | ||||
| 	{ | ||||
| 		if(artType->isBig()) | ||||
| 			return false; | ||||
| 		if(al.slot >= GameConstants::BACKPACK_START) | ||||
| 		{ | ||||
| 			if(artType->isBig()) | ||||
| 				return false; | ||||
| 		 | ||||
| 		//TODO backpack limit | ||||
| 		return true; | ||||
| 			//TODO backpack limit | ||||
| 			return true; | ||||
| 		} | ||||
|  | ||||
| 		if(!vstd::contains(artType->possibleSlots, al.slot)) | ||||
| 			return false; | ||||
|  | ||||
| 		return al.hero->isPositionFree(al.slot, assumeDestRemoved); | ||||
| 	} | ||||
|  | ||||
| 	if(!vstd::contains(artType->possibleSlots, al.slot)) | ||||
| 	else | ||||
| 		return false; | ||||
|  | ||||
| 	return al.hero->isPositionFree(al.slot, assumeDestRemoved); | ||||
| } | ||||
|  | ||||
| void CArtifactInstance::putAt(CGHeroInstance *h, ui16 slot) | ||||
| @@ -975,6 +965,15 @@ void CArtifactInstance::removeFrom(CGHeroInstance *h, ui16 slot) | ||||
| 	//TODO delete me? | ||||
| } | ||||
|  | ||||
| void CArtifactInstance::putAt(CStackInstance *s, ui16 slot) | ||||
| { | ||||
| 	tlog2 <<"Hero artifacts shouldn't be put on creatures!\n"; | ||||
| } | ||||
| void CArtifactInstance::removeFrom(CStackInstance *s, ui16 slot) | ||||
| { | ||||
| 	tlog2 <<"Strange, we try to remove hero artifact from CStackInstance\n"; | ||||
| } | ||||
|  | ||||
| bool CArtifactInstance::canBeDisassembled() const | ||||
| { | ||||
| 	return artType->constituents && artType->constituentOf->size(); | ||||
| @@ -1011,16 +1010,36 @@ std::vector<const CArtifact *> CArtifactInstance::assemblyPossibilities(const CG | ||||
|  | ||||
| void CArtifactInstance::move(ArtifactLocation &src, ArtifactLocation &dst) | ||||
| { | ||||
| 	removeFrom(src.hero, src.slot); | ||||
| 	putAt(dst.hero, dst.slot); | ||||
| 	if (artType->id == 135 && dst.slot == ArtifactPosition::RIGHT_HAND && !dst.hero->hasSpellbook()) //Titan's Thunder creates new spellbook on equip | ||||
| 		dst.hero->giveArtifact(0); | ||||
| 	if (src.hero) | ||||
| 		removeFrom(src.hero, src.slot); | ||||
| 	else if (src.stack) | ||||
| 		removeFrom(src.stack, src.slot); | ||||
| 	else | ||||
| 		tlog1 << "No source for moved artifact found!\n"; | ||||
|  | ||||
| 	if (dst.hero) | ||||
| 	{ | ||||
| 		putAt(dst.hero, dst.slot); | ||||
| 		if (artType->id == 135 && dst.slot == ArtifactPosition::RIGHT_HAND && !dst.hero->hasSpellbook()) //Titan's Thunder creates new spellbook on equip | ||||
| 			dst.hero->giveArtifact(0); | ||||
| 	} | ||||
| 	else if (dst.stack) | ||||
| 		putAt(dst.stack, dst.slot); | ||||
| 	else | ||||
| 		tlog1 << "No destination for moved artifact found!\n"; | ||||
|  | ||||
|  | ||||
| } | ||||
|  | ||||
| CArtifactInstance * CArtifactInstance::createNewArtifactInstance(CArtifact *Art) | ||||
| { | ||||
| 	if(!Art->constituents) | ||||
| 		return new CArtifactInstance(Art); | ||||
| 	{ | ||||
| 		 if (vstd::contains(VLC->arth->creatureArtifacts, Art->id)) | ||||
| 			 return new CCreatureArtifactInstance(Art); | ||||
| 		 else | ||||
| 			 return new CArtifactInstance(Art); | ||||
| 	} | ||||
| 	else | ||||
| 	{ | ||||
| 		CCombinedArtifactInstance * ret = new CCombinedArtifactInstance(Art); | ||||
| @@ -1233,6 +1252,56 @@ bool CCombinedArtifactInstance::ConstituentInfo::operator==(const ConstituentInf | ||||
| { | ||||
| 	return art == rhs.art && slot == rhs.slot; | ||||
| } | ||||
| CCreatureArtifactInstance::CCreatureArtifactInstance() | ||||
| { | ||||
| 	init(); | ||||
| } | ||||
|  | ||||
| CCreatureArtifactInstance::CCreatureArtifactInstance(CArtifact *Art) | ||||
| { | ||||
| 	init(); | ||||
| 	setType(Art); | ||||
| } | ||||
|  | ||||
| bool CCreatureArtifactInstance::isPart(const CArtifactInstance *supposedPart) const | ||||
| { | ||||
| 	return false; //TODO: any other proposals? | ||||
| } | ||||
|  | ||||
| std::string CCreatureArtifactInstance::nodeName() const | ||||
| { | ||||
| 	return "Creature artifact instance of " + (artType ? artType->Name() : std::string("uninitialized")) + " type"; | ||||
| } | ||||
|  | ||||
| bool CCreatureArtifactInstance::canBePutAt(const ArtifactLocation &al, bool assumeDestRemoved /*= false*/) const | ||||
| { | ||||
| 	if (al.stack) | ||||
| 	{ | ||||
| 		return true; //all artifacts should fit on creature | ||||
| 	} | ||||
| 	else if(al.slot >= GameConstants::BACKPACK_START) | ||||
| 	{	//TODO backpack limit? | ||||
| 		return true; | ||||
| 	} | ||||
| 	return false; //hero can't wear creature art | ||||
| } | ||||
|  | ||||
| void CCreatureArtifactInstance::putAt(CStackInstance *s, ui16 slot) | ||||
| { | ||||
| 	assert(canBePutAt(ArtifactLocation(s, slot))); | ||||
|  | ||||
| 	s->setNewArtSlot(slot, this, false); | ||||
| 	if(slot == GameConstants::CREATURE_ART) | ||||
| 		s->attachTo(this); | ||||
| } | ||||
|  | ||||
| void CCreatureArtifactInstance::removeFrom(CStackInstance *s, ui16 slot) | ||||
| { | ||||
| 	assert(s->CCreatureArtifactSet::getArt(slot) == this); | ||||
| 	s->eraseArtSlot(slot); | ||||
| 	if(slot == GameConstants::CREATURE_ART) //we remove worn artifact | ||||
| 		s->detachFrom(this); | ||||
| } | ||||
|  | ||||
| const CArtifactInstance* IArtifactSetBase::getArt(ui16 pos, bool excludeLocked) const | ||||
| { | ||||
|   | ||||
| @@ -16,6 +16,8 @@ | ||||
| class CDefHandler; | ||||
| class CArtifact; | ||||
| class CGHeroInstance; | ||||
| class CStackInstance; | ||||
| //class CCreatureArtifactSet; | ||||
| struct ArtifactLocation; | ||||
|  | ||||
| namespace ArtifactPosition | ||||
| @@ -75,7 +77,7 @@ public: | ||||
|  | ||||
| 	//CArtifactInstance(int aid); | ||||
|  | ||||
| 	std::string nodeName() const OVERRIDE; | ||||
| 	virtual std::string nodeName() const OVERRIDE; | ||||
| 	void deserializationFix(); | ||||
| 	void setType(CArtifact *Art); | ||||
|  | ||||
| @@ -87,6 +89,8 @@ public: | ||||
| 	virtual bool canBeDisassembled() const; | ||||
| 	virtual void putAt(CGHeroInstance *h, ui16 slot); | ||||
| 	virtual void removeFrom(CGHeroInstance *h, ui16 slot); | ||||
| 	virtual void putAt(CStackInstance *s, ui16 slot); | ||||
| 	virtual void removeFrom(CStackInstance *s, ui16 slot); | ||||
| 	virtual bool isPart(const CArtifactInstance *supposedPart) const; //checks if this a part of this artifact: artifact instance is a part of itself, additionally truth is returned for consituents of combined arts | ||||
|  | ||||
| 	std::vector<const CArtifact *> assemblyPossibilities(const CGHeroInstance *h) const; | ||||
| @@ -147,6 +151,30 @@ public: | ||||
| 	} | ||||
| }; | ||||
|  | ||||
| class DLL_LINKAGE CCreatureArtifactInstance : public CArtifactInstance | ||||
| { | ||||
| 	CCreatureArtifactInstance(CArtifact *Art); | ||||
| public: | ||||
|  | ||||
| 	bool canBePutAt(const ArtifactLocation &al, bool assumeDestRemoved = false) const OVERRIDE; | ||||
| 	void putAt(CStackInstance *s, ui16 slot) OVERRIDE; | ||||
| 	void removeFrom(CStackInstance *s, ui16 slot) OVERRIDE; | ||||
| 	bool isPart(const CArtifactInstance *supposedPart) const OVERRIDE; | ||||
|  | ||||
| 	std::string nodeName() const OVERRIDE; | ||||
|  | ||||
| 	CCreatureArtifactInstance(); | ||||
|  | ||||
| 	//void deserializationFix(); ..inherit from CArtifactInstance | ||||
|  | ||||
| 	friend class CArtifactInstance; | ||||
| 	template <typename Handler> void serialize(Handler &h, const int version) | ||||
| 	{ | ||||
| 		h & static_cast<CArtifactInstance&>(*this); | ||||
| 		BONUS_TREE_DESERIALIZATION_FIX | ||||
| 	} | ||||
| }; | ||||
|  | ||||
| // class DLL_LINKAGE IModableArt : public CArtifact //artifact which can have different properties, such as scroll or banner | ||||
| // { //used only for dynamic cast :P | ||||
| // public: | ||||
| @@ -212,7 +240,7 @@ public: | ||||
| 	std::vector< ConstTransitivePtr<CArtifact> > artifacts; | ||||
| 	std::vector<CArtifact *> allowedArtifacts; | ||||
| 	std::set<ui32> bigArtifacts; // Artifacts that cannot be moved to backpack, e.g. war machines. | ||||
| 	//std::map<ui32, ui8> modableArtifacts; //1-scroll, 2-banner, 3-commander art with progressive bonus | ||||
| 	std::set<ui32> creatureArtifacts; // can be held by Stacks | ||||
|  | ||||
| 	void loadArtifacts(bool onlyTxt); | ||||
| 	void sortArts(); | ||||
| @@ -235,6 +263,7 @@ public: | ||||
| 	template <typename Handler> void serialize(Handler &h, const int version) | ||||
| 	{ | ||||
| 		h & artifacts & allowedArtifacts & treasures & minors & majors & relics; | ||||
| 		h & creatureArtifacts; | ||||
| 		//if(!h.saving) sortArts(); | ||||
| 	} | ||||
| }; | ||||
| @@ -299,7 +328,7 @@ public: | ||||
| class DLL_LINKAGE CCreatureArtifactSet : public IArtifactSetBase | ||||
| { ///creature artifacts | ||||
| public: | ||||
| 	std::vector<ArtSlotInfo> artifactsInBackpack; //artifacts carried by creature - 4 max | ||||
| 	std::vector<ArtSlotInfo> artifactsInBackpack; //artifacts carried by creature - 4 max (according to WoG) | ||||
| 	ArtSlotInfo activeArtifact; //position 0 - Arts::CREATURE_ART | ||||
|  | ||||
| 	ArtSlotInfo &retreiveNewArtSlot(ui16 slot); | ||||
|   | ||||
| @@ -3,11 +3,12 @@ | ||||
|  | ||||
| #include "HeroBonus.h" | ||||
| #include "GameConstants.h" | ||||
| #include "CArtHandler.h" | ||||
|  | ||||
| class CCreature; | ||||
| class CGHeroInstance; | ||||
| class CArmedInstance; | ||||
|  | ||||
| class CCreatureArtifactSet; | ||||
|  | ||||
| class DLL_LINKAGE CStackBasicDescriptor | ||||
| { | ||||
| @@ -25,20 +26,20 @@ public: | ||||
| 	} | ||||
| }; | ||||
|  | ||||
| class DLL_LINKAGE CStackInstance : public CBonusSystemNode, public CStackBasicDescriptor | ||||
| class DLL_LINKAGE CStackInstance : public CBonusSystemNode, public CStackBasicDescriptor, public CCreatureArtifactSet | ||||
| { | ||||
| 	const CArmedInstance *_armyObj; //stack must be part of some army, army must be part of some object | ||||
| public: | ||||
| 	int idRand; //hlp variable used during loading game -> "id" placeholder for randomization | ||||
|  | ||||
| 	const CArmedInstance * const & armyObj; //stack must be part of some army, army must be part of some object | ||||
| 	ui32 experience; //TODO: handle | ||||
| 	//TODO: stack artifacts | ||||
| 	ui32 experience; | ||||
|  | ||||
| 	template <typename Handler> void serialize(Handler &h, const int version) | ||||
| 	{ | ||||
| 		h & static_cast<CBonusSystemNode&>(*this); | ||||
| 		h & static_cast<CStackBasicDescriptor&>(*this); | ||||
| 		h & static_cast<CCreatureArtifactSet&>(*this); | ||||
| 		h & _armyObj & experience; | ||||
| 		BONUS_TREE_DESERIALIZATION_FIX | ||||
| 	} | ||||
|   | ||||
| @@ -1410,6 +1410,7 @@ void CGameState::init( StartInfo * si, ui32 checksum, int Seed ) | ||||
| 				CGHeroInstance *hero = k->second.heroes[0]; | ||||
|  				hero->giveArtifact(toGive->id); | ||||
| 			} | ||||
| 			break; | ||||
| 		} | ||||
| 	} | ||||
| 	/****************************TOWNS************************************************/ | ||||
|   | ||||
| @@ -83,13 +83,17 @@ namespace GameConstants | ||||
| 	const int WEEKLY_GROWTH = 10; //percent | ||||
| 	const int AVAILABLE_HEROES_PER_PLAYER = 2; | ||||
| 	const bool DWELLINGS_ACCUMULATE_CREATURES = false; | ||||
| 	const bool STACK_EXP = true; | ||||
| 	const bool STACK_ARTIFACT = true; | ||||
| 	const int SPELLBOOK_GOLD_COST = 500; | ||||
|  | ||||
| 	const ui16 BACKPACK_START = 19; | ||||
| 	const int ID_CATAPULT = 3, ID_LOCK = 145; | ||||
| 	const ui16 CREATURE_ART = 0; | ||||
|  | ||||
| 	//game modules | ||||
| 	const bool STACK_EXP = true; | ||||
| 	const bool STACK_ARTIFACT = true; //now toggle for testing | ||||
| 	const bool COMMANDERS = false; | ||||
| 	const bool MITHRIL = false; | ||||
| } | ||||
|  | ||||
| // Enum declarations | ||||
|   | ||||
| @@ -845,6 +845,7 @@ typedef si32 TArtPos; | ||||
| struct ArtifactLocation | ||||
| { | ||||
| 	ConstTransitivePtr<CGHeroInstance> hero; | ||||
| 	ConstTransitivePtr<CStackInstance> stack; | ||||
| 	TArtPos slot; | ||||
|  | ||||
| 	ArtifactLocation() | ||||
| @@ -854,6 +855,13 @@ struct ArtifactLocation | ||||
| 	ArtifactLocation(const CGHeroInstance *Hero, TArtPos Slot) | ||||
| 	{ | ||||
| 		hero = const_cast<CGHeroInstance*>(Hero); //we are allowed here to const cast -> change will go through one of our packages... do not abuse! | ||||
| 		stack = NULL; | ||||
| 		slot = Slot; | ||||
| 	} | ||||
| 	ArtifactLocation(const CStackInstance *Stack, TArtPos Slot) | ||||
| 	{ | ||||
| 		stack = const_cast<CStackInstance*>(Stack); //we are allowed here to const cast -> change will go through one of our packages... do not abuse! | ||||
| 		hero = NULL; | ||||
| 		slot = Slot; | ||||
| 	} | ||||
| 	DLL_LINKAGE const CArtifactInstance *getArt() const; | ||||
| @@ -861,7 +869,7 @@ struct ArtifactLocation | ||||
| 	DLL_LINKAGE const ArtSlotInfo *getSlot() const; | ||||
| 	template <typename Handler> void serialize(Handler &h, const int version) | ||||
| 	{ | ||||
| 		h & hero & slot; | ||||
| 		h & hero & stack & slot; | ||||
| 	} | ||||
| }; | ||||
|  | ||||
| @@ -1746,17 +1754,19 @@ struct GarrisonHeroSwap : public CPackForServer | ||||
| }; | ||||
|  | ||||
| struct ExchangeArtifacts : public CPackForServer | ||||
| //TODO: allow exchange between heroes, stacks and commanders | ||||
| { | ||||
| 	ExchangeArtifacts(){}; | ||||
| 	ExchangeArtifacts(si32 H1, si32 H2, ui16 S1, ui16 S2) | ||||
| 		:hid1(H1),hid2(H2),slot1(S1),slot2(S2){}; | ||||
| 	si32 hid1, hid2; | ||||
| 	StackLocation s1, s2; //for creature stacks | ||||
| 	ui16 slot1, slot2; | ||||
|  | ||||
| 	bool applyGh(CGameHandler *gh); | ||||
| 	template <typename Handler> void serialize(Handler &h, const int version) | ||||
| 	{ | ||||
| 		h & hid1 & hid2 & slot1 & slot2; | ||||
| 		h & hid1 & hid2 & s1 & s2 & slot1 & slot2; | ||||
| 	} | ||||
| }; | ||||
|  | ||||
|   | ||||
| @@ -94,6 +94,7 @@ void registerTypes1(Serializer &s) | ||||
| 	s.template registerType<BattleInfo>(); | ||||
| 	s.template registerType<CArtifactInstance>(); | ||||
| 	s.template registerType<CCombinedArtifactInstance>(); | ||||
| 	s.template registerType<CCreatureArtifactInstance>(); | ||||
| } | ||||
|  | ||||
| template<typename Serializer>  | ||||
|   | ||||
| @@ -2572,6 +2572,40 @@ bool CGameHandler::moveArtifact(si32 srcHeroID, si32 destHeroID, ui16 srcSlot, u | ||||
| 	return true; | ||||
| } | ||||
|  | ||||
| bool CGameHandler::moveArtifact(StackLocation s1, StackLocation s2, ui16 srcSlot, ui16 destSlot) | ||||
| { | ||||
| 	ArtifactLocation src(s1.getStack(), srcSlot), dst(s2.getStack(), destSlot); | ||||
| 	moveArtifact(src, dst); | ||||
| 	return true; | ||||
| } | ||||
|  | ||||
| bool CGameHandler::moveArtifact(si32 srcHeroID, StackLocation s2, ui16 srcSlot, ui16 destSlot) | ||||
| { | ||||
| 	ArtifactLocation src(getHero(srcHeroID), srcSlot); | ||||
| 	ArtifactLocation dst(s2.getStack(), destSlot); | ||||
| 	moveArtifact(src, dst); | ||||
| 	return true; | ||||
| } | ||||
| bool CGameHandler::moveArtifact(StackLocation s1, si32 destHeroID, ui16 srcSlot, ui16 destSlot) | ||||
| { | ||||
| 	ArtifactLocation src(s1.getStack(), srcSlot); | ||||
| 	ArtifactLocation dst(getHero(destHeroID), destSlot); | ||||
| 	//hero should not wear stack artifact | ||||
| 	vstd::amin(dst.slot, GameConstants::BACKPACK_START + dst.hero->artifactsInBackpack.size()); //put on first free position | ||||
| 	moveArtifact(src, dst); | ||||
| 	return true; | ||||
| } | ||||
|  | ||||
| void CGameHandler::moveArtifact(const ArtifactLocation &al1, const ArtifactLocation &al2) | ||||
| { | ||||
| 	MoveArtifact ma; | ||||
| 	ma.src = al1; | ||||
| 	ma.dst = al2; | ||||
| 	sendAndApply(&ma); | ||||
| } | ||||
|  | ||||
|  | ||||
|  | ||||
| /** | ||||
|  * Assembles or disassembles a combination artifact. | ||||
|  * @param heroID ID of hero holding the artifact(s). | ||||
| @@ -5501,21 +5535,20 @@ void CGameHandler::putArtifact(const ArtifactLocation &al, const CArtifactInstan | ||||
| 	sendAndApply(&pa); | ||||
| } | ||||
|  | ||||
| void CGameHandler::moveArtifact(const ArtifactLocation &al1, const ArtifactLocation &al2) | ||||
| { | ||||
| 	MoveArtifact ma; | ||||
| 	ma.src = al1; | ||||
| 	ma.dst = al2; | ||||
| 	sendAndApply(&ma); | ||||
| } | ||||
|  | ||||
| void CGameHandler::giveHeroNewArtifact(const CGHeroInstance *h, const CArtifact *artType, int pos) | ||||
| { | ||||
| 	CArtifactInstance *a = NULL; | ||||
| 	if(!artType->constituents) | ||||
| 		a = new CArtifactInstance(); | ||||
| 	{ | ||||
| 		if (vstd::contains(VLC->arth->creatureArtifacts, artType->id)) | ||||
| 			a = new CCreatureArtifactInstance(); | ||||
| 		else | ||||
| 			a = new CArtifactInstance(); | ||||
| 	} | ||||
| 	else | ||||
| 	{ | ||||
| 		a = new CCombinedArtifactInstance(); | ||||
| 	} | ||||
| 	a->artType = artType; //*NOT* via settype -> all bonus-related stuff must be done by NewArtifact apply | ||||
| 	 | ||||
| 	NewArtifact na; | ||||
|   | ||||
| @@ -210,6 +210,9 @@ public: | ||||
| 	bool sellArtifact( const IMarket *m, const CGHeroInstance *h, int aid, int rid); //for artifact merchant selling | ||||
| 	bool buySecSkill( const IMarket *m, const CGHeroInstance *h, int skill); | ||||
| 	bool moveArtifact(si32 srcHeroID, si32 destHeroID, ui16 srcSlot, ui16 destSlot); | ||||
| 	bool moveArtifact(StackLocation s1, StackLocation s2, ui16 srcSlot, ui16 destSlot); //called when stacks merge | ||||
| 	bool moveArtifact(si32 srcHeroID, StackLocation s2, ui16 srcSlot, ui16 destSlot); //equip artifact | ||||
| 	bool moveArtifact(StackLocation s1, si32 destHeroID, ui16 srcSlot, ui16 destSlot); //return artifact to backpack | ||||
| 	bool garrisonSwap(si32 tid); | ||||
| 	bool upgradeCreature( ui32 objid, ui8 pos, ui32 upgID ); | ||||
| 	bool recruitCreatures(si32 objid, ui32 crid, ui32 cram, si32 level); | ||||
|   | ||||
		Reference in New Issue
	
	Block a user