1
0
mirror of https://github.com/vcmi/vcmi.git synced 2024-12-24 22:14:36 +02:00

- University is finally implemented, both town and map objects

This commit is contained in:
Ivan Savenko 2010-07-20 14:08:13 +00:00
parent cd9ab4cc62
commit 5dc444cd2b
18 changed files with 370 additions and 11 deletions

View File

@ -72,6 +72,7 @@ public:
//virtual void heroKilled(const CGHeroInstance*){};
virtual void heroMoved(const TryMoveHero & details){};
virtual void heroPrimarySkillChanged(const CGHeroInstance * hero, int which, si64 val){};
virtual void heroSecondarySkillChanged(const CGHeroInstance * hero, int which, int val){};
virtual void heroManaPointsChanged(const CGHeroInstance * hero){} //not called at the beginning of turn and after spell casts
virtual void heroMovePointsChanged(const CGHeroInstance * hero){} //not called at the beginning of turn and after movement
virtual void heroVisitsTown(const CGHeroInstance* hero, const CGTownInstance * town){};
@ -84,6 +85,7 @@ public:
virtual void showGarrisonDialog(const CArmedInstance *up, const CGHeroInstance *down, bool removableUnits, boost::function<void()> &onEnd) = 0; //all stacks operations between these objects become allowed, interface has to call onEnd when done
virtual void showPuzzleMap(){};
virtual void showMarketWindow(const IMarket *market, const CGHeroInstance *visitor){};
virtual void showUniversityWindow(const IMarket *market, const CGHeroInstance *visitor){};
virtual void showTavernWindow(const CGObjectInstance *townOrTavern){};
virtual void advmapSpellCast(const CGHeroInstance * caster, int spellID){}; //called when a hero casts a spell
virtual void tileHidden(const std::set<int3> &pos){};

View File

@ -703,7 +703,13 @@ void CCastleInterface::buildingClicked(int building)
LOCPLINT->showInfoDialog(boost::str(boost::format(CGI->generaltexth->allTexts[273]) % b->Name())); //Only visiting heroes may use the %s.
break;
/*Conflux*/ case 8: //Magic University
tlog4<<"Magic University not handled\n";
if (town->visitingHero)
GH.pushInt(new CUniversityWindow(town->visitingHero, town));
else if (town->garrisonHero)
GH.pushInt(new CUniversityWindow(town->garrisonHero, town));
else//no hero in town - default popup
defaultBuildingClicked(building);
break;
default:
defaultBuildingClicked(building);

View File

@ -405,6 +405,16 @@ void CPlayerInterface::heroPrimarySkillChanged(const CGHeroInstance * hero, int
else if(which < PRIMARY_SKILLS) //no need to redraw infowin if this is experience (exp is treated as prim skill with id==4)
updateInfo(hero);
}
void CPlayerInterface::heroSecondarySkillChanged(const CGHeroInstance * hero, int which, int val)
{
CUniversityWindow* cuw = dynamic_cast<CUniversityWindow*>(GH.topInt());
if(cuw) //university window is open
{
GH.totalRedraw();
}
}
void CPlayerInterface::heroManaPointsChanged(const CGHeroInstance * hero)
{
boost::unique_lock<boost::recursive_mutex> un(*pim);
@ -2013,6 +2023,12 @@ void CPlayerInterface::showMarketWindow(const IMarket *market, const CGHeroInsta
GH.pushInt(new CMarketplaceWindow(market, visitor, market->availableModes().front()));
}
void CPlayerInterface::showUniversityWindow(const IMarket *market, const CGHeroInstance *visitor)
{
CUniversityWindow *cuw = new CUniversityWindow(visitor, market);
GH.pushInt(cuw);
}
void CPlayerInterface::availableArtifactsChanged(const CGBlackMarket *bm /*= NULL*/)
{
if(CMarketplaceWindow *cmw = dynamic_cast<CMarketplaceWindow*>(GH.topInt()))

View File

@ -151,6 +151,7 @@ public:
void heroInGarrisonChange(const CGTownInstance *town);
void heroMoved(const TryMoveHero & details);
void heroPrimarySkillChanged(const CGHeroInstance * hero, int which, si64 val);
void heroSecondarySkillChanged(const CGHeroInstance * hero, int which, int val);
void heroManaPointsChanged(const CGHeroInstance * hero);
void heroMovePointsChanged(const CGHeroInstance * hero);
void heroVisitsTown(const CGHeroInstance* hero, const CGTownInstance * town);
@ -163,6 +164,7 @@ public:
void showArtifactAssemblyDialog(ui32 artifactID, ui32 assembleTo, bool assemble, CFunctionList<void()> onYes, CFunctionList<void()> onNo);
void showPuzzleMap();
void showMarketWindow(const IMarket *market, const CGHeroInstance *visitor);
void showUniversityWindow(const IMarket *market, const CGHeroInstance *visitor);
void showTavernWindow(const CGObjectInstance *townOrTavern);
void advmapSpellCast(const CGHeroInstance * caster, int spellID); //called when a hero casts a spell
void tileHidden(const std::set<int3> &pos); //called when given tiles become hidden under fog of war

View File

@ -5657,6 +5657,170 @@ CTransformerWindow::~CTransformerWindow()
}
void CUniversityWindow::CItem::clickLeft(tribool down, bool previousState)
{
if(previousState && (!down))
{
if ( state() != 2 )
return;
CUnivConfirmWindow *win = new CUnivConfirmWindow(parent, ID, LOCPLINT->cb->getResourceAmount(6) >= 2000);
GH.pushInt(win);
}
}
void CUniversityWindow::CItem::clickRight(tribool down, bool previousState)
{
if(down)
{
CInfoPopup *message = new CInfoPopup();
message->free = true;
message->bitmap = CMessage::drawBoxTextBitmapSub
(LOCPLINT->playerID,
CGI->generaltexth->skillInfoTexts[ID][0],
graphics->abils82->ourImages[ID*3+3].bitmap,
CGI->generaltexth->skillName[ID]);
message->pos.x = screen->w/2 - message->bitmap->w/2;
message->pos.y = screen->h/2 - message->bitmap->h/2;
GH.pushInt(message);
}
}
void CUniversityWindow::CItem::hover(bool on)
{
if (on)
GH.statusbar->print(CGI->generaltexth->skillName[ID]);
else
GH.statusbar->clear();
}
int CUniversityWindow::CItem::state()
{
if (parent->hero->getSecSkillLevel(ID))//hero know this skill
return 1;
if (parent->hero->secSkills.size() >= SKILL_PER_HERO)//can't learn more skills
return 0;
/* if (LOCPLINT->cb->getResourceAmount(6) < 2000 )//no gold - allowed in H3, confirm button is blocked instead
return 0;*/
return 2;
}
void CUniversityWindow::CItem::showAll(SDL_Surface * to)
{
SDL_Surface * bar;
switch (state())
{
case 0: bar = parent->red;
break;
case 1: bar = parent->yellow;
break;
case 2: bar = parent->green;
break;
}
blitAtLoc(bar, -28, -22, to);
blitAtLoc(bar, -28, 48, to);
printAtMiddleLoc (CGI->generaltexth->skillName[ID], 22, -13, FONT_SMALL, zwykly,to);//Name
printAtMiddleLoc (CGI->generaltexth->levels[0], 22, 57, FONT_SMALL, zwykly,to);//Level(always basic)
CPicture::showAll(to);
}
CUniversityWindow::CItem::CItem(CUniversityWindow * _parent, int _ID, int X, int Y):ID(_ID), parent(_parent),
CPicture (graphics->abils44->ourImages[_ID*3+3].bitmap,X,Y,false)
{
used = LCLICK | RCLICK | HOVER;
}
CUniversityWindow::CUniversityWindow(const CGHeroInstance * _hero, const IMarket * _market):hero(_hero), market(_market)
{
OBJ_CONSTRUCTION_CAPTURING_ALL;
bg = new CPicture("UNIVERS1.PCX");
bg->colorizeAndConvert(LOCPLINT->playerID);
yellow = BitmapHandler::loadBitmap("UNIVGOLD.PCX");
green = BitmapHandler::loadBitmap("UNIVGREN.PCX");//bars
red = BitmapHandler::loadBitmap("UNIVRED.PCX");
if ( market->o->ID == 104 ) // this is adventure map university
{
SDL_Surface * titleImage = BitmapHandler::loadBitmap("UNIVBLDG.PCX");
blitAtLoc(titleImage, 232-titleImage->w/2, 76-titleImage->h/2, bg->bg);
SDL_FreeSurface(titleImage);
}
else if (LOCPLINT->castleInt && LOCPLINT->castleInt->town->subID == 8)// this is town university
{
SDL_Surface * titleImage = LOCPLINT->castleInt->bicons->ourImages[21].bitmap;
blitAtLoc(titleImage, 232-titleImage->w/2, 76-titleImage->h/2, bg->bg);
}
else
tlog0<<"Error: Image for university was not found!\n";//This should not happen
printAtMiddleWBLoc(CGI->generaltexth->allTexts[603], 232, 153, FONT_SMALL, 70,zwykly,bg->bg);//Clerk speech
printAtMiddleLoc (CGI->generaltexth->allTexts[602], 231, 26 , FONT_MEDIUM ,tytulowy,bg->bg);//University
std::vector<int> list = market->availableItemsIds(RESOURCE_SKILL);
if (list.size()!=4)
tlog0<<"\t\tIncorrect size of available items vector!\n";
for (int i=0; i<list.size(); i++)//prepare clickable items
items.push_back(new CItem(this, list[i], pos.x+54+i*104, pos.y+234));
pos = center(bg->pos);
cancel = new AdventureMapButton(CGI->generaltexth->zelp[632],
boost::bind(&CGuiHandler::popIntTotally,&GH, this),200,313,"IOKAY.DEF",SDLK_RETURN);
bar = new CGStatusBar(232, 371);
}
CUniversityWindow::~CUniversityWindow()
{
delete red;
delete yellow;
delete green;
}
CUnivConfirmWindow::CUnivConfirmWindow(CUniversityWindow * PARENT, int SKILL, bool available ):parent(PARENT)
{
OBJ_CONSTRUCTION_CAPTURING_ALL;
bg = new CPicture("UNIVERS2.PCX");
bg->colorizeAndConvert(LOCPLINT->playerID);
std::string text = CGI->generaltexth->allTexts[608];
boost::replace_first(text, "%s", CGI->generaltexth->levels[0]);
boost::replace_first(text, "%s", CGI->generaltexth->skillName[SKILL]);
boost::replace_first(text, "%d", "2000");
printAtMiddleWBLoc(text, 230, 163, FONT_SMALL, 65,zwykly,bg->bg);//Clerk speech
printAtMiddleLoc (CGI->generaltexth-> skillName[SKILL], 230, 37, FONT_SMALL, zwykly,bg->bg);//Skill name
printAtMiddleLoc (CGI->generaltexth->levels[1], 230, 107, FONT_SMALL, zwykly,bg->bg);//Skill level
printAtMiddleLoc ("2000", 230, 267, FONT_SMALL, zwykly,bg->bg);//Cost
blitAtLoc(graphics->abils44->ourImages[SKILL*3+3].bitmap, 211, 51, bg->bg);//skill
blitAtLoc(graphics->resources32->ourImages[6].bitmap, 210, 210, bg->bg);//gold
pos = center(bg->pos);
std::string hoverText = CGI->generaltexth->allTexts[609];
boost::replace_first(hoverText, "%s", CGI->generaltexth->levels[0]+ " " + CGI->generaltexth->skillName[SKILL]);
text = CGI->generaltexth->zelp[633].second;
boost::replace_first(text, "%s", CGI->generaltexth->levels[0]);
boost::replace_first(text, "%s", CGI->generaltexth->skillName[SKILL]);
boost::replace_first(text, "%d", "2000");
confirm= new AdventureMapButton(hoverText, text, boost::bind(&CUnivConfirmWindow::makeDeal, this, SKILL),
148,299,"IBY6432.DEF",SDLK_RETURN);
confirm->block(!available);
cancel = new AdventureMapButton(CGI->generaltexth->zelp[631],boost::bind(&CGuiHandler::popIntTotally, &GH, this),
252,299,"ICANCEL.DEF",SDLK_ESCAPE);
bar = new CGStatusBar(232, 371);
}
void CUnivConfirmWindow::makeDeal(int skill)
{
LOCPLINT->cb->trade(parent->market->o, RESOURCE_SKILL, 6, skill, 1, parent->hero);
GH.popIntTotally(this);
}
void CThievesGuildWindow::activate()
{
CIntObject::activate();

View File

@ -1068,6 +1068,52 @@ public:
~CTransformerWindow(); //d-tor
};
class CUniversityWindow : public CIntObject
{
class CItem : public CPicture
{
public:
int ID;//id of selected skill
CUniversityWindow * parent;
void showAll(SDL_Surface * to);
void clickLeft(tribool down, bool previousState);
void clickRight(tribool down, bool previousState);
void hover(bool on);
int state();//0=can't learn, 1=learned, 2=can learn
CItem(CUniversityWindow * _parent, int _ID, int X, int Y);
};
public:
const CGHeroInstance *hero;
const IMarket * market;
SDL_Surface * red,
* green,//colored bars near skills
* yellow;
CPicture *bg; //background
std::vector<CItem*> items;
AdventureMapButton *cancel;
CGStatusBar *bar;
CUniversityWindow(const CGHeroInstance * _hero, const IMarket * _market); //c-tor
~CUniversityWindow(); //d-tor
};
class CUnivConfirmWindow : public CIntObject//Confirmation window for University
{
public:
CUniversityWindow * parent;
CPicture * bg;
CGStatusBar *bar;
AdventureMapButton *confirm, *cancel;
CUnivConfirmWindow(CUniversityWindow * PARENT, int SKILL, bool available); //c-tor
void makeDeal(int skill);
};
class CThievesGuildWindow : public CIntObject
{
const CGObjectInstance * owner;

View File

@ -61,7 +61,13 @@ void SetPrimSkill::applyCl( CClient *cl )
void SetSecSkill::applyCl( CClient *cl )
{
//TODO: inform interface?
const CGHeroInstance *h = GS(cl)->getHero(id);
if(!h)
{
tlog1 << "Cannot find hero with ID " << id << std::endl;
return;
}
INTERFACE_CALL_IF_PRESENT(h->tempOwner,heroSecondarySkillChanged,h,which,val);
}
void HeroVisitCastle::applyCl( CClient *cl )
@ -722,6 +728,14 @@ void OpenWindow::applyCl(CClient *cl)
GH.pushInt( new CThievesGuildWindow(obj) );
}
break;
case UNIVERSITY_WINDOW:
{
//displays University window (when hero enters University on adventure map)
const IMarket *market = IMarket::castFrom(cl->getObj(id1));
const CGHeroInstance *hero = cl->getHero(id2);
INTERFACE_CALL_IF_PRESENT(hero->tempOwner,showUniversityWindow, market, hero);
}
break;
case MARKET_WINDOW:
{
//displays Thieves' Guild window (when hero enters Den of Thieves)
@ -735,6 +749,7 @@ void OpenWindow::applyCl(CClient *cl)
{
INTERFACE_CALL_IF_PRESENT(id1, showPuzzleMap);
}
break;
case TAVERN_WINDOW:
const CGObjectInstance *obj1 = cl->getObj(id1),
*obj2 = cl->getObj(id2);

View File

@ -112,7 +112,7 @@ const int BFIELD_SIZE = BFIELD_WIDTH * BFIELD_HEIGHT;
enum EMarketMode
{
RESOURCE_RESOURCE, RESOURCE_PLAYER, CREATURE_RESOURCE, RESOURCE_ARTIFACT,
ARTIFACT_RESOURCE, ARTIFACT_EXP, CREATURE_EXP, CREATURE_UNDEAD,
ARTIFACT_RESOURCE, ARTIFACT_EXP, CREATURE_EXP, CREATURE_UNDEAD, RESOURCE_SKILL,
MARTKET_AFTER_LAST_PLACEHOLDER
};

View File

@ -51,7 +51,7 @@ ui8 CGObelisk::obeliskCount; //how many obelisks are on map
std::map<ui8, ui8> CGObelisk::visited; //map: color_id => how many obelisks has been visited
std::vector<const CArtifact *> CGTownInstance::merchantArtifacts;
std::vector<int> CGTownInstance::universitySkills;
void IObjectInterface::onHeroVisit(const CGHeroInstance * h) const
{};
@ -2250,6 +2250,8 @@ bool CGTownInstance::allowsTrade(EMarketMode mode) const
return subID == 6 && vstd::contains(builtBuildings, 21); //Freelancer's guild
case CREATURE_UNDEAD:
return subID == 4 && vstd::contains(builtBuildings, 22);//Skeleton transformer
case RESOURCE_SKILL:
return subID == 8 && vstd::contains(builtBuildings, 21);//Magic University
default:
assert(0);
return false;
@ -2268,6 +2270,10 @@ std::vector<int> CGTownInstance::availableItemsIds(EMarketMode mode) const
ret.push_back(-1);
return ret;
}
else if ( mode == RESOURCE_SKILL )
{
return universitySkills;
}
else
return IMarket::availableItemsIds(mode);
}
@ -6555,6 +6561,8 @@ const IMarket * IMarket::castFrom(const CGObjectInstance *obj)
case 221: //Trading Post (snow)
case 213: //Freelancer's Guild
return static_cast<const CGMarket*>(obj);
case 104: //University
return static_cast<const CGUniversity*>(obj);
default:
tlog1 << "Cannot cast to IMarket object with ID " << obj->ID << std::endl;
return NULL;
@ -6613,6 +6621,8 @@ bool CGMarket::allowsTrade(EMarketMode mode) const
case ARTIFACT_EXP:
case CREATURE_EXP:
return ID == 2; //TODO? check here for alignment of visiting hero? - would not be coherent with other checks here
case RESOURCE_SKILL:
return ID == 104;//University
}
return false;
}
@ -6669,4 +6679,45 @@ void CGBlackMarket::newTurn() const
saa.id = id;
cb->pickAllowedArtsSet(saa.arts);
cb->sendAndApply(&saa);
}
}
void CGUniversity::initObj()
{
std::vector <int> toChoose;
for (int i=0; i<SKILL_QUANTITY; i++)
if (cb->isAllowed(2,i))
toChoose.push_back(i);
if (toChoose.size() < 4)
{
tlog0<<"Warning: less then 4 available skills was found by University initializer!\n";
return;
}
for (int i=0; i<4; i++)//get 4 skills
{
int skillPos = ran()%toChoose.size();
skills.push_back(toChoose[skillPos]);//move it to selected
toChoose.erase(toChoose.begin()+skillPos);//remove from list
}
}
std::vector<int> CGUniversity::availableItemsIds(EMarketMode mode) const
{
switch (mode)
{
case RESOURCE_SKILL:
return skills;
default:
return std::vector <int> ();
}
}
void CGUniversity::onHeroVisit(const CGHeroInstance * h) const
{
OpenWindow ow;
ow.id1 = id;
ow.id2 = h->id;
ow.window = OpenWindow::UNIVERSITY_WINDOW;
cb->sendAndApply(&ow);
}

View File

@ -501,6 +501,7 @@ public:
//////////////////////////////////////////////////////////////////////////
static std::vector<const CArtifact *> merchantArtifacts; //vector of artifacts available at Artifact merchant, NULLs possible (for making empty space when artifact is bought)
static std::vector<int> universitySkills;//skills for university of magic
template <typename Handler> void serialize(Handler &h, const int version)
{
@ -1190,6 +1191,22 @@ public:
}
};
class DLL_EXPORT CGUniversity : public CGMarket
{
public:
std::vector<int> skills; //available skills
std::vector<int> availableItemsIds(EMarketMode mode) const;
void initObj();//set skills for trade
void onHeroVisit(const CGHeroInstance * h) const; //open window
template <typename Handler> void serialize(Handler &h, const int version)
{
h & static_cast<CGMarket&>(*this);
h & skills;
}
};
struct BankConfig
{
BankConfig() {level = chance = upgradeChance = combatValue = value = rewardDifficulty = easiest = 0; };

View File

@ -1494,6 +1494,9 @@ void CGameState::init( StartInfo * si, ui32 checksum, int Seed )
}
}
/****************************TOWNS************************************************/
for ( int i=0; i<4; i++)
CGTownInstance::universitySkills.push_back(14+i);//skills for university
for (unsigned int i=0;i<map->towns.size();i++)
{
CGTownInstance * vti =(map->towns[i]);
@ -1512,7 +1515,8 @@ void CGameState::init( StartInfo * si, ui32 checksum, int Seed )
if(ran()%2)
vti->builtBuildings.insert(31);
}
if (vstd::contains(vti->builtBuildings,(6)) && vti->state()==3)
if (vstd::contains(vti->builtBuildings,(6)) && vti->state()==2)
vti->builtBuildings.erase(6);//if we have harbor without water - erase it (this is H3 behaviour)
//init hordes

View File

@ -170,6 +170,8 @@ bool IGameCallback::isAllowed( int type, int id )
return gs->map->allowedSpell[id];
case 1:
return gs->map->allowedArtifact[id];
case 2:
return gs->map->allowedAbilities[id];
default:
tlog1 << "Wrong call to IGameCallback::isAllowed!\n";
return false;

View File

@ -59,7 +59,7 @@ public:
virtual int getHeroCount(int player, bool includeGarrisoned);
virtual void getTilesInRange(std::set<int3> &tiles, int3 pos, int radious, int player=-1, int mode=0); //mode 1 - only unrevealed tiles; mode 0 - all, mode -1 - only unrevealed
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 bool isAllowed(int type, int id); //type: 0 - spell; 1- artifact; 2 - secondary skill
virtual ui16 getRandomArt (int flags);
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

View File

@ -628,8 +628,8 @@ struct OpenWindow : public CPackForClient //517
OpenWindow(){type = 517;};
void applyCl(CClient *cl);
enum EWindow {EXCHANGE_WINDOW, RECRUITMENT_FIRST, RECRUITMENT_ALL, SHIPYARD_WINDOW, THIEVES_GUILD, PUZZLE_MAP,
MARKET_WINDOW, TAVERN_WINDOW};
enum EWindow {EXCHANGE_WINDOW, RECRUITMENT_FIRST, RECRUITMENT_ALL, SHIPYARD_WINDOW,
THIEVES_GUILD, UNIVERSITY_WINDOW, MARKET_WINDOW, PUZZLE_MAP, TAVERN_WINDOW};
ui8 window;
ui32 id1, id2;
@ -1407,7 +1407,7 @@ struct TradeOnMarketplace : public CPackForServer
const CGObjectInstance *market;
const CGHeroInstance *hero; //needed when trading artifacts / creatures
ui8 mode;//0 - res<->res;
ui8 mode;//enum EMarketMode
ui32 r1, r2; //mode 0: r1 - sold resource, r2 - bought res
ui32 val; //units of sold resource

View File

@ -975,7 +975,7 @@ void Mapa::loadHero( CGObjectInstance * &nobj, const unsigned char * bufor, int
{
bool areSpells = bufor[i]; ++i;
if(areSpells) //TODO: sprawdziæ //seems to be ok - tow
if(areSpells) //TODO: sprawdziæ //seems to be ok - tow
{
nhi->spells.insert(0xffffffff); //placeholder "preset spells"
int ist = i;
@ -1965,6 +1965,11 @@ void Mapa::readObjects( const unsigned char * bufor, int &i)
nobj = new CGMarket();
break;
}
case 104: //University
{
nobj = new CGUniversity();
break;
}
case 7: //Black Market
{
nobj = new CGBlackMarket();

View File

@ -3196,6 +3196,32 @@ bool CGameHandler::buyArtifact(const IMarket *m, const CGHeroInstance *h, int ri
giveHeroArtifact(aid, h->id, -2);
}
bool CGameHandler::buySecSkill( const IMarket *m, const CGHeroInstance *h, int skill)
{
if (!h)
COMPLAIN_RET("You need hero to buy a skill!");
if (h->getSecSkillLevel(skill))
COMPLAIN_RET("Hero already know this skill");
if (h->secSkills.size() >= SKILL_PER_HERO)//can't learn more skills
COMPLAIN_RET("Hero can't learn any more skills");
if(!vstd::contains(m->availableItemsIds(RESOURCE_SKILL), skill))
COMPLAIN_RET("That skill is unavailable!");
if(getResource(h->tempOwner, 6) < 2000)//TODO: remove hardcoded resource\summ?
COMPLAIN_RET("You can't afford to buy this skill");
SetResource sr;
sr.player = h->tempOwner;
sr.resid = 6;
sr.val = getResource(h->tempOwner, 6) - 2000;
sendAndApply(&sr);
changeSecSkill(h->id, skill, 1, true);
}
bool CGameHandler::tradeResources(const IMarket *market, ui32 val, ui8 player, ui32 id1, ui32 id2)
{
int r1 = gs->getPlayer(player)->resources[id1],

View File

@ -178,6 +178,7 @@ public:
bool assembleArtifacts (si32 heroID, ui16 artifactSlot, bool assemble, ui32 assembleTo);
bool buyArtifact( ui32 hid, si32 aid ); //for blacksmith and mage guild only -> buying for gold in common buildings
bool buyArtifact( const IMarket *m, const CGHeroInstance *h, int rid, int aid); //for artifact merchant and black market -> buying for any resource in special building / advobject
bool buySecSkill( const IMarket *m, const CGHeroInstance *h, int skill);
bool swapArtifacts(si32 srcHeroID, si32 destHeroID, ui16 srcSlot, ui16 destSlot);
bool garrisonSwap(si32 tid);
bool upgradeCreature( ui32 objid, ui8 pos, ui32 upgID );

View File

@ -158,6 +158,8 @@ bool TradeOnMarketplace::applyGh( CGameHandler *gh )
return gh->buyArtifact(m, hero, r1, r2);
case CREATURE_UNDEAD:
return gh->transformInUndead(m, hero, r1);
case RESOURCE_SKILL:
return gh->buySecSkill(m, hero, r2);
case CREATURE_EXP:
return gh->sacrificeCreatures(m, hero, r1, val);
default: