예제 #1
0
bool CCombinedArtifactInstance::canBePutAt(const CArtifactSet *artSet, ArtifactPosition slot, bool assumeDestRemoved /*= false*/) const
{
	bool canMainArtifactBePlaced = CArtifactInstance::canBePutAt(artSet, slot, assumeDestRemoved);
	if(!canMainArtifactBePlaced)
		return false; //no is no...
	if(slot >= GameConstants::BACKPACK_START)
		return true; //we can always remove combined art to the backapck


	assert(artType->constituents);
	std::vector<ConstituentInfo> constituentsToBePlaced = constituentsInfo; //we'll remove constituents from that list, as we find a suitable slot for them

	//it may be that we picked a combined artifact in hero screen (though technically it's still there) to move it
	//so we remove from the list all constituents that are already present on dst hero in the form of locks
	for(const ConstituentInfo &constituent : constituentsInfo)
	{
		if(constituent.art == artSet->getArt(constituent.slot, false)) //no need to worry about locked constituent
			constituentsToBePlaced -= constituent;
	}

	//we iterate over all active slots and check if constituents fits them
	for (int i = 0; i < GameConstants::BACKPACK_START; i++)
	{
		for(auto art = constituentsToBePlaced.begin(); art != constituentsToBePlaced.end(); art++)
		{
			if(art->art->canBePutAt(artSet, ArtifactPosition(i), i == slot)) // i == al.slot because we can remove already worn artifact only from that slot  that is our main destination
			{
				constituentsToBePlaced.erase(art);
				break;
			}
		}
	}

	return constituentsToBePlaced.empty();
}
예제 #2
0
ArtifactPosition CArtifactInstance::firstBackpackSlot(const CArtifactSet *h) const
{
	if(!artType->isBig()) //discard big artifact
		return ArtifactPosition(
			GameConstants::BACKPACK_START + h->artifactsInBackpack.size());

	return ArtifactPosition::PRE_FIRST;
}
예제 #3
0
void CArtHandler::makeItCommanderArt (CArtifact * a, bool onlyCommander /*= true*/ )
{
	if (onlyCommander)
	{
		a->possibleSlots[ArtBearer::HERO].clear();
		a->possibleSlots[ArtBearer::CREATURE].clear();
	}
	for (int i = ArtifactPosition::COMMANDER1; i <= ArtifactPosition::COMMANDER6; ++i)
		a->possibleSlots[ArtBearer::COMMANDER].push_back(ArtifactPosition(i));
}
예제 #4
0
void CGHeroInstance::initArmy(IArmyDescriptor *dst /*= nullptr*/)
{
	if(!dst)
		dst = this;

	int howManyStacks = 0; //how many stacks will hero receives <1 - 3>
	int pom = cb->gameState()->getRandomGenerator().nextInt(99);
	int warMachinesGiven = 0;

	if(pom < 9)
		howManyStacks = 1;
	else if(pom < 79)
		howManyStacks = 2;
	else
		howManyStacks = 3;

	vstd::amin(howManyStacks, type->initialArmy.size());

	for(int stackNo=0; stackNo < howManyStacks; stackNo++)
	{
		auto & stack = type->initialArmy[stackNo];

		int count = cb->gameState()->getRandomGenerator().nextInt(stack.minAmount, stack.maxAmount);

		if(stack.creature >= CreatureID::CATAPULT &&
		   stack.creature <= CreatureID::ARROW_TOWERS) //war machine
		{
			warMachinesGiven++;
			if(dst != this)
				continue;

			int slot = -1;
			ArtifactID aid = ArtifactID::NONE;
			switch (stack.creature)
			{
			case CreatureID::CATAPULT:
				slot = ArtifactPosition::MACH4;
				aid = ArtifactID::CATAPULT;
				break;
			default:
				aid = CArtHandler::creatureToMachineID(stack.creature);
				slot = 9 + aid;
				break;
			}
			auto convSlot = ArtifactPosition(slot);
			if(!getArt(convSlot))
				putArtifact(convSlot, CArtifactInstance::createNewArtifactInstance(aid));
			else
                logGlobal->warnStream() << "Hero " << name << " already has artifact at " << slot << ", omitting giving " << aid;
		}
		else
			dst->setCreature(SlotID(stackNo-warMachinesGiven), stack.creature, count);
	}
}
예제 #5
0
void CArtifactSet::eraseArtSlot(ArtifactPosition slot)
{
	if(slot < GameConstants::BACKPACK_START)
	{
		artifactsWorn.erase(slot);
	}
	else
	{
		slot = ArtifactPosition(slot - GameConstants::BACKPACK_START);
		artifactsInBackpack.erase(artifactsInBackpack.begin() + slot);
	}
}
예제 #6
0
ArtifactPosition CArtifactSet::getArtPos(const CArtifactInstance *art) const
{
	for(auto i : artifactsWorn)
		if(i.second.artifact == art)
			return i.first;

	for(int i = 0; i < artifactsInBackpack.size(); i++)
		if(artifactsInBackpack[i].artifact == art)
			return ArtifactPosition(GameConstants::BACKPACK_START + i);

	return ArtifactPosition::PRE_FIRST;
}
예제 #7
0
bool TradeOnMarketplace::applyGh( CGameHandler *gh )
{
	//market must be owned or visited
	const IMarket *m = IMarket::castFrom(market);

	if(!m)
		COMPLAIN_AND_RETURN("market is not-a-market! :/");

	ui8 player = market->tempOwner;

	if(player >= GameConstants::PLAYER_LIMIT)
		player = gh->getTile(market->visitablePos())->visitableObjects.back()->tempOwner;

	if(player >= GameConstants::PLAYER_LIMIT)
		COMPLAIN_AND_RETURN("No player can use this market!");

	if(hero && (player != hero->tempOwner || hero->visitablePos() != market->visitablePos()))
		COMPLAIN_AND_RETURN("This hero can't use this marketplace!");

	ERROR_IF_NOT(player);

	switch(mode)
	{
	case EMarketMode::RESOURCE_RESOURCE:
		return gh->tradeResources(m, val, player, r1, r2);
	case EMarketMode::RESOURCE_PLAYER:
		return gh->sendResources(val, player, static_cast<Res::ERes>(r1), static_cast<TPlayerColor>(r2));
	case EMarketMode::CREATURE_RESOURCE:
		if(!hero)
			COMPLAIN_AND_RETURN("Only hero can sell creatures!");
		return gh->sellCreatures(val, m, hero, r1, static_cast<Res::ERes>(r2));
	case EMarketMode::RESOURCE_ARTIFACT:
		if(!hero)
			COMPLAIN_AND_RETURN("Only hero can buy artifacts!");
		return gh->buyArtifact(m, hero, static_cast<Res::ERes>(r1), ArtifactID(r2));
	case EMarketMode::ARTIFACT_RESOURCE:
		if(!hero)
			COMPLAIN_AND_RETURN("Only hero can sell artifacts!");
		return gh->sellArtifact(m, hero, ArtifactInstanceID(r1), static_cast<Res::ERes>(r2));
	case EMarketMode::CREATURE_UNDEAD:
		return gh->transformInUndead(m, hero, r1);
	case EMarketMode::RESOURCE_SKILL:
		return gh->buySecSkill(m, hero, SecondarySkill(r2));
	case EMarketMode::CREATURE_EXP:
		return gh->sacrificeCreatures(m, hero, r1, val);
	case EMarketMode::ARTIFACT_EXP:
		return gh->sacrificeArtifact(m, hero, ArtifactPosition(r1));
	default:
		COMPLAIN_AND_RETURN("Unknown exchange mode!");
	}
}
예제 #8
0
ArtifactPosition CArtifactSet::getArtPos(int aid, bool onlyWorn /*= true*/) const
{
	for(auto i = artifactsWorn.cbegin(); i != artifactsWorn.cend(); i++)
		if(i->second.artifact->artType->id == aid)
			return i->first;

	if(onlyWorn)
		return ArtifactPosition::PRE_FIRST;

	for(int i = 0; i < artifactsInBackpack.size(); i++)
		if(artifactsInBackpack[i].artifact->artType->id == aid)
			return ArtifactPosition(GameConstants::BACKPACK_START + i);

	return ArtifactPosition::PRE_FIRST;
}