1
0
mirror of https://github.com/vcmi/vcmi.git synced 2025-10-31 00:07:39 +02:00

Mostly finished pregame part of hot-seat mode.

This commit is contained in:
Michał W. Urbańczyk
2010-02-16 16:35:24 +00:00
parent ab75f4b1f8
commit 4035155969
9 changed files with 179 additions and 103 deletions

View File

@@ -51,7 +51,8 @@ void startGame(StartInfo * options);
CGPreGame * CGP;
static const CMapInfo *curMap;
static StartInfo *curOpts;
static int playerColor, playerSerial;
static int playerColor, playerSerial; //if more than one player - applies to the first
static std::vector<std::string> playerNames; // serial id of name <-> player name
static std::string selectedName; //set when game is started/loaded
@@ -211,9 +212,8 @@ CGPreGame::~CGPreGame()
void CGPreGame::openSel( CMenuScreen::EState type )
{
std::vector<std::string> names;
names.push_back(CGI->generaltexth->allTexts[434]);
GH.pushInt(new CSelectionScreen(type, names));
playerNames.push_back(CGI->generaltexth->allTexts[434]); //we have only one player and his name is "Player"
GH.pushInt(new CSelectionScreen(type));
}
void CGPreGame::loadGraphics()
@@ -257,8 +257,7 @@ void CGPreGame::update()
GH.handleEvents();
}
CSelectionScreen::CSelectionScreen( CMenuScreen::EState Type, const std::vector<std::string> &PlayerNames )
:playerNames(PlayerNames)
CSelectionScreen::CSelectionScreen(CMenuScreen::EState Type)
{
OBJ_CONSTRUCTION_CAPTURING_ALL;
IShowActivable::type = BLOCK_ADV_HOTKEYS;
@@ -358,6 +357,7 @@ CSelectionScreen::~CSelectionScreen()
curMap = NULL;
curOpts = NULL;
playerSerial = playerColor = -1;
playerNames.clear();
}
void CSelectionScreen::toggleTab(CIntObject *tab)
@@ -396,6 +396,25 @@ void CSelectionScreen::changeSelection( const CMapInfo *to )
}
}
void setPlayer(PlayerSettings &pset, unsigned player)
{
if(player < playerNames.size())
{
pset.name = playerNames[player];
pset.human = true;
if(playerColor < 0)
{
playerColor = pset.color;
playerSerial = pset.serial;
}
}
else
{
pset.name = CGI->generaltexth->allTexts[468];//Computer
pset.human = false;
}
}
void CSelectionScreen::updateStartInfo( const CMapInfo * to )
{
sInfo.playerInfos.clear();
@@ -405,7 +424,7 @@ void CSelectionScreen::updateStartInfo( const CMapInfo * to )
sInfo.playerInfos.resize(to->playerAmnt);
sInfo.mapname = to->filename;
playerSerial = playerColor = -1;
int placedPlayers = 0;
ui8 placedPlayers = 0;
int serialC=0;
for (int i = 0; i < PLAYER_LIMIT; i++)
@@ -419,22 +438,7 @@ void CSelectionScreen::updateStartInfo( const CMapInfo * to )
PlayerSettings &pset = sInfo.playerInfos[serialC];
pset.color = i;
pset.serial = serialC++;
if (pinfo.canHumanPlay && placedPlayers < playerNames.size())
{
pset.name = playerNames[placedPlayers++];
pset.human = true;
if(playerColor < 0)
{
playerColor = i;
playerSerial = pset.serial;
}
}
else
{
pset.name = CGI->generaltexth->allTexts[468];//Computer
pset.human = false;
}
setPlayer(pset, placedPlayers++);
for (int j = 0; j < F_NUMBER && pset.castle != -1; j++) //we start with none and find matching faction. if more than one, then set to random
{
@@ -1479,22 +1483,77 @@ void OptionsTab::setTurnLength( int npos )
void OptionsTab::flagPressed( int player )
{
if(player == playerSerial) //that color is already selected, no action needed
return;
static std::pair<int, int> playerToRestore(-1, -1); //<color serial, player name serial>
PlayerSettings &s = curOpts->playerInfos[player],
&old = curOpts->playerInfos[playerSerial];
PlayerSettings &clicked = curOpts->playerInfos[player];
PlayerSettings *old = NULL;
std::swap(old.human, s.human);
std::swap(old.name, s.name);
playerColor = s.color;
if(playerNames.size() == 1) //single player -> swap
{
if(player == playerSerial) //that color is already selected, no action needed
return;
if(!entries[playerSerial]->fixedHero)
old.hero = -1;
playerSerial = player;
entries[s.serial]->selectButtons();
entries[old.serial]->selectButtons();
old = &curOpts->playerInfos[playerSerial];
std::swap(old->human, clicked.human);
std::swap(old->name, clicked.name);
playerColor = clicked.color;
playerSerial = player;
}
else
{
//identify clicked player
int curNameID = clicked.human
? vstd::findPos(playerNames, clicked.name)
: -1;
if(curNameID >= 0 && playerToRestore.second == curNameID) //player to restore is about to being replaced -> put him back to the old place
{
PlayerSettings &restPos = curOpts->playerInfos[playerToRestore.first];
setPlayer(restPos, playerToRestore.second);
playerToRestore.first = playerToRestore.second = 0;
}
//who will be put here?
if(curNameID < 0) //if possible replace computer with unallocated player
{
for(int i = 0; i < playerNames.size(); i++)
{
if(!curOpts->getPlayersSettings(playerNames[i]))
{
curNameID = i-1; //-1 because it'll incremented soon
break;
}
}
}
setPlayer(clicked, ++curNameID); //simply next player
//if that player was somewhere else, we need to replace him with computer
if(curNameID < playerNames.size())
{
for(std::vector<PlayerSettings>::iterator i = curOpts->playerInfos.begin(); i != curOpts->playerInfos.end(); i++)
{
if(i->serial != player && i->name == playerNames[curNameID])
{
assert(i->human);
playerToRestore.first = i->serial;
playerToRestore.second = vstd::findPos(playerNames, i->name);
setPlayer(*i, -1); //set computer
old = &*i;
break;
}
}
}
}
entries[clicked.serial]->selectButtons();
if(old)
{
entries[old->serial]->selectButtons();
if(!entries[playerSerial]->fixedHero)
old->hero = -1;
}
GH.totalRedraw();
}
@@ -1991,13 +2050,12 @@ CHotSeatPlayers::CHotSeatPlayers(const std::string &firstPlayer)
void CHotSeatPlayers::enterSelectionScreen()
{
std::vector<std::string> playerNames;
for(int i = 0; i < ARRAY_COUNT(txt); i++)
if(txt[i]->text.length())
playerNames.push_back(txt[i]->text);
GH.popInts(2);
GH.pushInt(new CSelectionScreen(CMenuScreen::newGame, playerNames));
GH.pushInt(new CSelectionScreen(CMenuScreen::newGame));
}
CBonusSelection::CBonusSelection( const CCampaign * ourCampaign, int whichMap )

View File

@@ -206,9 +206,8 @@ public:
const CMapInfo *current;
StartInfo sInfo;
CIntObject *curTab;
std::vector<std::string> playerNames;
CSelectionScreen(CMenuScreen::EState Type, const std::vector<std::string> &PlayerNames = std::vector<std::string>());
CSelectionScreen(CMenuScreen::EState Type);
~CSelectionScreen();
void toggleTab(CIntObject *tab);
void changeSelection(const CMapInfo *to);

View File

@@ -156,7 +156,7 @@ void CGuiHandler::handleEvent(SDL_Event *sEvent)
}
bool keysCaptured = false;
for(std::list<CIntObject*>::iterator i=keyinterested.begin(); i != keyinterested.end();i++)
for(std::list<CIntObject*>::iterator i=keyinterested.begin(); i != keyinterested.end() && current; i++)
{
if((*i)->captureAllKeys)
{
@@ -166,7 +166,7 @@ void CGuiHandler::handleEvent(SDL_Event *sEvent)
}
std::list<CIntObject*> miCopy = keyinterested;
for(std::list<CIntObject*>::iterator i=miCopy.begin(); i != miCopy.end();i++)
for(std::list<CIntObject*>::iterator i=miCopy.begin(); i != miCopy.end() && current; i++)
if(vstd::contains(keyinterested,*i) && (!keysCaptured || (*i)->captureAllKeys))
(**i).keyPressed(key);
}
@@ -183,7 +183,7 @@ void CGuiHandler::handleEvent(SDL_Event *sEvent)
if(lastClick == sEvent->motion && (SDL_GetTicks() - lastClickTime) < 300)
{
std::list<CIntObject*> hlp = doubleClickInterested;
for(std::list<CIntObject*>::iterator i=hlp.begin(); i != hlp.end();i++)
for(std::list<CIntObject*>::iterator i=hlp.begin(); i != hlp.end() && current; i++)
{
if(!vstd::contains(doubleClickInterested,*i)) continue;
if (isItIn(&(*i)->pos,sEvent->motion.x,sEvent->motion.y))
@@ -198,7 +198,7 @@ void CGuiHandler::handleEvent(SDL_Event *sEvent)
lastClickTime = SDL_GetTicks();
std::list<CIntObject*> hlp = lclickable;
for(std::list<CIntObject*>::iterator i=hlp.begin(); i != hlp.end();i++)
for(std::list<CIntObject*>::iterator i=hlp.begin(); i != hlp.end() && current; i++)
{
if(!vstd::contains(lclickable,*i)) continue;
if (isItIn(&(*i)->pos,sEvent->motion.x,sEvent->motion.y))
@@ -212,7 +212,7 @@ void CGuiHandler::handleEvent(SDL_Event *sEvent)
else if (sEvent->button.button == SDL_BUTTON_RIGHT)
{
std::list<CIntObject*> hlp = rclickable;
for(std::list<CIntObject*>::iterator i=hlp.begin(); i != hlp.end();i++)
for(std::list<CIntObject*>::iterator i=hlp.begin(); i != hlp.end() && current; i++)
{
if(!vstd::contains(rclickable,*i)) continue;
if (isItIn(&(*i)->pos,sEvent->motion.x,sEvent->motion.y))
@@ -226,7 +226,7 @@ void CGuiHandler::handleEvent(SDL_Event *sEvent)
else if(sEvent->button.button == SDL_BUTTON_WHEELDOWN || sEvent->button.button == SDL_BUTTON_WHEELUP)
{
std::list<CIntObject*> hlp = wheelInterested;
for(std::list<CIntObject*>::iterator i=hlp.begin(); i != hlp.end();i++)
for(std::list<CIntObject*>::iterator i=hlp.begin(); i != hlp.end() && current; i++)
{
if(!vstd::contains(wheelInterested,*i)) continue;
(*i)->wheelScrolled(sEvent->button.button == SDL_BUTTON_WHEELDOWN, isItIn(&(*i)->pos,sEvent->motion.x,sEvent->motion.y));
@@ -236,7 +236,7 @@ void CGuiHandler::handleEvent(SDL_Event *sEvent)
else if ((sEvent->type==SDL_MOUSEBUTTONUP) && (sEvent->button.button == SDL_BUTTON_LEFT))
{
std::list<CIntObject*> hlp = lclickable;
for(std::list<CIntObject*>::iterator i=hlp.begin(); i != hlp.end();i++)
for(std::list<CIntObject*>::iterator i=hlp.begin(); i != hlp.end() && current; i++)
{
if(!vstd::contains(lclickable,*i)) continue;
prev = (*i)->pressedL;
@@ -252,7 +252,7 @@ void CGuiHandler::handleEvent(SDL_Event *sEvent)
else if ((sEvent->type==SDL_MOUSEBUTTONUP) && (sEvent->button.button == SDL_BUTTON_RIGHT))
{
std::list<CIntObject*> hlp = rclickable;
for(std::list<CIntObject*>::iterator i=hlp.begin(); i != hlp.end();i++)
for(std::list<CIntObject*>::iterator i=hlp.begin(); i != hlp.end() && current; i++)
{
if(!vstd::contains(rclickable,*i)) continue;
prev = (*i)->pressedR;

View File

@@ -460,7 +460,7 @@ public:
//objs to blit
std::vector<IShowable*> objsToBlit;
SDL_Event * current; //current event
SDL_Event * current; //current event - can be set to NULL to stop handling event
IUpdateable *curInt;
Point lastClick;

View File

@@ -62,7 +62,8 @@ using namespace CSDL_Ext;
extern std::queue<SDL_Event*> events;
extern boost::mutex eventsM;
CTextInput * CTextInput::inputWithFocus;
std::list<CFocusable*> CFocusable::focusables;
CFocusable * CFocusable::inputWithFocus;
#undef min
#undef max
@@ -5174,8 +5175,9 @@ void CGStatusBar::init()
}
CTextInput::CTextInput( const Rect &Pos, const Point &bgOffset, const std::string &bgName, const CFunctionList<void(const std::string &)> &CB )
:cb(CB), focus(false)
:cb(CB)
{
focus = false;
pos += Pos;
OBJ_CONSTRUCTION;
bg = new CPicture(bgName, bgOffset.x, bgOffset.y);
@@ -5184,8 +5186,8 @@ CTextInput::CTextInput( const Rect &Pos, const Point &bgOffset, const std::strin
}
CTextInput::CTextInput(const Rect &Pos, SDL_Surface *srf)
: focus(false)
{
focus = false;
pos += Pos;
OBJ_CONSTRUCTION;
bg = new CPicture(Pos, 0, true);
@@ -5213,7 +5215,16 @@ void CTextInput::clickLeft( tribool down, bool previousState )
void CTextInput::keyPressed( const SDL_KeyboardEvent & key )
{
if(!focus || key.state != SDL_PRESSED) return;
if(!focus || key.state != SDL_PRESSED)
return;
if(key.keysym.sym == SDLK_TAB)
{
moveFocus();
GH.current = NULL;
return;
}
switch(key.keysym.sym)
{
case SDLK_BACKSPACE:
@@ -5241,11 +5252,21 @@ void CTextInput::setText( const std::string &nText, bool callCb )
CTextInput::~CTextInput()
{
if(inputWithFocus == this)
inputWithFocus = NULL;
}
void CTextInput::giveFocus()
CFocusable::CFocusable()
{
focusables.push_back(this);
}
CFocusable::~CFocusable()
{
if(inputWithFocus == this)
inputWithFocus = NULL;
focusables -= this;
}
void CFocusable::giveFocus()
{
if(inputWithFocus)
{
@@ -5257,3 +5278,20 @@ void CTextInput::giveFocus()
inputWithFocus = this;
redraw();
}
void CFocusable::moveFocus()
{
std::list<CFocusable*>::iterator i = vstd::find(focusables, this),
ourIt = i;
for(i++; i != ourIt; i++)
{
if(i == focusables.end())
i = focusables.begin();
if((*i)->active)
{
(*i)->giveFocus();
break;;
}
}
}

View File

@@ -261,7 +261,7 @@ public:
};
class CLabel
: public CIntObject
: public virtual CIntObject
{
public:
enum EAlignment {TOPLEFT, CENTER, BOTTOMRIGHT} alignment;
@@ -296,12 +296,26 @@ public:
~CGStatusBar();
};
class CFocusable
: public virtual CIntObject
{
public:
bool focus; //only one focusable control can have focus at one moment
class CTextInput : public CLabel
void giveFocus(); //captures focus
void moveFocus(); //moves focus to next active control (may be used for tab switching)
static std::list<CFocusable*> focusables; //all existing objs
static CFocusable *inputWithFocus; //who has focus now
CFocusable();
~CFocusable();
};
class CTextInput
: public CLabel, public CFocusable
{
public:
CFunctionList<void(const std::string &)> cb;
bool focus; //only one text input may have focus at once
void setText(const std::string &nText, bool callCb = false);
@@ -311,8 +325,6 @@ public:
void showAll(SDL_Surface * to);
void clickLeft(tribool down, bool previousState);
void keyPressed(const SDL_KeyboardEvent & key);
void giveFocus();
static CTextInput *inputWithFocus;
};
class CList : public CIntObject