1
0
mirror of https://github.com/vcmi/vcmi.git synced 2025-01-12 02:28:11 +02:00

Some changes to the market window, sending resources to other players.

This commit is contained in:
Michał W. Urbańczyk 2010-05-07 22:10:32 +00:00
parent 3c72644880
commit 921bddc35e
12 changed files with 254 additions and 127 deletions

View File

@ -981,6 +981,13 @@ si8 CCallback::battleCanTeleportTo(int stackID, int destHex, int telportLevel)
return gs->curB->canTeleportTo(stackID, destHex, telportLevel);
}
int CCallback::getPlayerStatus(int player) const
{
const PlayerState *ps = gs->getPlayer(player, false);
if(!ps)
return -1;
return ps->status;
}
InfoAboutTown::InfoAboutTown()
{
tType = NULL;

View File

@ -118,6 +118,7 @@ public:
virtual int estimateSpellDamage(const CSpell * sp) const =0; //estimates damage of given spell; returns 0 if spell causes no dmg
virtual void getThievesGuildInfo(SThievesGuildInfo & thi, const CGObjectInstance * obj)=0; //get thieves' guild info obtainable while visiting given object
virtual int3 getGrailPos(float &outKnownRatio)=0;
virtual int getPlayerStatus(int player) const = 0; //-1 if no such player
//hero
virtual int howManyHeroes(bool includeGarrisoned = true)const =0;
@ -279,6 +280,7 @@ public:
bool getHeroInfo(const CGObjectInstance *hero, InfoAboutHero &dest) const;
bool getTownInfo(const CGObjectInstance *town, InfoAboutTown &dest) const;
int3 guardingCreaturePosition (int3 pos) const;
int getPlayerStatus(int player) const;
//battle
int battleGetBattlefieldType(); // 1. sand/shore 2. sand/mesas 3. dirt/birches 4. dirt/hills 5. dirt/pines 6. grass/hills 7. grass/pines 8. lava 9. magic plains 10. snow/mountains 11. snow/trees 12. subterranean 13. swamp/trees 14. fiery fields 15. rock lands 16. magic clouds 17. lucid pools 18. holy ground 19. clover field 20. evil fog 21. "favourable winds" text on magic plains background 22. cursed ground 23. rough 24. ship to ship 25. ship

View File

@ -468,7 +468,7 @@ void CSlider::mouseMoved (const SDL_MouseMotionEvent & sEvent)
void CSlider::redrawSlider()
{
slider->show(screenBuf);
//slider->show(screenBuf);
}
void CSlider::moveLeft()

View File

@ -7,6 +7,7 @@
#include "CGameInfo.h"
#include "CCursorHandler.h"
#include "CBitmapHandler.h"
#include "Graphics.h"
/*
* GUIBase.cpp, part of VCMI engine
*
@ -697,6 +698,12 @@ void CIntObject::moveTo( const Point &p, bool propagate /*= true*/ )
moveBy(Point(p.x - pos.x, p.y - pos.y), propagate);
}
void CIntObject::delChild(CIntObject *child)
{
children -= child;
delete child;
}
CPicture::CPicture( SDL_Surface *BG, int x, int y, bool Free )
{
bg = BG;
@ -767,6 +774,14 @@ void CPicture::createSimpleRect(const Rect &r, bool screenFormat, ui32 color)
SDL_FillRect(bg, NULL, color);
}
void CPicture::colorizeAndConvert(int player)
{
assert(bg);
assert(bg->format->BitsPerPixel == 8);
graphics->blueToPlayersAdv(bg, player);
convertToScreenBPP();
}
ObjectConstruction::ObjectConstruction( CIntObject *obj )
:myObj(obj)
{

View File

@ -390,6 +390,8 @@ public:
const Rect & center(); //centers when pos.w and pos.h are set, returns new position
void moveBy(const Point &p, bool propagate = true);
void moveTo(const Point &p, bool propagate = true);
void delChild(CIntObject *child); //removes from chidlren list, deletes
};
//class for binding keys to left mouse button clicks
@ -443,6 +445,7 @@ public:
~CPicture();
void showAll(SDL_Surface * to);
void convertToScreenBPP();
void colorizeAndConvert(int player);
};
class CGuiHandler

View File

@ -2318,8 +2318,7 @@ void CCreInfoWindow::init(const CCreature *cre, const CStackInstance *stack, int
c = cre;
bitmap = new CPicture("CRSTKPU.bmp");
graphics->blueToPlayersAdv(*bitmap, LOCPLINT->playerID);
bitmap->convertToScreenBPP();
bitmap->colorizeAndConvert(LOCPLINT->playerID);
pos = bitmap->center();
{
@ -2583,12 +2582,23 @@ CMarketplaceWindow::CTradeableItem::CTradeableItem( int Type, int ID, bool Left)
left = Left;
type = Type;
id = ID;
used = LCLICK;
}
void CMarketplaceWindow::CTradeableItem::show(SDL_Surface * to)
{
SDL_Surface *hlp = getSurface();
blitAt(hlp,pos.x+19,pos.y+9,to);
Rect dest = pos;
switch(type)
{
case RESOURCE:
dest.x += 19;
dest.y += 9;
break;
}
blitAt(hlp, dest, to);
}
void CMarketplaceWindow::CTradeableItem::clickLeft(tribool down, bool previousState)
@ -2615,96 +2625,102 @@ void CMarketplaceWindow::CTradeableItem::clickLeft(tribool down, bool previousSt
}
}
void CMarketplaceWindow::CTradeableItem::activate()
{
activateLClick();
}
void CMarketplaceWindow::CTradeableItem::deactivate()
{
deactivateLClick();
}
SDL_Surface * CMarketplaceWindow::CTradeableItem::getSurface()
{
switch(type)
{
case 0:
case RESOURCE:
return graphics->resources32->ourImages[id].bitmap;
case 1:
case PLAYER:
return graphics->flags->ourImages[id].bitmap;
case ARTIFACT:
return graphics->artDefs->ourImages[id].bitmap;
default:
return NULL;
}
}
static void initItems( std::vector<CMarketplaceWindow::CTradeableItem*> &i, std::vector<SDL_Rect> &p, int type, int amount, bool left, std::vector<int> *ids/*=NULL*/ )
static void initItems( std::vector<CMarketplaceWindow::CTradeableItem*> &i, std::vector<Rect> &p, int type, int amount, bool left, std::vector<int> *ids/*=NULL*/ )
{
if(ids)
amin(amount, ids->size());
i.resize(amount);
for(int j=0;j<amount;j++)
{
i[j] = new CMarketplaceWindow::CTradeableItem(type,(ids && ids->size()>j) ? (*ids)[j] : j, left);
i[j]->pos = p[j];
i[j]->pos = p[j] + i[j]->pos;
}
}
void CMarketplaceWindow::setMode( int mode )
{
std::vector<SDL_Rect> lpos, rpos;
clear();
switch(mode)
{
case 0:
{
SDL_Surface *bg2 = BitmapHandler::loadBitmap("TPMRKRES.bmp");
SDL_SetColorKey(bg2,SDL_SRCCOLORKEY,SDL_MapRGB(bg2->format,0,255,255));
graphics->blueToPlayersAdv(bg2,LOCPLINT->playerID);
bg = SDL_ConvertSurface(bg2,screen->format,0);
SDL_FreeSurface(bg2);
lpos += genRect(66,74,39,180), genRect(66,74,122,180), genRect(66,74,204,180),
genRect(66,74,39,259), genRect(66,74,122,259), genRect(66,74,204,259),
genRect(66,74,122,338);
for(int i=0;i<lpos.size();i++)
{
lpos[i].x += pos.x;
lpos[i].y += pos.y;
rpos.push_back(lpos[i]);
rpos[rpos.size()-1].x += 288;
}
initItems(left,lpos,0,7,true,NULL);
initItems(right,rpos,0,7,false,NULL);
printAtMiddle(CGI->generaltexth->allTexts[158],300,27,FONT_BIG,tytulowy,bg); //title
printAtMiddle(CGI->generaltexth->allTexts[270],154,148,FONT_SMALL,zwykly,bg); //kingdom res.
printAtMiddle(CGI->generaltexth->allTexts[168],445,147,FONT_SMALL,zwykly,bg); //available for trade
}
}
}
void CMarketplaceWindow::clear()
{
for(int i=0;i<left.size();i++)
delete left[i];
for(int i=0;i<right.size();i++)
delete right[i];
left.clear();
right.clear();
SDL_FreeSurface(bg);
}
CMarketplaceWindow::CMarketplaceWindow(int Mode)
{
OBJ_CONSTRUCTION_CAPTURING_ALL;
type = BLOCK_ADV_HOTKEYS;
mode = Mode;
bg = NULL;
ok = max = deal = NULL;
pos.x = screen->w/2 - 300;
pos.y = screen->h/2 - 296;
slider = new CSlider(pos.x+231,pos.y+490,137,boost::bind(&CMarketplaceWindow::sliderMoved,this,_1),0,0);
setMode(mode);
std::string bgName;
std::vector<int> *rIds = NULL, *lIds = NULL;
switch(Mode)
{
case RESOURCE_RESOURCE:
bgName = "TPMRKRES.bmp";
ltype = RESOURCE;
rtype = RESOURCE;
break;
case RESOURCE_PLAYER:
bgName = "TPMRKPTS.bmp";
ltype = RESOURCE;
rtype = PLAYER;
rIds = new std::vector<int>;
for(int i = 0, found = 0; i < PLAYER_LIMIT; i++)
if(i != LOCPLINT->playerID && LOCPLINT->cb->getPlayerStatus(i) == PlayerState::INGAME)
rIds->push_back(i);
break;
}
bg = new CPicture(bgName);
bg->colorizeAndConvert(LOCPLINT->playerID);
printAtMiddle(CGI->generaltexth->allTexts[158],300,27,FONT_BIG,tytulowy,*bg); //title
printAtMiddle(CGI->generaltexth->allTexts[270],154,148,FONT_SMALL,zwykly,*bg); //kingdom res.
std::vector<Rect> lpos, rpos;
getPositionsFor(lpos, false, ltype);
getPositionsFor(rpos, true, rtype);
initItems(left, lpos, ltype, 7, true, lIds);
initItems(right, rpos, rtype, rIds ? rIds->size() : 7, false, rIds);
delNull(rIds);
delNull(lIds);
//slider and buttons must be created after bg
slider = new CSlider(231,490,137,boost::bind(&CMarketplaceWindow::sliderMoved,this,_1),0,0);
hLeft = hRight = NULL;
ok = new AdventureMapButton("","",boost::bind(&CGuiHandler::popIntTotally,&GH,this),pos.x+516,pos.y+520,"IOK6432.DEF",SDLK_RETURN);
ok = new AdventureMapButton("","",boost::bind(&CGuiHandler::popIntTotally,&GH,this),516,520,"IOK6432.DEF",SDLK_RETURN);
ok->assignedKeys.insert(SDLK_ESCAPE);
deal = new AdventureMapButton("","",boost::bind(&CMarketplaceWindow::makeDeal,this),pos.x+307,pos.y+520,"TPMRKB.DEF");
max = new AdventureMapButton("","",boost::bind(&CMarketplaceWindow::setMax,this),pos.x+229,pos.y+520,"IRCBTNS.DEF");
deal = new AdventureMapButton("","",boost::bind(&CMarketplaceWindow::makeDeal,this),307,520,"TPMRKB.DEF");
max = new AdventureMapButton("","",boost::bind(&CMarketplaceWindow::setMax,this),229,520,"IRCBTNS.DEF");
switch(Mode)
{
case RESOURCE_RESOURCE:
{
new AdventureMapButton("","",boost::bind(&CMarketplaceWindow::setMode,this, RESOURCE_PLAYER), 18, 520,"TPMRKBU1.DEF");
printAtMiddle(CGI->generaltexth->allTexts[168],445,147,FONT_SMALL,zwykly,*bg); //available for trade
}
break;
case RESOURCE_PLAYER:
{
new AdventureMapButton("","",boost::bind(&CMarketplaceWindow::setMode,this, RESOURCE_RESOURCE), 516, 450,"TPMRKBU5.DEF");
printAtMiddle(CGI->generaltexth->allTexts[169],445,55,FONT_SMALL,zwykly,*bg); //players
}
break;
}
max->block(true);
deal->block(true);
@ -2712,33 +2728,45 @@ CMarketplaceWindow::CMarketplaceWindow(int Mode)
CMarketplaceWindow::~CMarketplaceWindow()
{
clear();
delete slider;
hLeft = hRight = NULL;
for(int i=0;i<left.size();i++)
delChild(left[i]);
for(int i=0;i<right.size();i++)
delChild(right[i]);
left.clear();
right.clear();
delChild(bg);
bg = NULL;
}
void CMarketplaceWindow::show(SDL_Surface * to)
{
blitAt(bg,pos,to);
CIntObject::show(to);
if(hRight)
CSDL_Ext::drawBorder(to,hRight->pos.x-1,hRight->pos.y-1,hRight->pos.w+2,hRight->pos.h+2,int3(255,231,148));
if(hLeft)
CSDL_Ext::drawBorder(to,hLeft->pos.x-1,hLeft->pos.y-1,hLeft->pos.w+2,hLeft->pos.h+2,int3(255,231,148));
ok->show(to);
deal->show(to);
max->show(to);
slider->show(to);
for(int i=0;i<left.size();i++)
left[i]->show(to);
for(int i=0;i<right.size();i++)
right[i]->show(to);
if(mode==0)
//left side
if(mode == RESOURCE_RESOURCE || mode == RESOURCE_PLAYER)
{
char buf[15];
for(int i=0;i<left.size();i++)
printAtMiddle(boost::lexical_cast<std::string>(LOCPLINT->cb->getResourceAmount(i)),
left[i]->pos.x+36,left[i]->pos.y+57,FONT_SMALL,zwykly,to);
if(hLeft && hRight && (hLeft->id != hRight->id || mode != RESOURCE_RESOURCE))
{
SDL_itoa(LOCPLINT->cb->getResourceAmount(i),buf,10);
printAtMiddle(buf,left[i]->pos.x+36,left[i]->pos.y+57,FONT_SMALL,zwykly,to);
blitAt(hLeft->getSurface(),pos.x+141,pos.y+457,to);
printAtMiddle(boost::lexical_cast<std::string>( slider->value * r1 ),pos.x+156,pos.y+505,FONT_SMALL,zwykly,to);
}
}
if(mode == RESOURCE_RESOURCE)
{
if(hLeft) //print prices
{
for(int i=0; i<right.size();i++)
@ -2749,40 +2777,24 @@ void CMarketplaceWindow::show(SDL_Surface * to)
printAtMiddle(CGI->generaltexth->allTexts[164],right[i]->pos.x+36,right[i]->pos.y+57,FONT_SMALL,zwykly,to);
}
}
if(hLeft && hRight && hLeft->id!= hRight->id)
if(hLeft && hRight && (hLeft->id != hRight->id))
{
blitAt(hLeft->getSurface(),pos.x+141,pos.y+457,to);
blitAt(hRight->getSurface(),pos.x+429,pos.y+457,to);
SDL_itoa(slider->value * r1,buf,10);
printAtMiddle(buf,pos.x+156,pos.y+505,FONT_SMALL,zwykly,to);
SDL_itoa(slider->value * r2,buf,10);
printAtMiddle(buf,pos.x+443,pos.y+505,FONT_SMALL,zwykly,to);
printAtMiddle(boost::lexical_cast<std::string>( slider->value * r2 ),pos.x+443,pos.y+505,FONT_SMALL,zwykly,to);
}
}
}
else if(mode == RESOURCE_PLAYER)
{
BOOST_FOREACH(CTradeableItem *i, right)
printAtMiddle(CGI->generaltexth->capColors[i->id], i->pos.x + 31, i->pos.y + 76, FONT_SMALL, zwykly, to);
void CMarketplaceWindow::activate()
{
for(int i=0;i<left.size();i++)
left[i]->activate();
for(int i=0;i<right.size();i++)
right[i]->activate();
ok->activate();
max->activate();
deal->activate();
slider->activate();
}
void CMarketplaceWindow::deactivate()
{
for(int i=0;i<left.size();i++)
left[i]->deactivate();
for(int i=0;i<right.size();i++)
right[i]->deactivate();
ok->deactivate();
max->deactivate();
deal->deactivate();
slider->deactivate();
if(hLeft && hRight)
{
blitAt(hRight->getSurface(),pos.x+417,pos.y+451,to);
printAtMiddle(CGI->generaltexth->capColors[hRight->id], pos.x+417 + 31, pos.y+451 + 76, FONT_SMALL, zwykly, to);
}
}
}
void CMarketplaceWindow::setMax()
@ -2800,15 +2812,22 @@ void CMarketplaceWindow::makeDeal()
void CMarketplaceWindow::sliderMoved( int to )
{
}
void CMarketplaceWindow::selectionChanged(bool side)
{
if(hLeft && hRight && hLeft->id!= hRight->id)
if(hLeft && hRight && (hLeft->id!= hRight->id || mode != RESOURCE_RESOURCE))
{
LOCPLINT->cb->getMarketOffer(hLeft->id,hRight->id,r1,r2,0);
slider->setAmount(LOCPLINT->cb->getResourceAmount(hLeft->id) / r1);
if(mode == RESOURCE_RESOURCE)
{
LOCPLINT->cb->getMarketOffer(hLeft->id,hRight->id,r1,r2,0);
slider->setAmount(LOCPLINT->cb->getResourceAmount(hLeft->id) / r1);
}
else if(mode == RESOURCE_PLAYER)
{
r1 = 1;
slider->setAmount(LOCPLINT->cb->getResourceAmount(hLeft->id));
}
slider->moveTo(0);
max->block(false);
deal->block(false);
@ -2837,6 +2856,32 @@ void CMarketplaceWindow::selectionChanged(bool side)
}
}
void CMarketplaceWindow::getPositionsFor(std::vector<Rect> &poss, bool Right, EType type) const
{
if(type == RESOURCE)
{
poss += genRect(66,74,39 ,180), genRect(66,74,122,180), genRect(66,74,204,180),
genRect(66,74,39,259), genRect(66,74,122,259), genRect(66,74,204,259),
genRect(66,74,122,338);
if(Right)
BOOST_FOREACH(Rect &r, poss)
r.x += 288;
}
else if(type == PLAYER)
{
assert(Right);
poss += genRect(64, 58, 333, 84), genRect(64, 58, 333 + 83, 84), genRect(64, 58, 333 + 2 * 83, 84),
genRect(64, 58, 333, 84 + 118), genRect(64, 58, 333 + 83, 84 + 118), genRect(64, 58, 333 + 2 * 83, 84 + 118),
genRect(64, 58, 333 + 83, 84 + 2*118);
}
}
void CMarketplaceWindow::setMode(int Mode)
{
GH.popIntTotally(this);
GH.pushInt(new CMarketplaceWindow(Mode));
}
CSystemOptionsWindow::CSystemOptionsWindow(const SDL_Rect &pos, CPlayerInterface * owner)
{
this->pos = pos;

View File

@ -518,6 +518,10 @@ public:
class CMarketplaceWindow : public CIntObject
{
public:
enum EType
{
RESOURCE, PLAYER, ARTIFACT
};
class CTradeableItem : public CIntObject
{
public:
@ -526,35 +530,33 @@ public:
bool left;
CFunctionList<void()> callback;
void activate();
void deactivate();
void show(SDL_Surface * to);
void clickLeft(tribool down, bool previousState);
SDL_Surface *getSurface();
CTradeableItem(int Type, int ID, bool Left);
};
SDL_Surface *bg; //background
CPicture *bg; //background
std::vector<CTradeableItem*> left, right;
std::vector<std::string> rSubs; //offer caption
CTradeableItem *hLeft, *hRight; //highlighted items (NULL if no highlight)
EType ltype, rtype;
int mode,//0 - res<->res; 1 - res<->plauer; 2 - buy artifact; 3 - sell artifact
r1, r2; //suggested amounts of traded resources
AdventureMapButton *ok, *max, *deal;
CSlider *slider; //for choosing amount to be exchanged
void activate();
void deactivate();
void show(SDL_Surface * to);
void setMax();
void sliderMoved(int to);
void makeDeal();
void selectionChanged(bool side); //true == left
CMarketplaceWindow(int Mode=0); //c-tor
CMarketplaceWindow(int Mode = RESOURCE_RESOURCE); //c-tor
~CMarketplaceWindow(); //d-tor
void setMode(int mode); //mode setter
void clear();
void setMode(int Mode); //mode setter
void getPositionsFor(std::vector<Rect> &poss, bool Right, EType type) const;
};
class CSystemOptionsWindow : public CIntObject

View File

@ -105,6 +105,11 @@ const int SPELL_LEVELS = 5;
#define BFIELD_HEIGHT (11)
#define BFIELD_SIZE ((BFIELD_WIDTH) * (BFIELD_HEIGHT))
enum EMarketMode
{
RESOURCE_RESOURCE, RESOURCE_PLAYER, CREATURE_RESOURCE, ARTIFACT_RESOURCE
};
//uncomment to make it work
//#define MARK_BLOCKED_POSITIONS
//#define MARK_VISITABLE_POSITIONS

View File

@ -141,6 +141,19 @@ public:
static IShipyard *castFrom(CGObjectInstance *obj);
};
/*class DLL_EXPORT IMarket
{
public:
const CGObjectInstance *o;
IMarket(const CGObjectInstance *O);
virtual bool allowsMode(EMarketMode mode);
virtual float getEfficiency(EMarketMode mode);
static const IMarket *castFrom(const CGObjectInstance *obj);
static IMarket castFrom(CGObjectInstance *obj);
};*/
class DLL_EXPORT CGObjectInstance : public IObjectInterface
{
protected:

View File

@ -2952,6 +2952,31 @@ bool CGameHandler::tradeResources( ui32 val, ui8 player, ui32 id1, ui32 id2 )
return true;
}
bool CGameHandler::sendResources(ui32 val, ui8 player, ui32 r1, ui32 r2)
{
const PlayerState *p2 = gs->getPlayer(r2, false);
if(!p2 || p2->status != PlayerState::INGAME)
{
complain("Dest player must be in game!");
return false;
}
si32 curRes1 = gs->getPlayer(player)->resources[r1], curRes2 = gs->getPlayer(r2)->resources[r1];
val = std::min(si32(val),curRes1);
SetResource sr;
sr.player = player;
sr.resid = r1;
sr.val = curRes1 - val;
sendAndApply(&sr);
sr.player = r2;
sr.val = curRes2 + val;
sendAndApply(&sr);
return true;
}
bool CGameHandler::setFormation( si32 hid, ui8 formation )
{
gs->getHero(hid)-> formation = formation;
@ -3171,8 +3196,8 @@ bool CGameHandler::makeBattleAction( BattleAction &ba )
sendAndApply(&StartAction(ba)); //start shooting
BattleAttack bat;
prepareAttack(bat, curStack, destStack, 0);
bat.flags |= 1;
prepareAttack(bat, curStack, destStack, 0);
sendAndApply(&bat);
if(curStack->valOfBonuses(Bonus::ADDITIONAL_ATTACK) > 0 //if unit shots twice let's make another shot
@ -4414,4 +4439,4 @@ bool CGameHandler::castSpell(const CGHeroInstance *h, int spellID, const int3 &p
sendAndApply(&sm);
return true;
}
}

View File

@ -164,6 +164,7 @@ public:
bool buildBoat( ui32 objid );
bool setFormation( si32 hid, ui8 formation );
bool tradeResources( ui32 val, ui8 player, ui32 id1, ui32 id2 );
bool sendResources(ui32 val, ui8 player, ui32 r1, ui32 r2);
bool assembleArtifacts (si32 heroID, ui16 artifactSlot, bool assemble, ui32 assembleTo);
bool buyArtifact( ui32 hid, si32 aid );
bool swapArtifacts(si32 srcHeroID, si32 destHeroID, ui16 srcSlot, ui16 destSlot);

View File

@ -113,7 +113,16 @@ bool BuyArtifact::applyGh( CGameHandler *gh )
bool TradeOnMarketplace::applyGh( CGameHandler *gh )
{
if(gh->getPlayerAt(c) != player) ERROR_AND_RETURN;
return gh->tradeResources(val,player,r1,r2);
switch(mode)
{
case RESOURCE_RESOURCE:
return gh->tradeResources(val,player,r1,r2);
case RESOURCE_PLAYER:
return gh->sendResources(val, player, r1, r2);
default:
gh->complain("Unknown exchange mode!");
ERROR_AND_RETURN;
}
}
bool SetFormation::applyGh( CGameHandler *gh )