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(); }
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; }
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)); }
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); } }
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); } }
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; }
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!"); } }
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; }