mirror of
https://github.com/vcmi/vcmi.git
synced 2024-12-24 22:14:36 +02:00
Backpack limit part2 (Pick up, Dig up, Object rewards)
This commit is contained in:
parent
96e8a1f21c
commit
e23766280f
@ -212,7 +212,7 @@ public:
|
||||
void removeAfterVisit(const CGObjectInstance * object) override {};
|
||||
bool swapGarrisonOnSiege(ObjectInstanceID tid) override {return false;};
|
||||
void giveHeroNewArtifact(const CGHeroInstance * h, const CArtifact * artType, ArtifactPosition pos) override {};
|
||||
void giveHeroArtifact(const CGHeroInstance * h, const CArtifactInstance * a, ArtifactPosition pos) override {};
|
||||
bool giveHeroArtifact(const CGHeroInstance * h, const CArtifactInstance * a, ArtifactPosition pos) override {return false;};
|
||||
void putArtifact(const ArtifactLocation & al, const CArtifactInstance * a) override {};
|
||||
void removeArtifact(const ArtifactLocation & al) override {};
|
||||
bool moveArtifact(const ArtifactLocation & al1, const ArtifactLocation & al2) override {return false;};
|
||||
|
@ -176,7 +176,7 @@ bool CArtifact::canBePutAt(const CArtifactSet * artSet, ArtifactPosition slot, b
|
||||
if(!simpleArtCanBePutAt(artSet, slot, assumeDestRemoved))
|
||||
return false;
|
||||
if(ArtifactUtils::isSlotBackpack(slot))
|
||||
return true; //TODO backpack limit
|
||||
return true;
|
||||
|
||||
CArtifactFittingSet fittingSet(artSet->bearerType());
|
||||
fittingSet.artifactsWorn = artSet->artifactsWorn;
|
||||
@ -1082,7 +1082,7 @@ void CCombinedArtifactInstance::putAt(ArtifactLocation al)
|
||||
CArtifactInstance *mainConstituent = figureMainConstituent(al); //it'll be replaced with combined artifact, not a lock
|
||||
CArtifactInstance::putAt(al); //puts combined art (this)
|
||||
|
||||
for(ConstituentInfo &ci : constituentsInfo)
|
||||
for(ConstituentInfo & ci : constituentsInfo)
|
||||
{
|
||||
if(ci.art != mainConstituent)
|
||||
{
|
||||
@ -1090,14 +1090,11 @@ void CCombinedArtifactInstance::putAt(ArtifactLocation al)
|
||||
const bool inActiveSlot = vstd::isbetween(ci.slot, 0, GameConstants::BACKPACK_START);
|
||||
const bool suggestedPosValid = ci.art->canBePutAt(suggestedPos);
|
||||
|
||||
ArtifactPosition pos = ArtifactPosition::PRE_FIRST;
|
||||
if(inActiveSlot && suggestedPosValid) //there is a valid suggestion where to place lock
|
||||
pos = ci.slot;
|
||||
else
|
||||
ci.slot = pos = ci.art->firstAvailableSlot(al.getHolderArtSet());
|
||||
if(!(inActiveSlot && suggestedPosValid)) //there is a valid suggestion where to place lock
|
||||
ci.slot = ArtifactUtils::getArtifactDstPosition(ci.art->artType->getId(), al.getHolderArtSet());
|
||||
|
||||
assert(!ArtifactUtils::isSlotBackpack(pos));
|
||||
al.getHolderArtSet()->setNewArtSlot(pos, ci.art, true); //sets as lock
|
||||
assert(ArtifactUtils::isSlotEquipment(ci.slot));
|
||||
al.getHolderArtSet()->setNewArtSlot(ci.slot, ci.art, true); //sets as lock
|
||||
}
|
||||
else
|
||||
{
|
||||
@ -1525,8 +1522,10 @@ void CArtifactFittingSet::putArtifact(ArtifactPosition pos, CArtifactInstance *
|
||||
{
|
||||
for(auto & part : dynamic_cast<CCombinedArtifactInstance*>(art)->constituentsInfo)
|
||||
{
|
||||
const auto slot = ArtifactUtils::getArtifactDstPosition(part.art->artType->getId(), this);
|
||||
assert(slot != ArtifactPosition::PRE_FIRST);
|
||||
// For the ArtFittingSet is no needed to do figureMainConstituent, just lock slots
|
||||
this->setNewArtSlot(part.art->firstAvailableSlot(this), part.art, true);
|
||||
this->setNewArtSlot(slot, part.art, true);
|
||||
}
|
||||
}
|
||||
else
|
||||
@ -1650,4 +1649,13 @@ DLL_LINKAGE bool ArtifactUtils::isBackpackFreeSlots(const CArtifactSet * target,
|
||||
return target->artifactsInBackpack.size() + reqSlots <= backpackCap;
|
||||
}
|
||||
|
||||
DLL_LINKAGE bool ArtifactUtils::isPossibleToGetArt(const CArtifactSet * target, const ArtifactID & aid)
|
||||
{
|
||||
const auto slot = getArtifactDstPosition(aid, target);
|
||||
if(isSlotEquipment(slot) || (isSlotBackpack(slot) && isBackpackFreeSlots(target)))
|
||||
return true;
|
||||
else
|
||||
return false;
|
||||
}
|
||||
|
||||
VCMI_LIB_NAMESPACE_END
|
||||
|
@ -389,6 +389,7 @@ namespace ArtifactUtils
|
||||
DLL_LINKAGE bool isSlotBackpack(const ArtifactPosition & slot);
|
||||
DLL_LINKAGE bool isSlotEquipment(const ArtifactPosition & slot);
|
||||
DLL_LINKAGE bool isBackpackFreeSlots(const CArtifactSet * target, const size_t reqSlots = 1);
|
||||
DLL_LINKAGE bool isPossibleToGetArt(const CArtifactSet * target, const ArtifactID & aid);
|
||||
}
|
||||
|
||||
VCMI_LIB_NAMESPACE_END
|
||||
|
@ -1588,12 +1588,17 @@ void CGameState::giveCampaignBonusToHero(CGHeroInstance * hero)
|
||||
}
|
||||
break;
|
||||
case CScenarioTravel::STravelBonus::ARTIFACT:
|
||||
gs->giveHeroArtifact(hero, static_cast<ArtifactID>(curBonus->info2));
|
||||
if(!gs->giveHeroArtifact(hero, static_cast<ArtifactID>(curBonus->info2)))
|
||||
logGlobal->error("Cannot give starting artifact - no free slots!");
|
||||
break;
|
||||
case CScenarioTravel::STravelBonus::SPELL_SCROLL:
|
||||
{
|
||||
CArtifactInstance * scroll = CArtifactInstance::createScroll(SpellID(curBonus->info2));
|
||||
scroll->putAt(ArtifactLocation(hero, scroll->firstAvailableSlot(hero)));
|
||||
const auto slot = ArtifactUtils::getArtifactDstPosition(scroll->artType->getId(), hero);
|
||||
if(ArtifactUtils::isSlotEquipment(slot) || ArtifactUtils::isSlotBackpack(slot))
|
||||
scroll->putAt(ArtifactLocation(hero, slot));
|
||||
else
|
||||
logGlobal->error("Cannot give starting scroll - no free slots!");
|
||||
}
|
||||
break;
|
||||
case CScenarioTravel::STravelBonus::PRIMARY_SKILL:
|
||||
@ -1686,7 +1691,10 @@ void CGameState::initStartingBonus()
|
||||
const Artifact * toGive = VLC->arth->pickRandomArtifact(getRandomGenerator(), CArtifact::ART_TREASURE).toArtifact(VLC->artifacts());
|
||||
|
||||
CGHeroInstance *hero = elem.second.heroes[0];
|
||||
giveHeroArtifact(hero, toGive->getId());
|
||||
if(!giveHeroArtifact(hero, toGive->getId()))
|
||||
{
|
||||
logGlobal->error("Cannot give starting artifact - no free slots!");
|
||||
}
|
||||
}
|
||||
break;
|
||||
}
|
||||
@ -2805,12 +2813,21 @@ void CGameState::attachArmedObjects()
|
||||
}
|
||||
}
|
||||
|
||||
void CGameState::giveHeroArtifact(CGHeroInstance * h, const ArtifactID & aid)
|
||||
bool CGameState::giveHeroArtifact(CGHeroInstance * h, const ArtifactID & aid)
|
||||
{
|
||||
CArtifact * const artifact = VLC->arth->objects[aid]; //pointer to constant object
|
||||
CArtifactInstance *ai = CArtifactInstance::createNewArtifactInstance(artifact);
|
||||
CArtifactInstance * ai = CArtifactInstance::createNewArtifactInstance(artifact);
|
||||
map->addNewArtifactInstance(ai);
|
||||
ai->putAt(ArtifactLocation(h, ai->firstAvailableSlot(h)));
|
||||
auto slot = ArtifactUtils::getArtifactDstPosition(aid, h);
|
||||
if(ArtifactUtils::isSlotEquipment(slot) || ArtifactUtils::isSlotBackpack(slot))
|
||||
{
|
||||
ai->putAt(ArtifactLocation(h, slot));
|
||||
return true;
|
||||
}
|
||||
else
|
||||
{
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
std::set<HeroTypeID> CGameState::getUnusedAllowedHeroes(bool alsoIncludeNotAllowed) const
|
||||
|
@ -178,7 +178,7 @@ public:
|
||||
|
||||
void updateEntity(Metatype metatype, int32_t index, const JsonNode & data) override;
|
||||
|
||||
void giveHeroArtifact(CGHeroInstance * h, const ArtifactID & aid);
|
||||
bool giveHeroArtifact(CGHeroInstance * h, const ArtifactID & aid);
|
||||
|
||||
void apply(CPack *pack);
|
||||
BattleField battleGetBattlefieldType(int3 tile, CRandomGenerator & rand);
|
||||
|
@ -110,7 +110,7 @@ public:
|
||||
virtual void removeAfterVisit(const CGObjectInstance *object) = 0; //object will be destroyed when interaction is over. Do not call when interaction is not ongoing!
|
||||
|
||||
virtual void giveHeroNewArtifact(const CGHeroInstance *h, const CArtifact *artType, ArtifactPosition pos) = 0;
|
||||
virtual void giveHeroArtifact(const CGHeroInstance *h, const CArtifactInstance *a, ArtifactPosition pos) = 0; //pos==-1 - first free slot in backpack=0; pos==-2 - default if available or backpack
|
||||
virtual bool giveHeroArtifact(const CGHeroInstance *h, const CArtifactInstance *a, ArtifactPosition pos) = 0; //pos==-1 - first free slot in backpack=0; pos==-2 - default if available or backpack
|
||||
virtual void putArtifact(const ArtifactLocation &al, const CArtifactInstance *a) = 0;
|
||||
virtual void removeArtifact(const ArtifactLocation &al) = 0;
|
||||
virtual bool moveArtifact(const ArtifactLocation &al1, const ArtifactLocation &al2) = 0;
|
||||
|
@ -855,7 +855,8 @@ void CGSeerHut::completeQuest (const CGHeroInstance * h) const //reward
|
||||
cb->changeSecSkill(h, SecondarySkill(rID), rVal, false);
|
||||
break;
|
||||
case ARTIFACT:
|
||||
cb->giveHeroNewArtifact(h, VLC->arth->objects[rID],ArtifactPosition::FIRST_AVAILABLE);
|
||||
if(ArtifactUtils::isPossibleToGetArt(h, VLC->arth->objects[rID]->getId()))
|
||||
cb->giveHeroNewArtifact(h, VLC->arth->objects[rID],ArtifactPosition::FIRST_AVAILABLE);
|
||||
break;
|
||||
case SPELL:
|
||||
{
|
||||
|
@ -1300,9 +1300,12 @@ void CGArtifact::onHeroVisit(const CGHeroInstance * h) const
|
||||
InfoWindow iw;
|
||||
iw.type = EInfoWindowMode::AUTO;
|
||||
iw.player = h->tempOwner;
|
||||
switch(ID)
|
||||
|
||||
if(ArtifactUtils::isPossibleToGetArt(h, storedArtifact->artType->getId()))
|
||||
{
|
||||
case Obj::ARTIFACT:
|
||||
switch (ID)
|
||||
{
|
||||
case Obj::ARTIFACT:
|
||||
{
|
||||
iw.components.emplace_back(Component::EComponentType::ARTIFACT, subID, 0, 0);
|
||||
if(message.length())
|
||||
@ -1311,7 +1314,7 @@ void CGArtifact::onHeroVisit(const CGHeroInstance * h) const
|
||||
iw.text.addTxt(MetaString::ART_EVNTS, subID);
|
||||
}
|
||||
break;
|
||||
case Obj::SPELL_SCROLL:
|
||||
case Obj::SPELL_SCROLL:
|
||||
{
|
||||
int spellID = storedArtifact->getGivenSpellID();
|
||||
iw.components.emplace_back(Component::EComponentType::SPELL, spellID, 0, 0);
|
||||
@ -1319,11 +1322,16 @@ void CGArtifact::onHeroVisit(const CGHeroInstance * h) const
|
||||
iw.text << message;
|
||||
else
|
||||
{
|
||||
iw.text.addTxt(MetaString::ADVOB_TXT,135);
|
||||
iw.text.addTxt(MetaString::ADVOB_TXT, 135);
|
||||
iw.text.addReplacement(MetaString::SPELL_NAME, spellID);
|
||||
}
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
iw.text << "no slots";
|
||||
}
|
||||
cb->showInfoDialog(&iw);
|
||||
pick(h);
|
||||
@ -1368,8 +1376,8 @@ void CGArtifact::onHeroVisit(const CGHeroInstance * h) const
|
||||
|
||||
void CGArtifact::pick(const CGHeroInstance * h) const
|
||||
{
|
||||
cb->giveHeroArtifact(h, storedArtifact, ArtifactPosition::FIRST_AVAILABLE);
|
||||
cb->removeObject(this);
|
||||
if(cb->giveHeroArtifact(h, storedArtifact, ArtifactPosition::FIRST_AVAILABLE))
|
||||
cb->removeObject(this);
|
||||
}
|
||||
|
||||
BattleField CGArtifact::getBattlefield() const
|
||||
|
@ -5876,13 +5876,18 @@ bool CGameHandler::dig(const CGHeroInstance *h)
|
||||
if (h->diggingStatus() != EDiggingStatus::CAN_DIG) //checks for terrain and movement
|
||||
COMPLAIN_RETF("Hero cannot dig (error code %d)!", h->diggingStatus());
|
||||
|
||||
//create a hole
|
||||
NewObject no;
|
||||
no.ID = Obj::HOLE;
|
||||
no.pos = h->visitablePos();
|
||||
no.subID = 0;
|
||||
sendAndApply(&no);
|
||||
|
||||
const auto isHeroAbleGet = ArtifactUtils::isPossibleToGetArt(h, ArtifactID::GRAIL);
|
||||
|
||||
if(isHeroAbleGet)
|
||||
{
|
||||
//create a hole
|
||||
NewObject no;
|
||||
no.ID = Obj::HOLE;
|
||||
no.pos = h->visitablePos();
|
||||
no.subID = 0;
|
||||
sendAndApply(&no);
|
||||
}
|
||||
|
||||
//take MPs
|
||||
SetMovePoints smp;
|
||||
smp.hid = h->id;
|
||||
@ -5894,17 +5899,25 @@ bool CGameHandler::dig(const CGHeroInstance *h)
|
||||
iw.player = h->tempOwner;
|
||||
if (gs->map->grailPos == h->visitablePos())
|
||||
{
|
||||
iw.text.addTxt(MetaString::GENERAL_TXT, 58); //"Congratulations! After spending many hours digging here, your hero has uncovered the "
|
||||
iw.text.addTxt(MetaString::ART_NAMES, ArtifactID::GRAIL);
|
||||
iw.soundID = soundBase::ULTIMATEARTIFACT;
|
||||
giveHeroNewArtifact(h, VLC->arth->objects[ArtifactID::GRAIL], ArtifactPosition::PRE_FIRST); //give grail
|
||||
sendAndApply(&iw);
|
||||
if(isHeroAbleGet)
|
||||
{
|
||||
iw.text.addTxt(MetaString::GENERAL_TXT, 58); //"Congratulations! After spending many hours digging here, your hero has uncovered the "
|
||||
iw.text.addTxt(MetaString::ART_NAMES, ArtifactID::GRAIL);
|
||||
iw.soundID = soundBase::ULTIMATEARTIFACT;
|
||||
giveHeroNewArtifact(h, VLC->arth->objects[ArtifactID::GRAIL], ArtifactPosition::PRE_FIRST); //give grail
|
||||
sendAndApply(&iw);
|
||||
|
||||
iw.soundID = soundBase::invalid;
|
||||
iw.components.emplace_back(Component::EComponentType::ARTIFACT, ArtifactID::GRAIL, 0, 0);
|
||||
iw.text.clear();
|
||||
iw.text.addTxt(MetaString::ART_DESCR, ArtifactID::GRAIL);
|
||||
sendAndApply(&iw);
|
||||
iw.soundID = soundBase::invalid;
|
||||
iw.components.emplace_back(Component::EComponentType::ARTIFACT, ArtifactID::GRAIL, 0, 0);
|
||||
iw.text.clear();
|
||||
iw.text.addTxt(MetaString::ART_DESCR, ArtifactID::GRAIL);
|
||||
sendAndApply(&iw);
|
||||
}
|
||||
else
|
||||
{
|
||||
iw.text << "found but no free slots";
|
||||
sendAndApply(&iw);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
@ -6818,35 +6831,32 @@ bool CGameHandler::makeAutomaticAction(const CStack *stack, BattleAction &ba)
|
||||
return ret;
|
||||
}
|
||||
|
||||
void CGameHandler::giveHeroArtifact(const CGHeroInstance *h, const CArtifactInstance *a, ArtifactPosition pos)
|
||||
bool CGameHandler::giveHeroArtifact(const CGHeroInstance * h, const CArtifactInstance * a, ArtifactPosition pos)
|
||||
{
|
||||
assert(a->artType);
|
||||
ArtifactLocation al;
|
||||
al.artHolder = const_cast<CGHeroInstance*>(h);
|
||||
ArtifactLocation al(h, ArtifactPosition::PRE_FIRST);
|
||||
|
||||
ArtifactPosition slot = ArtifactPosition::PRE_FIRST;
|
||||
if (pos < 0)
|
||||
if(pos == ArtifactPosition::FIRST_AVAILABLE)
|
||||
{
|
||||
if (pos == ArtifactPosition::FIRST_AVAILABLE)
|
||||
slot = a->firstAvailableSlot(h);
|
||||
else
|
||||
slot = a->firstBackpackSlot(h);
|
||||
al.slot = ArtifactUtils::getArtifactDstPosition(a->artType->getId(), h);
|
||||
}
|
||||
else
|
||||
{
|
||||
slot = pos;
|
||||
if(a->artType->canBePutAt(h, pos, false))
|
||||
al.slot = pos;
|
||||
}
|
||||
|
||||
al.slot = slot;
|
||||
|
||||
if (slot < 0 || !a->canBePutAt(al))
|
||||
if(ArtifactUtils::isSlotEquipment(al.slot) || ArtifactUtils::isSlotBackpack(al.slot))
|
||||
{
|
||||
complain("Cannot put artifact in that slot!");
|
||||
return;
|
||||
putArtifact(al, a);
|
||||
return true;
|
||||
}
|
||||
else
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
putArtifact(al, a);
|
||||
}
|
||||
|
||||
void CGameHandler::putArtifact(const ArtifactLocation &al, const CArtifactInstance *a)
|
||||
{
|
||||
PutArtifact pa;
|
||||
@ -6884,7 +6894,7 @@ void CGameHandler::giveHeroNewArtifact(const CGHeroInstance *h, const CArtifact
|
||||
na.art = a;
|
||||
sendAndApply(&na); // -> updates a!!!, will create a on other machines
|
||||
|
||||
giveHeroArtifact(h, a, pos);
|
||||
COMPLAIN_RET_IF(!giveHeroArtifact(h, a, pos), "Cannot put artifact in that slot!");
|
||||
}
|
||||
|
||||
void CGameHandler::setBattleResult(BattleResult::EResult resultType, int victoriusSide)
|
||||
|
@ -177,7 +177,7 @@ public:
|
||||
|
||||
bool giveHeroNewArtifact(const CGHeroInstance * h, const CArtifact * art);
|
||||
void giveHeroNewArtifact(const CGHeroInstance *h, const CArtifact *artType, ArtifactPosition pos) override;
|
||||
void giveHeroArtifact(const CGHeroInstance *h, const CArtifactInstance *a, ArtifactPosition pos) override;
|
||||
bool giveHeroArtifact(const CGHeroInstance * h, const CArtifactInstance * a, ArtifactPosition pos) override;
|
||||
void putArtifact(const ArtifactLocation &al, const CArtifactInstance *a) override;
|
||||
void removeArtifact(const ArtifactLocation &al) override;
|
||||
bool moveArtifact(const ArtifactLocation & al1, const ArtifactLocation & al2) override;
|
||||
|
@ -65,7 +65,7 @@ public:
|
||||
void removeAfterVisit(const CGObjectInstance *object) override {} //object will be destroyed when interaction is over. Do not call when interaction is not ongoing!
|
||||
|
||||
void giveHeroNewArtifact(const CGHeroInstance *h, const CArtifact *artType, ArtifactPosition pos) override {}
|
||||
void giveHeroArtifact(const CGHeroInstance *h, const CArtifactInstance *a, ArtifactPosition pos) override {} //pos==-1 - first free slot in backpack=0; pos==-2 - default if available or backpack
|
||||
bool giveHeroArtifact(const CGHeroInstance *h, const CArtifactInstance *a, ArtifactPosition pos) override {} //pos==-1 - first free slot in backpack=0; pos==-2 - default if available or backpack
|
||||
void putArtifact(const ArtifactLocation &al, const CArtifactInstance *a) override {}
|
||||
void removeArtifact(const ArtifactLocation &al) override {}
|
||||
bool moveArtifact(const ArtifactLocation &al1, const ArtifactLocation &al2) override {return false;}
|
||||
|
Loading…
Reference in New Issue
Block a user