mirror of
https://github.com/vcmi/vcmi.git
synced 2025-08-13 19:54:17 +02:00
@@ -9,6 +9,7 @@
|
||||
#include <boost/assign/list_of.hpp>
|
||||
#include <boost/lexical_cast.hpp>
|
||||
#include <boost/foreach.hpp>
|
||||
#include <boost/random/linear_congruential.hpp>
|
||||
#include "../lib/VCMI_Lib.h"
|
||||
extern CLodHandler *bitmaph;
|
||||
using namespace boost::assign;
|
||||
@@ -23,6 +24,8 @@ using namespace boost::assign;
|
||||
*
|
||||
*/
|
||||
|
||||
extern boost::rand48 ran;
|
||||
|
||||
const std::string & CArtifact::Name() const
|
||||
{
|
||||
if(name.size())
|
||||
@@ -349,26 +352,96 @@ int CArtHandler::convertMachineID(int id, bool creToArt )
|
||||
|
||||
void CArtHandler::sortArts()
|
||||
{
|
||||
for(int i=0;i<144;i++) //do 144, bo nie chcemy bzdurek
|
||||
for (int i=0; i<allowedArtifacts.size(); ++i) //do 144, bo nie chcemy bzdurek
|
||||
{
|
||||
switch (artifacts[i]->aClass)
|
||||
switch (allowedArtifacts[i]->aClass)
|
||||
{
|
||||
case CArtifact::ART_TREASURE:
|
||||
treasures.push_back(artifacts[i]);
|
||||
treasures.push_back(allowedArtifacts[i]);
|
||||
break;
|
||||
case CArtifact::ART_MINOR:
|
||||
minors.push_back(artifacts[i]);
|
||||
minors.push_back(allowedArtifacts[i]);
|
||||
break;
|
||||
case CArtifact::ART_MAJOR:
|
||||
majors.push_back(artifacts[i]);
|
||||
majors.push_back(allowedArtifacts[i]);
|
||||
break;
|
||||
case CArtifact::ART_RELIC:
|
||||
relics.push_back(artifacts[i]);
|
||||
relics.push_back(allowedArtifacts[i]);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
void CArtHandler::erasePickedArt (si32 id)
|
||||
{
|
||||
std::vector<CArtifact*>* ptr;
|
||||
CArtifact *art = artifacts[id];
|
||||
switch (art->aClass)
|
||||
{
|
||||
case CArtifact::ART_TREASURE:
|
||||
ptr = &treasures;
|
||||
break;
|
||||
case CArtifact::ART_MINOR:
|
||||
ptr = &minors;
|
||||
break;
|
||||
case CArtifact::ART_MAJOR:
|
||||
ptr = &majors;
|
||||
break;
|
||||
case CArtifact::ART_RELIC:
|
||||
ptr = &relics;
|
||||
break;
|
||||
default: //special artifacts should not be erased
|
||||
return;
|
||||
}
|
||||
ptr->erase (std::find(ptr->begin(), ptr->end(), art)); //remove the artifact from avaliable list
|
||||
}
|
||||
ui16 CArtHandler::getRandomArt(int flags)
|
||||
{
|
||||
std::vector<CArtifact*> out;
|
||||
getAllowed(out, flags);
|
||||
ui16 id = out[ran() % out.size()]->id;
|
||||
erasePickedArt (id);
|
||||
return id;
|
||||
}
|
||||
ui16 CArtHandler::getArtSync (ui32 rand, int flags)
|
||||
{
|
||||
std::vector<CArtifact*> out;
|
||||
getAllowed(out, flags);
|
||||
CArtifact *art = out[rand % out.size()];
|
||||
return art->id;
|
||||
}
|
||||
void CArtHandler::getAllowed(std::vector<CArtifact*> &out, int flags)
|
||||
{
|
||||
if (flags & CArtifact::ART_TREASURE)
|
||||
getAllowedArts (out, &treasures, CArtifact::ART_TREASURE);
|
||||
if (flags & CArtifact::ART_MINOR)
|
||||
getAllowedArts (out, &minors, CArtifact::ART_MINOR);
|
||||
if (flags & CArtifact::ART_MAJOR)
|
||||
getAllowedArts (out, &majors, CArtifact::ART_MAJOR);
|
||||
if (flags & CArtifact::ART_RELIC)
|
||||
getAllowedArts (out, &relics, CArtifact::ART_RELIC);
|
||||
if (!out.size()) //no arts are avaliable
|
||||
{
|
||||
out.resize (64);
|
||||
std::fill_n (out.begin(), 64, artifacts[2]); //magic
|
||||
}
|
||||
}
|
||||
void CArtHandler::getAllowedArts(std::vector<CArtifact*> &out, std::vector<CArtifact*> *arts, int flag)
|
||||
{
|
||||
if (arts->empty()) //restock avaliable arts
|
||||
{
|
||||
for (int i = 0; i < allowedArtifacts.size(); ++i)
|
||||
{
|
||||
if (allowedArtifacts[i]->aClass == flag)
|
||||
arts->push_back(allowedArtifacts[i]);
|
||||
}
|
||||
}
|
||||
|
||||
for (int i = 0; i < arts->size(); ++i)
|
||||
{
|
||||
CArtifact *art = (*arts)[i];
|
||||
out.push_back(art);
|
||||
}
|
||||
}
|
||||
void CArtHandler::giveArtBonus( int aid, Bonus::BonusType type, int val, int subtype, int valType )
|
||||
{
|
||||
Bonus added(Bonus::PERMANENT,type,Bonus::ARTIFACT,val,aid,subtype);
|
||||
|
@@ -51,12 +51,18 @@ class DLL_EXPORT CArtHandler //handles artifacts
|
||||
public:
|
||||
std::vector<CArtifact*> treasures, minors, majors, relics;
|
||||
std::vector<CArtifact *> artifacts;
|
||||
std::vector<CArtifact *> allowedArtifacts;
|
||||
std::set<ui32> bigArtifacts; // Artifacts that cannot be moved to backpack, e.g. war machines.
|
||||
|
||||
void loadArtifacts(bool onlyTxt);
|
||||
void sortArts();
|
||||
void addBonuses();
|
||||
void clear();
|
||||
ui16 getRandomArt (int flags);
|
||||
ui16 getArtSync (ui32 rand, int flags);
|
||||
void getAllowedArts(std::vector<CArtifact*> &out, std::vector<CArtifact*> *arts, int flag);
|
||||
void getAllowed(std::vector<CArtifact*> &out, int flags);
|
||||
void erasePickedArt (si32 id);
|
||||
bool isBigArtifact (ui32 artID) {return bigArtifacts.find(artID) != bigArtifacts.end();}
|
||||
void equipArtifact (std::map<ui16, ui32> &artifWorn, ui16 slotID, ui32 artifactID, BonusList *bonuses = NULL);
|
||||
void unequipArtifact (std::map<ui16, ui32> &artifWorn, ui16 slotID, BonusList *bonuses = NULL);
|
||||
@@ -66,9 +72,8 @@ public:
|
||||
|
||||
template <typename Handler> void serialize(Handler &h, const int version)
|
||||
{
|
||||
h & artifacts;
|
||||
if(!h.saving)
|
||||
sortArts();
|
||||
h & artifacts & allowedArtifacts & treasures & minors & majors & relics;
|
||||
//if(!h.saving) sortArts();
|
||||
}
|
||||
};
|
||||
|
||||
|
@@ -1767,39 +1767,6 @@ void CGTownInstance::newTurn() const
|
||||
cb->setObjProperty (id, 12, (*i)->id); //reset visitors for Mana Vortex
|
||||
}
|
||||
}
|
||||
|
||||
if(cb->getDate(2) == 1) //reset on new month
|
||||
{
|
||||
std::vector<CArtifact*>::iterator index;
|
||||
for (ui8 i = 0; i < 3; ++i) //each tier
|
||||
{
|
||||
int count = 0;
|
||||
std::vector<CArtifact*> arts; //to avoid addition of different tiers
|
||||
switch (i)
|
||||
{
|
||||
case 0:
|
||||
cb->getAllowed (arts, CArtifact::ART_TREASURE);
|
||||
count = 3; // first row - three treasures,
|
||||
break;
|
||||
case 1:
|
||||
cb->getAllowed (arts, CArtifact::ART_MINOR);
|
||||
count = 3; // second row three minors
|
||||
break;
|
||||
case 2:
|
||||
cb->getAllowed (arts, CArtifact::ART_MAJOR);
|
||||
count = 1; // and a third row - one major
|
||||
break;
|
||||
}
|
||||
for (ui8 n = 0; n < count; n++)
|
||||
{
|
||||
|
||||
// index = arts.begin() + val % arts.size();
|
||||
// advMapArts [advMapArts.size()] = new Component (Component::ARTIFACT, (*index)->id, 0, 0);
|
||||
// arts.erase(index);
|
||||
// val *= (id + n * i); //randomize
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
int3 CGTownInstance::getSightCenter() const
|
||||
@@ -5023,25 +4990,12 @@ void CBank::reset(ui16 var1) //prevents desync
|
||||
void CBank::initialize() const
|
||||
{
|
||||
cb->setObjProperty (id, 14, ran()); //synchronous reset
|
||||
ui32 artid;
|
||||
for (ui8 i = 0; i <= 3; i++)
|
||||
{
|
||||
for (ui8 n = 0; n < bc->artifacts[i]; n++) //new function using proper randomization algorithm
|
||||
{
|
||||
switch (i)
|
||||
{
|
||||
case 0:
|
||||
cb->setObjProperty(id, 18, cb->getRandomArt (CArtifact::ART_TREASURE));
|
||||
break;
|
||||
case 1:
|
||||
cb->setObjProperty(id, 18, cb->getRandomArt (CArtifact::ART_MINOR));
|
||||
break;
|
||||
case 2:
|
||||
cb->setObjProperty(id, 18, cb->getRandomArt (CArtifact::ART_MAJOR));
|
||||
break;
|
||||
case 3:
|
||||
cb->setObjProperty(id, 18, cb->getRandomArt (CArtifact::ART_RELIC));
|
||||
break;
|
||||
}
|
||||
cb->setObjProperty (id, 18 + i, ran()); //synchronic
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -5052,7 +5006,7 @@ void CBank::setPropertyDer (ui8 what, ui32 val)
|
||||
{
|
||||
case 11: //daycounter
|
||||
if (val == 0)
|
||||
daycounter = 0;
|
||||
daycounter = 1; //yes, 1
|
||||
else
|
||||
daycounter++;
|
||||
break;
|
||||
@@ -5118,8 +5072,33 @@ void CBank::setPropertyDer (ui8 what, ui32 val)
|
||||
}
|
||||
break;
|
||||
case 18: //add Artifact
|
||||
artifacts.push_back (val);
|
||||
{
|
||||
int id = cb->getArtSync(val, CArtifact::ART_TREASURE);
|
||||
artifacts.push_back (id);
|
||||
cb->erasePickedArt(id);
|
||||
break;
|
||||
}
|
||||
case 19: //add Artifact
|
||||
{
|
||||
int id = cb->getArtSync(val, CArtifact::ART_MINOR);
|
||||
artifacts.push_back (id);
|
||||
cb->erasePickedArt(id);
|
||||
break;
|
||||
}
|
||||
case 20: //add Artifact
|
||||
{
|
||||
int id = cb->getArtSync(val, CArtifact::ART_MAJOR);
|
||||
artifacts.push_back (id);
|
||||
cb->erasePickedArt(id);
|
||||
break;
|
||||
}
|
||||
case 21: //add Artifact
|
||||
{
|
||||
int id = cb->getArtSync(val, CArtifact::ART_RELIC);
|
||||
artifacts.push_back (id);
|
||||
cb->erasePickedArt(id);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
@@ -302,6 +302,16 @@ public:
|
||||
h & patrolling & patrolRadious;
|
||||
}
|
||||
} patrol;
|
||||
struct DLL_EXPORT HeroSpecial : CBonusSystemNode
|
||||
{
|
||||
bool growthsWithLevel;
|
||||
void RecalculateSpecials(){};
|
||||
template <typename Handler> void serialize(Handler &h, const int version)
|
||||
{
|
||||
h & static_cast<CBonusSystemNode&>(*this);
|
||||
h & growthsWithLevel;
|
||||
}
|
||||
} speciality;
|
||||
|
||||
//BonusList bonuses;
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
@@ -313,7 +323,7 @@ public:
|
||||
h & exp & level & name & biography & portrait & mana & secSkills & movement
|
||||
& sex & inTownGarrison & artifacts & artifWorn & spells & patrol & moveDir;
|
||||
|
||||
h & type;
|
||||
h & type & speciality;
|
||||
//visitied town pointer will be restored by map serialization method
|
||||
}
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
|
@@ -904,28 +904,16 @@ std::pair<int,int> CGameState::pickObject (CGObjectInstance *obj)
|
||||
{
|
||||
switch(obj->ID)
|
||||
{
|
||||
case 65: //random artifact
|
||||
return std::pair<int,int>(5,(ran()%136)+7); //the only reasonable range - there are siege weapons and blanks we must ommit
|
||||
case 66: //random treasure artifact
|
||||
return std::pair<int,int>(5,VLC->arth->treasures[ran()%VLC->arth->treasures.size()]->id);
|
||||
case 67: //random minor artifact
|
||||
return std::pair<int,int>(5,VLC->arth->minors[ran()%VLC->arth->minors.size()]->id);
|
||||
case 68: //random major artifact
|
||||
return std::pair<int,int>(5,VLC->arth->majors[ran()%VLC->arth->majors.size()]->id);
|
||||
case 69: //random relic artifact
|
||||
return std::pair<int,int>(5,VLC->arth->relics[ran()%VLC->arth->relics.size()]->id);
|
||||
/*
|
||||
case 65: //random artifact //how the hell use IGameCallback for this?
|
||||
return std::pair<int,int>(5, obj->cb->getRandomArt (CArtifact::ART_TREASURE | CArtifact::ART_MINOR | CArtifact::ART_MAJOR | CArtifact::ART_RELIC));
|
||||
return std::pair<int,int>(5, VLC->arth->getRandomArt (CArtifact::ART_TREASURE | CArtifact::ART_MINOR | CArtifact::ART_MAJOR | CArtifact::ART_RELIC));
|
||||
case 66: //random treasure artifact
|
||||
return std::pair<int,int>(5, cb->getRandomArt(CArtifact::ART_TREASURE));
|
||||
return std::pair<int,int>(5, VLC->arth->getRandomArt (CArtifact::ART_TREASURE));
|
||||
case 67: //random minor artifact
|
||||
return std::pair<int,int>(5, cb->getRandomArt (CArtifact::ART_MINOR));
|
||||
return std::pair<int,int>(5, VLC->arth->getRandomArt (CArtifact::ART_MINOR));
|
||||
case 68: //random major artifact
|
||||
return std::pair<int,int>(5, cb->getRandomArt (CArtifact::ART_MAJOR));
|
||||
return std::pair<int,int>(5, VLC->arth->getRandomArt (CArtifact::ART_MAJOR));
|
||||
case 69: //random relic artifact
|
||||
return std::pair<int,int>(5, cb->getRandomArt (CArtifact::ART_RELIC));
|
||||
*/
|
||||
return std::pair<int,int>(5, VLC->arth->getRandomArt (CArtifact::ART_RELIC));
|
||||
case 70: //random hero
|
||||
{
|
||||
return std::pair<int,int>(HEROI_TYPE,pickHero(obj->tempOwner));
|
||||
@@ -1185,6 +1173,11 @@ void CGameState::init( StartInfo * si, ui32 checksum, int Seed )
|
||||
{
|
||||
case 0:
|
||||
map = new Mapa(si->mapname);
|
||||
for (int i=0; i<144; ++i) //yes, 144
|
||||
{
|
||||
if (map->allowedArtifact[i])
|
||||
VLC->arth->allowedArtifacts.push_back(VLC->arth->artifacts[i]);
|
||||
}
|
||||
break;
|
||||
case 2:
|
||||
campaign = new CCampaignState();
|
||||
@@ -1192,6 +1185,11 @@ void CGameState::init( StartInfo * si, ui32 checksum, int Seed )
|
||||
std::string &mapContent = campaign->camp->mapPieces[si->whichMapInCampaign];
|
||||
map = new Mapa();
|
||||
map->initFromBytes((const unsigned char*)mapContent.c_str());
|
||||
for (int i=0; i<144; ++i)
|
||||
{
|
||||
if (map->allowedArtifact[i])
|
||||
VLC->arth->allowedArtifacts.push_back(VLC->arth->artifacts[i]);
|
||||
}
|
||||
break;
|
||||
}
|
||||
tlog0 << "Map loaded!" << std::endl;
|
||||
@@ -3816,11 +3814,24 @@ PlayerState::PlayerState()
|
||||
|
||||
void PlayerState::getParents(TCNodes &out, const CBonusSystemNode *root /*= NULL*/) const
|
||||
{
|
||||
//TODO: global effects
|
||||
/*
|
||||
for (std::vector<CGHeroInstance *>::const_iterator it = heroes.begin(); it != heroes.end(); ++it)
|
||||
{
|
||||
if (*it != root)
|
||||
(*it)->getParents(out, root);
|
||||
}
|
||||
for (std::vector<CGTownInstance *>::const_iterator it = towns.begin(); it != towns.end(); ++it)
|
||||
{
|
||||
if (*it != root)
|
||||
(*it)->getParents(out, root);
|
||||
}
|
||||
*/
|
||||
//TODO - dwellings
|
||||
}
|
||||
|
||||
void PlayerState::getBonuses(BonusList &out, const CSelector &selector, const CBonusSystemNode *root /*= NULL*/) const
|
||||
{
|
||||
{//temporary
|
||||
//CBonusSystemNode::getBonuses(out, selector, root);
|
||||
}
|
||||
|
||||
InfoAboutHero::InfoAboutHero()
|
||||
|
@@ -175,27 +175,6 @@ bool IGameCallback::isAllowed( int type, int id )
|
||||
}
|
||||
}
|
||||
|
||||
void IGameCallback::getAllowedArts(std::vector<CArtifact*> &out, std::vector<CArtifact*> CArtHandler::*arts, int flag)
|
||||
{
|
||||
if (!(VLC->arth->*arts).size()) //restock avaliable arts
|
||||
{
|
||||
for (int i = 0; i < VLC->arth->artifacts.size(); i++)
|
||||
{
|
||||
if (VLC->arth->artifacts[i]->aClass == flag)
|
||||
(VLC->arth->*arts).push_back(VLC->arth->artifacts[i]);
|
||||
}
|
||||
}
|
||||
|
||||
for (int i = 0; i < (VLC->arth->*arts).size(); i++)
|
||||
{
|
||||
CArtifact *art = (VLC->arth->*arts)[i];
|
||||
if(isAllowed(1, art->id))
|
||||
{
|
||||
out.push_back(art);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void IGameCallback::pickAllowedArtsSet(std::vector<const CArtifact*> &out)
|
||||
{
|
||||
for (int i = 0; i < 2; i++)
|
||||
@@ -208,50 +187,22 @@ void IGameCallback::pickAllowedArtsSet(std::vector<const CArtifact*> &out)
|
||||
out.push_back(VLC->arth->artifacts[getRandomArt(CArtifact::ART_MAJOR)]);
|
||||
}
|
||||
|
||||
void IGameCallback::getAllowed(std::vector<CArtifact*> &out, int flags)
|
||||
{
|
||||
if(flags & CArtifact::ART_TREASURE)
|
||||
getAllowedArts(out,&CArtHandler::treasures, CArtifact::ART_TREASURE);
|
||||
if(flags & CArtifact::ART_MINOR)
|
||||
getAllowedArts(out,&CArtHandler::minors, CArtifact::ART_MINOR);
|
||||
if(flags & CArtifact::ART_MAJOR)
|
||||
getAllowedArts(out,&CArtHandler::majors, CArtifact::ART_MAJOR);
|
||||
if(flags & CArtifact::ART_RELIC)
|
||||
getAllowedArts(out,&CArtHandler::relics, CArtifact::ART_RELIC);
|
||||
if (!out.size()) //no arts are avaliable
|
||||
{
|
||||
out.resize(64);
|
||||
std::fill_n(out.begin(), 64, VLC->arth->artifacts[2]); //magic
|
||||
}
|
||||
}
|
||||
|
||||
ui16 IGameCallback::getRandomArt (int flags)
|
||||
{
|
||||
std::vector<CArtifact*> out;
|
||||
getAllowed(out, flags);
|
||||
CArtifact *art = out[ran() % out.size()];
|
||||
std::vector<CArtifact*>* ptr;
|
||||
switch (art->aClass)
|
||||
{
|
||||
case CArtifact::ART_TREASURE:
|
||||
ptr = &VLC->arth->treasures;
|
||||
break;
|
||||
case CArtifact::ART_MINOR:
|
||||
ptr = &VLC->arth->minors;
|
||||
break;
|
||||
case CArtifact::ART_MAJOR:
|
||||
ptr = &VLC->arth->majors;
|
||||
break;
|
||||
case CArtifact::ART_RELIC:
|
||||
ptr = &VLC->arth->relics;
|
||||
break;
|
||||
default: //special artifacts should not be erased
|
||||
return art->id;
|
||||
}
|
||||
ptr->erase (std::find(ptr->begin(), ptr->end(), art)); //remove the artifact from avaliable list
|
||||
return art->id;
|
||||
return VLC->arth->getRandomArt(flags);
|
||||
}
|
||||
|
||||
ui16 IGameCallback::getArtSync (ui32 rand, int flags)
|
||||
{
|
||||
return VLC->arth->getArtSync (rand, flags);
|
||||
}
|
||||
|
||||
void IGameCallback::erasePickedArt (si32 id)
|
||||
{
|
||||
VLC->arth->erasePickedArt(id);
|
||||
}
|
||||
|
||||
|
||||
void IGameCallback::getAllowedSpells(std::vector<ui16> &out, ui16 level)
|
||||
{
|
||||
|
||||
|
@@ -60,9 +60,9 @@ public:
|
||||
virtual void getAllTiles (std::set<int3> &tiles, int player=-1, int level=-1, int surface=0); //returns all tiles on given level (-1 - both levels, otherwise number of level); surface: 0 - land and water, 1 - only land, 2 - only water
|
||||
virtual bool isAllowed(int type, int id); //type: 0 - spell; 1- artifact
|
||||
virtual ui16 getRandomArt (int flags);
|
||||
virtual void getAllowedArts(std::vector<CArtifact*> &out, std::vector<CArtifact*> CArtHandler::*arts, int flag);
|
||||
virtual ui16 getArtSync (ui32 rand, int flags); //synchronic
|
||||
virtual void pickAllowedArtsSet(std::vector<const CArtifact*> &out); //gives 3 treasures, 3 minors, 1 major -> used by Black Market and Artifact Merchant
|
||||
virtual void getAllowed(std::vector<CArtifact*> &out, int flags); //flags: bitfield uses EartClass
|
||||
virtual void erasePickedArt (si32 id);
|
||||
virtual void getAllowedSpells(std::vector<ui16> &out, ui16 level);
|
||||
virtual int3 getMapSize(); //returns size of the map
|
||||
virtual TerrainTile * getTile(int3 pos);
|
||||
|
@@ -1906,7 +1906,6 @@ void CGameHandler::takeCreatures (int objid, TSlots creatures) //probably we cou
|
||||
int slot = newArmy.getSlotFor(creatures.begin()->second.type->idNumber);
|
||||
if (slot < 0)
|
||||
break;
|
||||
//newArmy.slots[slot].type = creatures.begin()->second.type;
|
||||
newArmy.slots[slot].count -= creatures.begin()->second.count;
|
||||
if (newArmy.getStack(slot).count < 1)
|
||||
newArmy.eraseStack(slot);
|
||||
|
Reference in New Issue
Block a user