1
0
mirror of https://github.com/vcmi/vcmi.git synced 2025-12-13 23:57:41 +02:00

Little more work on artifacts.

This commit is contained in:
Michał W. Urbańczyk
2010-12-29 21:04:22 +00:00
parent 8104a43809
commit c9189119b9
17 changed files with 425 additions and 314 deletions

View File

@@ -1610,43 +1610,46 @@ void CGameHandler::stopHeroVisitCastle(int obj, int heroID)
sendAndApply(&vc);
}
bool CGameHandler::removeArtifact(const CArtifact* art, int hid)
{
const CGHeroInstance* h = getHero(hid);
SetHeroArtifacts sha;
sha.hid = hid;
sha.artifacts = h->artifacts;
sha.artifWorn = h->artifWorn;
std::vector<const CArtifact*>::iterator it;
if ((it = std::find(sha.artifacts.begin(), sha.artifacts.end(), art)) != sha.artifacts.end()) //it is in backpack
sha.artifacts.erase(it);
else //worn
{
std::map<ui16, const CArtifact*>::iterator itr;
for (itr = sha.artifWorn.begin(); itr != sha.artifWorn.end(); ++itr)
{
if (itr->second == art)
{
VLC->arth->unequipArtifact(sha.artifWorn, itr->first);
break;
}
}
if(itr == sha.artifWorn.end())
{
tlog2 << "Cannot find artifact to remove!\n";
return false;
}
}
sendAndApply(&sha);
return true;
}
// bool CGameHandler::removeArtifact(const CArtifact* art, int hid)
// {
// const CGHeroInstance* h = getHero(hid);
//
// SetHeroArtifacts sha;
// sha.hid = hid;
// sha.artifacts = h->artifacts;
// sha.artifWorn = h->artifWorn;
//
// std::vector<const CArtifact*>::iterator it;
// if ((it = std::find(sha.artifacts.begin(), sha.artifacts.end(), art)) != sha.artifacts.end()) //it is in backpack
// sha.artifacts.erase(it);
// else //worn
// {
// std::map<ui16, const CArtifact*>::iterator itr;
// for (itr = sha.artifWorn.begin(); itr != sha.artifWorn.end(); ++itr)
// {
// if (itr->second == art)
// {
// VLC->arth->unequipArtifact(sha.artifWorn, itr->first);
// break;
// }
// }
//
// if(itr == sha.artifWorn.end())
// {
// tlog2 << "Cannot find artifact to remove!\n";
// return false;
// }
// }
// sendAndApply(&sha);
// return true;
// }
void CGameHandler::removeArtifact(const ArtifactLocation &al)
{
assert(al.getArt());
EraseArtifact ea;
ea.al = al;
sendAndApply(&ea);
}
void CGameHandler::startBattleI(const CArmedInstance *army1, const CArmedInstance *army2, int3 tile, const CGHeroInstance *hero1, const CGHeroInstance *hero2, bool creatureBank, boost::function<void(BattleResult*)> cb, const CGTownInstance *town) //use hero=NULL for no hero
{
@@ -1656,10 +1659,10 @@ void CGameHandler::startBattleI(const CArmedInstance *army1, const CArmedInstanc
if(army2->tempOwner < PLAYER_LIMIT)
states.setFlag(army2->tempOwner,&PlayerStatus::engagedIntoBattle,true);
const CArmedInstance *armies[2];
static const CArmedInstance *armies[2];
armies[0] = army1;
armies[1] = army2;
const CGHeroInstance*heroes[2];
static const CGHeroInstance*heroes[2];
heroes[0] = hero1;
heroes[1] = hero2;
@@ -2098,7 +2101,8 @@ bool CGameHandler::buildStructure( si32 tid, si32 bid, bool force /*=false*/ )
return false;
}
removeArtifact(VLC->arth->artifacts[2], t->visitingHero->id);
//remove grail
removeArtifact(ArtifactLocation(t->visitingHero, t->visitingHero->getArtPos(2, false)));
}
NewStructures ns;
@@ -2450,103 +2454,97 @@ bool CGameHandler::garrisonSwap( si32 tid )
}
// With the amount of changes done to the function, it's more like transferArtifacts.
bool CGameHandler::swapArtifacts(si32 srcHeroID, si32 destHeroID, ui16 srcSlot, ui16 destSlot)
// Function moves artifact from src to dst. If dst is not a backpack and is already occupied, old dst art goes to backpack and is replaced.
bool CGameHandler::moveArtifact(si32 srcHeroID, si32 destHeroID, ui16 srcSlot, ui16 destSlot)
{
CGHeroInstance *srcHero = gs->getHero(srcHeroID);
CGHeroInstance *destHero = gs->getHero(destHeroID);
ArtifactLocation src(srcHero, srcSlot), dst(destHero, destSlot);
// Make sure exchange is even possible between the two heroes.
if (distance(srcHero->pos,destHero->pos) > 1.5 )
return false;
if(!isAllowedExchange(srcHeroID, destHeroID))
COMPLAIN_RET("That heroes cannot make any exchange!");
const CArtifact *srcArtifact = srcHero->getArt(srcSlot);
const CArtifact *destArtifact = destHero->getArt(destSlot);
const CArtifactInstance *srcArtifact = src.getArt();
const CArtifactInstance *destArtifact = dst.getArt();
if (srcArtifact == NULL)
{
complain("No artifact to swap!");
return false;
}
COMPLAIN_RET("No artifact to move!");
if (destArtifact && srcHero->tempOwner != destHero->tempOwner)
{
complain("Can't take artifact from hero of another player!");
return false;
}
COMPLAIN_RET("Can't touch artifact on hero of another player!");
SetHeroArtifacts sha;
sha.hid = srcHeroID;
sha.artifacts = srcHero->artifacts;
sha.artifWorn = srcHero->artifWorn;
// Combinational artifacts needs to be removed first so they don't get denied movement because of their own locks.
if (srcHeroID == destHeroID && srcSlot < 19 && destSlot < 19)
{
sha.setArtAtPos(srcSlot, NULL);
if (!vstd::contains(sha.artifWorn, destSlot))
destArtifact = NULL;
}
// // Combinational artifacts needs to be removed first so they don't get denied movement because of their own locks.
// if (srcHeroID == destHeroID && srcSlot < 19 && destSlot < 19)
// {
// sha.setArtAtPos(srcSlot, NULL);
// if (!vstd::contains(sha.artifWorn, destSlot))
// destArtifact = NULL;
// }
// Check if src/dest slots are appropriate for the artifacts exchanged.
// Moving to the backpack is always allowed.
if ((!srcArtifact || destSlot < 19)
&& (srcArtifact && !srcArtifact->fitsAt(srcHeroID == destHeroID ? sha.artifWorn : destHero->artifWorn, destSlot)))
if ((!srcArtifact || destSlot < Arts::BACKPACK_START)
&& srcArtifact && !srcArtifact->canBePutAt(dst))
COMPLAIN_RET("Cannot swap artifacts!");
if ((srcArtifact && srcArtifact->artType->id == Arts::LOCK_ID) || (destArtifact && destArtifact->artType->id == Arts::LOCK_ID))
COMPLAIN_RET("Cannot move artifact locks.");
if (destSlot >= Arts::BACKPACK_START && srcArtifact->artType->isBig())
COMPLAIN_RET("Cannot put big artifacts in backpack!");
if (srcSlot == Arts::MACH4 || destSlot == Arts::MACH4)
COMPLAIN_RET("Cannot move catapult!");
//moving art to backpack is always allowed (we've ruled out exceptions)
if(destSlot >= Arts::BACKPACK_START)
{
complain("Cannot swap artifacts!");
return false;
moveArtifact(src, dst);
}
else //moving art to another slot
{
if(destArtifact) //old artifact must be removed first
{
moveArtifact(dst, ArtifactLocation(destHero, destHero->artifactsInBackpack.size()-1));
}
moveArtifact(src, dst);
}
if ((srcArtifact && srcArtifact->id == 145) || (destArtifact && destArtifact->id == 145))
{
complain("Cannot move artifact locks.");
return false;
}
if (destSlot >= 19 && srcArtifact->isBig())
{
complain("Cannot put big artifacts in backpack!");
return false;
}
if (srcSlot == 16 || destSlot == 16)
{
complain("Cannot move catapult!");
return false;
}
// If dest does not fit in src, put it in dest's backpack instead.
if (srcHeroID == destHeroID) // To avoid stumbling on own locks, remove artifact first.
sha.setArtAtPos(destSlot, NULL);
const bool destFits = !destArtifact || srcSlot >= 19 || destSlot >= 19 || destArtifact->fitsAt(sha.artifWorn, srcSlot);
if (srcHeroID == destHeroID && destArtifact)
sha.setArtAtPos(destSlot, destArtifact);
sha.setArtAtPos(srcSlot, NULL);
if (destSlot < 19 && (destArtifact || srcSlot < 19) && destFits)
sha.setArtAtPos(srcSlot, destArtifact ? destArtifact : NULL);
// Internal hero artifact arrangement.
if(srcHero == destHero)
{
// Correction for destination from removing source artifact in backpack.
if (srcSlot >= 19 && destSlot >= 19 && srcSlot < destSlot)
destSlot--;
sha.setArtAtPos(destSlot, srcHero->getArtAtPos(srcSlot));
}
if (srcHeroID != destHeroID)
{
// Exchange between two different heroes.
SetHeroArtifacts sha2;
sha2.hid = destHeroID;
sha2.artifacts = destHero->artifacts;
sha2.artifWorn = destHero->artifWorn;
sha2.setArtAtPos(destSlot, srcArtifact ? srcArtifact : NULL);
if (!destFits)
sha2.setArtAtPos(sha2.artifacts.size() + 19, destHero->getArtAtPos(destSlot));
sendAndApply(&sha2);
}
sendAndApply(&sha);
//
// // If dest does not fit in src, put it in dest's backpack instead.
// if (srcHeroID == destHeroID) // To avoid stumbling on own locks, remove artifact first.
// sha.setArtAtPos(destSlot, NULL);
// const bool destFits = !destArtifact || srcSlot >= 19 || destSlot >= 19 || destArtifact->fitsAt(sha.artifWorn, srcSlot);
// if (srcHeroID == destHeroID && destArtifact)
// sha.setArtAtPos(destSlot, destArtifact);
//
// sha.setArtAtPos(srcSlot, NULL);
// if (destSlot < 19 && (destArtifact || srcSlot < 19) && destFits)
// sha.setArtAtPos(srcSlot, destArtifact ? destArtifact : NULL);
//
// // Internal hero artifact arrangement.
// if(srcHero == destHero)
// {
// // Correction for destination from removing source artifact in backpack.
// if (srcSlot >= 19 && destSlot >= 19 && srcSlot < destSlot)
// destSlot--;
//
// sha.setArtAtPos(destSlot, srcHero->getArtAtPos(srcSlot));
// }
// if (srcHeroID != destHeroID)
// {
// // Exchange between two different heroes.
// SetHeroArtifacts sha2;
// sha2.hid = destHeroID;
// sha2.artifacts = destHero->artifacts;
// sha2.artifWorn = destHero->artifWorn;
// sha2.setArtAtPos(destSlot, srcArtifact ? srcArtifact : NULL);
// if (!destFits)
// sha2.setArtAtPos(sha2.artifacts.size() + 19, destHero->getArtAtPos(destSlot));
// sendAndApply(&sha2);
// }
// sendAndApply(&sha);
return true;
}
@@ -2566,8 +2564,8 @@ bool CGameHandler::assembleArtifacts (si32 heroID, ui16 artifactSlot, bool assem
}
CGHeroInstance *hero = gs->getHero(heroID);
const CArtifact *destArtifact = hero->getArt(artifactSlot);
const CArtifactInstance *destArtifact = hero->getArt(artifactSlot);
/*
SetHeroArtifacts sha;
sha.hid = heroID;
sha.artifacts = hero->artifacts;
@@ -2678,7 +2676,8 @@ bool CGameHandler::assembleArtifacts (si32 heroID, ui16 artifactSlot, bool assem
sendAndApply(&sha);
return true;
return true;*/
return false;
}
bool CGameHandler::buyArtifact( ui32 hid, si32 aid )
@@ -2711,7 +2710,7 @@ bool CGameHandler::buyArtifact( ui32 hid, si32 aid )
return false;
}
giveResource(hero->getOwner(),6,-price);
giveResource(hero->getOwner(),Res::GOLD,-price);
giveHeroNewArtifact(hero, VLC->arth->artifacts[aid], 9+aid);
return true;
}
@@ -4562,13 +4561,19 @@ bool CGameHandler::sacrificeCreatures(const IMarket *market, const CGHeroInstanc
return true;
}
bool CGameHandler::sacrificeArtifact(const IMarket * m, const CGHeroInstance * hero, const CArtifact* art)
bool CGameHandler::sacrificeArtifact(const IMarket * m, const CGHeroInstance * hero, int slot)
{
if(!removeArtifact(art, hero->id))
ArtifactLocation al(hero, slot);
const CArtifactInstance *a = al.getArt();
if(!a)
COMPLAIN_RET("Cannot find artifact to sacrifice!");
int dmp, expToGive;
m->getOffer(art->id, 0, dmp, expToGive, ARTIFACT_EXP);
m->getOffer(hero->getArtTypeId(slot), 0, dmp, expToGive, ARTIFACT_EXP);
removeArtifact(al);
changePrimSkill(hero->id, 4, expToGive);
return true;
}
@@ -4977,7 +4982,10 @@ void CGameHandler::putArtifact(const ArtifactLocation &al, const CArtifactInstan
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)
@@ -4987,7 +4995,7 @@ void CGameHandler::giveHeroNewArtifact(const CGHeroInstance *h, const CArtifact
NewArtifact na;
na.art = a;
sendAndApply(&na);
sendAndApply(&na); // -> updates a!!!
giveHeroArtifact(h, a, pos);
}