mirror of
https://github.com/vcmi/vcmi.git
synced 2025-03-19 21:10:12 +02:00
* Fixed bug #112
* Improved the security checks for ExchangeArtifact and SetArtifact, but have also come to realize that SetArtifact is inherently broken and can be used for cheating. :( * Preliminary work for combination artifacts, it's now possible to identify artifacts that are combined and what they're made up of. * Happy New Year!
This commit is contained in:
parent
b79fe389a2
commit
ef5b1ca1de
@ -3696,10 +3696,11 @@ bool CArtPlace::fitsHere(const CArtifact * art)
|
||||
if(!art)
|
||||
return true;
|
||||
|
||||
// Anything can be placed in the backpack, except War Machines.
|
||||
if (slotID >= 19 && !CGI->arth->isBigArtifact(art->id)
|
||||
|| vstd::contains(art->possibleSlots, slotID))
|
||||
{
|
||||
// Anything can but War Machines can be placed in backpack.
|
||||
if (slotID >= 19) {
|
||||
return !CGI->arth->isBigArtifact(art->id);
|
||||
} else if (vstd::contains(art->possibleSlots, slotID)) {
|
||||
// TODO: Deal with combinational at dest and as src.
|
||||
return true;
|
||||
}
|
||||
|
||||
|
@ -674,11 +674,11 @@ public:
|
||||
{
|
||||
std::set<CArtifactsOfHero *> participants; // Needed to mark slots.
|
||||
const CArtifact * srcArtifact; // Held artifact.
|
||||
const CArtifactsOfHero * srcAOH; // Following two needed to uniquely identify the source.
|
||||
int srcSlotID; //
|
||||
const CArtifactsOfHero * srcAOH; // Following two needed to uniquely identify the source.
|
||||
int srcSlotID; //
|
||||
const CArtifactsOfHero * destAOH; // For swapping. (i.e. changing what is held)
|
||||
int destSlotID; // Needed to determine what kind of action was last taken in setHero
|
||||
const CArtifact * destArtifact; // For swapping.
|
||||
int destSlotID; // Needed to determine what kind of action was last taken in setHero
|
||||
const CArtifact * destArtifact; // For swapping.
|
||||
} * commonInfo; //when we have more than one CArtifactsOfHero in one window with exchange possibility, we use this (eg. in exchange window); to be provided externally
|
||||
|
||||
AdventureMapButton * leftArtRoll, * rightArtRoll;
|
||||
@ -812,4 +812,4 @@ class CFreelancersWindow : public CShopWindow
|
||||
{};
|
||||
class CHillFortWindow : public CIntObject //garrison dialog? shop?
|
||||
{};
|
||||
#endif //__GUICLASSES_H__
|
||||
#endif //__GUICLASSES_H__
|
@ -35,6 +35,12 @@ const std::string & CArtifact::Description() const
|
||||
else
|
||||
return VLC->generaltexth->artifDescriptions[id];
|
||||
}
|
||||
|
||||
bool CArtifact::isBig () const
|
||||
{
|
||||
return VLC->arth->isBigArtifact(id);
|
||||
}
|
||||
|
||||
CArtHandler::CArtHandler()
|
||||
{
|
||||
VLC->arth = this;
|
||||
@ -79,6 +85,75 @@ void CArtHandler::loadArtifacts(bool onlyTxt)
|
||||
if(desc[0] == '\"' && desc[desc.size()-1] == '\"')
|
||||
desc = desc.substr(1,desc.size()-2);
|
||||
|
||||
// Fill in information about combined artifacts.
|
||||
switch (nart.id) {
|
||||
case 129: // Angelic Alliance
|
||||
nart.constituents = new std::vector<ui32>(6);
|
||||
*nart.constituents += 31, 32, 33, 34, 35, 36;
|
||||
break;
|
||||
|
||||
case 130: // Cloak of the Undead King
|
||||
nart.constituents = new std::vector<ui32>(3);
|
||||
*nart.constituents += 54, 55, 56;
|
||||
break;
|
||||
|
||||
case 131: // Elixir of Life
|
||||
nart.constituents = new std::vector<ui32>(3);
|
||||
*nart.constituents += 94, 95, 96;
|
||||
break;
|
||||
|
||||
case 132: // Armor of the Damned
|
||||
nart.constituents = new std::vector<ui32>(4);
|
||||
*nart.constituents += 8, 14, 20, 26;
|
||||
break;
|
||||
|
||||
case 133: // Statue of Legion
|
||||
nart.constituents = new std::vector<ui32>(5);
|
||||
*nart.constituents += 118, 119, 120, 121, 122;
|
||||
break;
|
||||
|
||||
case 134: // Power of the Dragon Father
|
||||
nart.constituents = new std::vector<ui32>(9);
|
||||
*nart.constituents += 37, 38, 39, 40, 41, 42, 43, 44, 45;
|
||||
break;
|
||||
|
||||
case 135: // Titan's Thunder
|
||||
nart.constituents = new std::vector<ui32>(4);
|
||||
*nart.constituents += 12, 18, 24, 30;
|
||||
break;
|
||||
|
||||
case 136: // Admiral's Hat
|
||||
nart.constituents = new std::vector<ui32>(2);
|
||||
*nart.constituents += 71, 123;
|
||||
break;
|
||||
|
||||
case 137: // Bow of the Sharpshooter
|
||||
nart.constituents = new std::vector<ui32>(3);
|
||||
*nart.constituents += 60, 61, 62;
|
||||
break;
|
||||
|
||||
case 138: // Wizards' Well
|
||||
nart.constituents = new std::vector<ui32>(3);
|
||||
*nart.constituents += 73, 74, 75;
|
||||
break;
|
||||
|
||||
case 139: // Ring of the Magi
|
||||
nart.constituents = new std::vector<ui32>(3);
|
||||
*nart.constituents += 76, 77, 78;
|
||||
break;
|
||||
|
||||
case 140: // Cornucopia
|
||||
nart.constituents = new std::vector<ui32>(4);
|
||||
*nart.constituents += 109, 110, 111, 113;
|
||||
break;
|
||||
|
||||
// TODO: WoG combinationals
|
||||
|
||||
default:
|
||||
nart.constituents = NULL;
|
||||
break;
|
||||
}
|
||||
|
||||
if(!onlyTxt)
|
||||
artifacts.push_back(nart);
|
||||
}
|
||||
|
@ -25,16 +25,18 @@ public:
|
||||
enum EartClass {ART_SPECIAL=1, ART_TREASURE=2, ART_MINOR=4, ART_MAJOR=8, ART_RELIC=16}; //artifact classes
|
||||
const std::string &Name() const; //getter
|
||||
const std::string &Description() const; //getter
|
||||
bool isBig () const;
|
||||
|
||||
ui32 price;
|
||||
std::vector<ui16> possibleSlots; //ids of slots where artifact can be placed
|
||||
std::vector<ui32> * constituents; // Artifacts IDs a combined artifact consists of, or NULL.
|
||||
EartClass aClass;
|
||||
ui32 id;
|
||||
std::list<HeroBonus> bonuses; //bonuses given by artifact
|
||||
|
||||
template <typename Handler> void serialize(Handler &h, const int version)
|
||||
{
|
||||
h & name & description & price & possibleSlots & aClass & id & bonuses;
|
||||
h & name & description & price & possibleSlots & constituents & aClass & id & bonuses;
|
||||
}
|
||||
};
|
||||
|
||||
|
@ -1197,6 +1197,26 @@ si32 CGHeroInstance::getArtPos(int aid) const
|
||||
return -1;
|
||||
}
|
||||
|
||||
/**
|
||||
* Places an artifact in hero's backpack. If it's a big artifact equips it
|
||||
* or discards it if it cannot be equipped.
|
||||
*/
|
||||
void CGHeroInstance::giveArtifact (ui32 aid)
|
||||
{
|
||||
const CArtifact &artifact = VLC->arth->artifacts[aid];
|
||||
|
||||
if (artifact.isBig()) {
|
||||
for (std::vector<ui16>::const_iterator it = artifact.possibleSlots.begin(); it != artifact.possibleSlots.end(); ++it) {
|
||||
if (artifWorn.find(*it) == artifWorn.end()) {
|
||||
artifWorn[*it] = aid;
|
||||
break;
|
||||
}
|
||||
}
|
||||
} else {
|
||||
artifacts.push_back(aid);
|
||||
}
|
||||
}
|
||||
|
||||
void CGHeroInstance::recreateArtBonuses()
|
||||
{
|
||||
//clear all bonuses from artifacts (if present) and give them again
|
||||
|
@ -296,6 +296,7 @@ public:
|
||||
ui32 getArtAtPos(ui16 pos) const; //-1 - no artifact
|
||||
const CArtifact * getArt(int pos) const;
|
||||
si32 getArtPos(int aid) const; //looks for equipped artifact with given ID and returns its slot ID or -1 if none(if more than one such artifact lower ID is returned)
|
||||
void giveArtifact (ui32 aid);
|
||||
int getSpellSecLevel(int spell) const; //returns level of secondary ability (fire, water, earth, air magic) known to this hero and applicable to given spell; -1 if error
|
||||
static int3 convertPosition(int3 src, bool toh3m); //toh3m=true: manifest->h3m; toh3m=false: h3m->manifest
|
||||
double getHeroStrength() const;
|
||||
|
@ -1448,7 +1448,7 @@ void CGameState::init(StartInfo * si, Mapa * map, int Seed)
|
||||
hero->recreateArtBonuses();
|
||||
}
|
||||
else
|
||||
hero->artifacts.push_back(toGive->id);
|
||||
hero->giveArtifact(toGive->id);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -1005,7 +1005,7 @@ void Mapa::loadHero( CGObjectInstance * &nobj, const unsigned char * bufor, int
|
||||
{
|
||||
id = readNormalNr(bufor,i, artidlen); i+=artidlen;
|
||||
if(id!=artmask)
|
||||
nhi->artifacts.push_back(id);
|
||||
nhi->giveArtifact(id);
|
||||
}
|
||||
}
|
||||
} //artifacts
|
||||
@ -1244,7 +1244,7 @@ void Mapa::readPredefinedHeroes( const unsigned char * bufor, int &i)
|
||||
{
|
||||
id = readNormalNr(bufor,i, artidlen); i+=artidlen;
|
||||
if(id!=artmask)
|
||||
cgh->artifacts.push_back(id);
|
||||
cgh->giveArtifact(id);
|
||||
}
|
||||
}
|
||||
} //artifacts
|
||||
|
@ -1673,10 +1673,10 @@ void CGameHandler::giveHeroArtifact(int artid, int hid, int position) //pos==-1
|
||||
break;
|
||||
}
|
||||
}
|
||||
if(i == art.possibleSlots.size()) //if haven't find proper slot, use backpack
|
||||
if(i == art.possibleSlots.size() && !art.isBig()) //if haven't find proper slot, use backpack or discard big artifact
|
||||
sha.artifacts.push_back(artid);
|
||||
}
|
||||
else //should be -1 => put artifact into backpack
|
||||
else if (!art.isBig()) //should be -1 => put artifact into backpack
|
||||
{
|
||||
sha.artifacts.push_back(artid);
|
||||
}
|
||||
@ -1687,7 +1687,7 @@ void CGameHandler::giveHeroArtifact(int artid, int hid, int position) //pos==-1
|
||||
{
|
||||
sha.artifWorn[position] = artid;
|
||||
}
|
||||
else
|
||||
else if (!art.isBig())
|
||||
{
|
||||
sha.artifacts.push_back(artid);
|
||||
}
|
||||
@ -2330,10 +2330,13 @@ bool CGameHandler::swapArtifacts(si32 srcHeroID, si32 destHeroID, ui16 srcSlot,
|
||||
return false;
|
||||
}
|
||||
|
||||
// TODO: This relates to bug #112, fix later.
|
||||
// Make sure the artifacts are not war machines.
|
||||
if ((srcSlot>=13 && srcSlot<=16) || (destSlot>=13 && destSlot<=16)) {
|
||||
complain("Cannot move war machine!");
|
||||
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;
|
||||
}
|
||||
|
||||
@ -2375,9 +2378,26 @@ bool CGameHandler::swapArtifacts(si32 srcHeroID, si32 destHeroID, ui16 srcSlot,
|
||||
*/
|
||||
bool CGameHandler::setArtifact(si32 heroID, ui16 slot, int artID)
|
||||
{
|
||||
CGHeroInstance *hero = gs->getHero(heroID);
|
||||
const CGHeroInstance *hero = gs->getHero(heroID);
|
||||
|
||||
// TODO: Deal with war machine placement.
|
||||
if (artID != -1) {
|
||||
const CArtifact &artifact = VLC->arth->artifacts[artID];
|
||||
|
||||
if (slot < 19 && !vstd::contains(artifact.possibleSlots, slot)) {
|
||||
complain("Artifact does not fit!");
|
||||
return false;
|
||||
}
|
||||
|
||||
if (slot >= 19 && artifact.isBig()) {
|
||||
complain("Cannot put big artifacts in backpack!");
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
if (slot == 16) {
|
||||
complain("Cannot alter catapult slot!");
|
||||
return false;
|
||||
}
|
||||
|
||||
// Perform the exchange.
|
||||
SetHeroArtifacts sha;
|
||||
|
Loading…
x
Reference in New Issue
Block a user