- added new in-game popup menu and new ability to switch teams in game (turned off by default in advanced settings)

This commit is contained in:
Mark Vejvoda 2011-09-21 06:51:28 +00:00
parent c4f4e28ca6
commit 7d53df698a
30 changed files with 1087 additions and 21 deletions

View File

@ -157,6 +157,42 @@ void Ai::update() {
if(SystemFlags::getSystemSettingType(SystemFlags::debugPerformance).enabled && chrono.getMillis() > 0) SystemFlags::OutputDebug(SystemFlags::debugPerformance,"In [%s::%s Line: %d] took msecs: %lld [START]\n",__FILE__,__FUNCTION__,__LINE__,chrono.getMillis());
if(aiInterface->getMyFaction()->getFirstSwitchTeamVote() != NULL) {
const SwitchTeamVote *vote = aiInterface->getMyFaction()->getFirstSwitchTeamVote();
aiInterface->getMyFaction()->setCurrentSwitchTeamVoteFactionIndex(vote->factionIndex);
factionSwitchTeamRequestCount[vote->factionIndex]++;
int factionSwitchTeamRequestCountCurrent = factionSwitchTeamRequestCount[vote->factionIndex];
//int allowJoinTeam = random.randRange(0, 100);
srand(time(NULL) + aiInterface->getMyFaction()->getIndex());
int allowJoinTeam = rand() % 100;
SwitchTeamVote *voteResult = aiInterface->getMyFaction()->getSwitchTeamVote(vote->factionIndex);
voteResult->voted = true;
voteResult->allowSwitchTeam = false;
const GameSettings *settings = aiInterface->getWorld()->getGameSettings();
// Can only ask the AI player 2 times max per game
if(factionSwitchTeamRequestCountCurrent <= 2) {
// x% chance the AI will answer yes
if(settings->getAiAcceptSwitchTeamPercentChance() >= 100) {
voteResult->allowSwitchTeam = true;
}
else if(settings->getAiAcceptSwitchTeamPercentChance() <= 0) {
voteResult->allowSwitchTeam = false;
}
else {
voteResult->allowSwitchTeam = (allowJoinTeam >= (100 - settings->getAiAcceptSwitchTeamPercentChance()));
}
}
if(SystemFlags::getSystemSettingType(SystemFlags::debugSystem).enabled) SystemFlags::OutputDebug(SystemFlags::debugSystem,"In [%s::%s Line: %d] AI for faction# %d voted %s [%d] factionSwitchTeamRequestCountCurrent [%d] settings->getAiAcceptSwitchTeamPercentChance() [%d]\n",__FILE__,__FUNCTION__,__LINE__,aiInterface->getMyFaction()->getIndex(),(voteResult->allowSwitchTeam ? "Yes" : "No"),allowJoinTeam,factionSwitchTeamRequestCountCurrent,settings->getAiAcceptSwitchTeamPercentChance());
//printf("AI for faction# %d voted %s [%d] factionSwitchTeamRequestCountCurrent [%d]\n",aiInterface->getMyFaction()->getIndex(),(voteResult->allowSwitchTeam ? "Yes" : "No"),allowJoinTeam,factionSwitchTeamRequestCountCurrent);
aiInterface->giveCommandSwitchTeamVote(aiInterface->getMyFaction(),voteResult);
}
//process ai rules
for(int ruleIdx = 0; ruleIdx < aiRules.size(); ++ruleIdx) {
AiRule *rule = aiRules[ruleIdx];
@ -412,7 +448,7 @@ void Ai::addExpansion(const Vec2i &pos){
}
}
Vec2i Ai::getRandomHomePosition(){
Vec2i Ai::getRandomHomePosition() {
if(expansionPositions.empty() || random.randRange(0, 1) == 0){
return aiInterface->getHomeLocation();

View File

@ -144,6 +144,7 @@ private:
Tasks tasks;
Positions expansionPositions;
RandomGen random;
std::map<int,int> factionSwitchTeamRequestCount;
bool getAdjacentUnits(std::map<float, std::map<int, const Unit *> > &signalAdjacentUnits, const Unit *unit);

View File

@ -117,6 +117,13 @@ bool AiInterface::executeCommandOverNetwork() {
return faction->getCpuControl(enableServerControlledAI,isNetworkGame,role);
}
CommandResult AiInterface::giveCommandSwitchTeamVote(const Faction* faction, SwitchTeamVote *vote) {
assert(this->gameSettings != NULL);
commander->trySwitchTeamVote(faction,vote);
return crSuccess;
}
CommandResult AiInterface::giveCommand(int unitIndex, CommandClass commandClass, const Vec2i &pos){
assert(this->gameSettings != NULL);

View File

@ -70,6 +70,8 @@ public:
CommandResult giveCommand(int unitIndex, const CommandType *commandType, Unit *u= NULL);
CommandResult giveCommand(const Unit *unit, const CommandType *commandType, const Vec2i &pos, int unitGroupCommandId);
CommandResult giveCommandSwitchTeamVote(const Faction* faction, SwitchTeamVote *vote);
//get data
const ControlType getControlType();
int getMapMaxPlayers();

View File

@ -646,5 +646,123 @@ int GraphicScrollBar::getThickness() const {
return horizontal?getH():getW();
}
// ===========================================================
// class PopupMenu
// ===========================================================
const int PopupMenu::defH= 240;
const int PopupMenu::defW= 350;
PopupMenu::PopupMenu() {
h= defH;
w= defW;
}
PopupMenu::~PopupMenu() {
}
void PopupMenu::init(string menuHeader,std::vector<string> menuItems) {
header = menuHeader;
font= CoreData::getInstance().getMenuFontNormal();
font3D= CoreData::getInstance().getMenuFontNormal3D();
buttons.clear();
const Metrics &metrics= Metrics::getInstance();
x= (metrics.getVirtualW()-w)/2;
y= (metrics.getVirtualH()-h)/2;
int maxButtonWidth = -1;
for(unsigned int i = 0; i < menuItems.size(); ++i) {
int currentButtonWidth = -1;
if(font3D != NULL) {
FontMetrics *fontMetrics= font3D->getMetrics();
currentButtonWidth = fontMetrics->getTextWidth(menuItems[i]);
}
else {
FontMetrics *fontMetrics= font->getMetrics();
currentButtonWidth = fontMetrics->getTextWidth(menuItems[i]);
}
if(maxButtonWidth < 0 || currentButtonWidth > maxButtonWidth) {
maxButtonWidth = currentButtonWidth + 5;
}
}
int textHeight = 30;
int yStartOffset = y + (h/2) + (textHeight/2);
for(unsigned int i = 0; i < menuItems.size(); ++i) {
GraphicButton button;
button.init(x+(w-maxButtonWidth)/2, yStartOffset - (i*textHeight));
button.setText(menuItems[i]);
button.setW(maxButtonWidth);
buttons.push_back(button);
}
}
void PopupMenu::setX(int x) {
this->x= x;
for(unsigned int i = 0; i < buttons.size(); ++i) {
GraphicButton &button = buttons[i];
button.init(x+(w-GraphicButton::defW)/4, y+25 + (i*25));
}
}
void PopupMenu::setY(int y) {
this->y= y;
for(unsigned int i = 0; i < buttons.size(); ++i) {
GraphicButton &button = buttons[i];
button.init(x+(w-GraphicButton::defW)/4, y+25 + (i*25));
}
}
bool PopupMenu::mouseMove(int x, int y){
if(this->getVisible() == false) {
return false;
}
for(unsigned int i = 0; i < buttons.size(); ++i) {
GraphicButton &button = buttons[i];
if(button.mouseMove(x, y)) {
return true;
}
}
return false;
}
bool PopupMenu::mouseClick(int x, int y) {
if(this->getVisible() == false) {
return false;
}
for(unsigned int i = 0; i < buttons.size(); ++i) {
GraphicButton &button = buttons[i];
if(button.mouseClick(x, y)) {
return true;
}
}
return false;
}
std::pair<int,string> PopupMenu::mouseClickedMenuItem(int x, int y) {
std::pair<int,string> result;
for(unsigned int i = 0; i < buttons.size(); ++i) {
GraphicButton &button = buttons[i];
if(button.mouseClick(x, y)) {
result.first = i;
result.second = buttons[i].getText();
break;
}
}
return result;
}
}}//end namespace

View File

@ -336,5 +336,36 @@ public:
int getVisibleCompPosEnd() const {return visibleCompPosEnd;}
};
// ===========================================================
// class PopupMenu
// ===========================================================
class PopupMenu: public GraphicComponent {
public:
static const int defH;
static const int defW;
private:
std::vector<GraphicButton> buttons;
string header;
public:
PopupMenu();
~PopupMenu();
void init(string menuHeader, std::vector<string> menuItems);
std::vector<GraphicButton> & getMenuItems() {return buttons;}
string getHeader() const {return header;}
virtual void setX(int x);
virtual void setY(int y);
void setHeader(string header) {this->header= header;}
virtual bool mouseMove(int x, int y);
virtual bool mouseClick(int x, int y);
std::pair<int,string> mouseClickedMenuItem(int x, int y);
};
}}//end namespace
#endif

View File

@ -459,6 +459,15 @@ void Commander::trySetMeetingPoint(const Unit* unit, const Vec2i &pos) const {
pushNetworkCommand(&command);
}
void Commander::trySwitchTeam(const Faction* faction, int teamIndex) const {
NetworkCommand command(this->world,nctSwitchTeam, faction->getIndex(), teamIndex);
pushNetworkCommand(&command);
}
void Commander::trySwitchTeamVote(const Faction* faction, SwitchTeamVote *vote) const {
NetworkCommand command(this->world,nctSwitchTeamVote, faction->getIndex(), vote->factionIndex,Vec2i(0),vote->allowSwitchTeam);
pushNetworkCommand(&command);
}
// ==================== PRIVATE ====================
@ -660,6 +669,138 @@ void Commander::giveNetworkCommand(NetworkCommand* networkCommand) const {
if(SystemFlags::getSystemSettingType(SystemFlags::debugSystem).enabled) SystemFlags::OutputDebug(SystemFlags::debugSystem,"In [%s::%s Line: %d] found nctSetMeetingPoint\n",__FILE__,__FUNCTION__,__LINE__);
}
break;
case nctSwitchTeam: {
if(SystemFlags::getSystemSettingType(SystemFlags::debugSystem).enabled) SystemFlags::OutputDebug(SystemFlags::debugSystem,"In [%s::%s Line: %d] found nctSetMeetingPoint\n",__FILE__,__FUNCTION__,__LINE__);
int factionIndex = networkCommand->getUnitId();
int newTeam = networkCommand->getCommandTypeId();
// Auto join empty team or ask players to join
bool autoJoinTeam = true;
for(int i = 0; i < world->getFactionCount(); ++i) {
if(newTeam == world->getFaction(i)->getTeam()) {
autoJoinTeam = false;
break;
}
}
if(autoJoinTeam == true) {
Faction *faction = world->getFaction(factionIndex);
int oldTeam = faction->getTeam();
faction->setTeam(newTeam);
GameSettings *settings = world->getGameSettingsPtr();
settings->setTeam(factionIndex,newTeam);
if(factionIndex == world->getThisFactionIndex()) {
world->setThisTeamIndex(newTeam);
GameNetworkInterface *gameNetworkInterface= NetworkManager::getInstance().getGameNetworkInterface();
if(gameNetworkInterface != NULL) {
char szMsg[1024]="";
sprintf(szMsg,"Player %s switched from team# %d to team# %d.",settings->getNetworkPlayerName(factionIndex).c_str(),oldTeam,newTeam);
gameNetworkInterface->sendTextMessage(szMsg,-1, true, "");
}
}
}
else {
for(int i = 0; i < world->getFactionCount(); ++i) {
if(newTeam == world->getFaction(i)->getTeam()) {
Faction *faction = world->getFaction(factionIndex);
SwitchTeamVote vote;
vote.factionIndex = factionIndex;
vote.allowSwitchTeam = false;
vote.oldTeam = faction->getTeam();
vote.newTeam = newTeam;
vote.voted = false;
world->getFaction(i)->setSwitchTeamVote(vote);
}
}
}
if(SystemFlags::getSystemSettingType(SystemFlags::debugPerformance).enabled && chrono.getMillis() > 0) SystemFlags::OutputDebug(SystemFlags::debugPerformance,"In [%s::%s Line: %d] took msecs: %lld [after unit->setMeetingPos]\n",__FILE__,__FUNCTION__,__LINE__,chrono.getMillis());
if(SystemFlags::getSystemSettingType(SystemFlags::debugSystem).enabled) SystemFlags::OutputDebug(SystemFlags::debugSystem,"In [%s::%s Line: %d] found nctSetMeetingPoint\n",__FILE__,__FUNCTION__,__LINE__);
}
break;
case nctSwitchTeamVote: {
if(SystemFlags::getSystemSettingType(SystemFlags::debugSystem).enabled) SystemFlags::OutputDebug(SystemFlags::debugSystem,"In [%s::%s Line: %d] found nctSetMeetingPoint\n",__FILE__,__FUNCTION__,__LINE__);
int votingFactionIndex = networkCommand->getUnitId();
int factionIndex = networkCommand->getCommandTypeId();
bool allowSwitchTeam = networkCommand->getUnitTypeId();
Faction *faction = world->getFaction(votingFactionIndex);
SwitchTeamVote *vote = faction->getSwitchTeamVote(factionIndex);
if(vote == NULL) {
throw runtime_error("vote == NULL");
}
vote->voted = true;
vote->allowSwitchTeam = allowSwitchTeam;
// Join the new team if > 50 % said yes
int newTeamTotalMemberCount=0;
int newTeamVotedYes=0;
int newTeamVotedNo=0;
for(int i = 0; i < world->getFactionCount(); ++i) {
if(vote->newTeam == world->getFaction(i)->getTeam()) {
newTeamTotalMemberCount++;
SwitchTeamVote *teamVote = world->getFaction(i)->getSwitchTeamVote(factionIndex);
if(teamVote != NULL && teamVote->voted == true) {
if(teamVote->allowSwitchTeam == true) {
newTeamVotedYes++;
}
else {
newTeamVotedNo++;
}
}
}
}
// If > 50% of team vote yes, switch th eplayers team
if(newTeamVotedYes / newTeamTotalMemberCount > 0.5) {
Faction *faction = world->getFaction(factionIndex);
int oldTeam = faction->getTeam();
faction->setTeam(vote->newTeam);
GameSettings *settings = world->getGameSettingsPtr();
settings->setTeam(factionIndex,vote->newTeam);
if(factionIndex == world->getThisFactionIndex()) {
world->setThisTeamIndex(vote->newTeam);
GameNetworkInterface *gameNetworkInterface= NetworkManager::getInstance().getGameNetworkInterface();
if(gameNetworkInterface != NULL) {
char szMsg[1024]="";
sprintf(szMsg,"Player %s switched from team# %d to team# %d.",settings->getNetworkPlayerName(factionIndex).c_str(),oldTeam,vote->newTeam);
gameNetworkInterface->sendTextMessage(szMsg,-1, true, "");
}
}
}
else if(newTeamTotalMemberCount == (newTeamVotedYes + newTeamVotedNo)) {
if(factionIndex == world->getThisFactionIndex()) {
GameSettings *settings = world->getGameSettingsPtr();
Faction *faction = world->getFaction(factionIndex);
int oldTeam = faction->getTeam();
GameNetworkInterface *gameNetworkInterface= NetworkManager::getInstance().getGameNetworkInterface();
if(gameNetworkInterface != NULL) {
char szMsg[1024]="";
sprintf(szMsg,"Player %s was denied the request to switch from team# %d to team# %d.",settings->getNetworkPlayerName(factionIndex).c_str(),oldTeam,vote->newTeam);
gameNetworkInterface->sendTextMessage(szMsg,-1, true, "");
}
}
}
if(SystemFlags::getSystemSettingType(SystemFlags::debugPerformance).enabled && chrono.getMillis() > 0) SystemFlags::OutputDebug(SystemFlags::debugPerformance,"In [%s::%s Line: %d] took msecs: %lld [after unit->setMeetingPos]\n",__FILE__,__FUNCTION__,__LINE__,chrono.getMillis());
if(SystemFlags::getSystemSettingType(SystemFlags::debugSystem).enabled) SystemFlags::OutputDebug(SystemFlags::debugSystem,"In [%s::%s Line: %d] found nctSetMeetingPoint\n",__FILE__,__FUNCTION__,__LINE__);
}
break;
default:
assert(false);
}

View File

@ -34,6 +34,7 @@ class Command;
class CommandType;
class NetworkCommand;
class Game;
class SwitchTeamVote;
// =====================================================
// class Commander
@ -98,6 +99,9 @@ public:
CommandResult tryGiveCommand(const Selection *selection, const Vec2i &pos, const Unit *targetUnit= NULL, bool tryQueue = false, int unitCommandGroupId = -1) const;
CommandResult tryCancelCommand(const Selection *selection) const;
void trySetMeetingPoint(const Unit* unit, const Vec2i &pos) const;
void trySwitchTeam(const Faction* faction, int teamIndex) const;
void trySwitchTeamVote(const Faction* faction, SwitchTeamVote *vote) const;
CommandResult pushNetworkCommand(const NetworkCommand* networkCommand) const;
//void giveNetworkCommandSpecial(const NetworkCommand* networkCommand) const;

View File

@ -42,6 +42,9 @@ Game *thisGamePtr = NULL;
const float PHOTO_MODE_MAXHEIGHT = 500.0;
const int CREATE_NEW_TEAM = -100;
const int CANCEL_SWITCH_TEAM = -1;
Game::Game() : ProgramState(NULL) {
if(SystemFlags::VERBOSE_MODE_ENABLED) printf("In [%s::%s Line: %d]\n",__FILE__,__FUNCTION__,__LINE__);
originalDisplayMsgCallback = NULL;
@ -83,6 +86,10 @@ Game::Game() : ProgramState(NULL) {
withRainEffect=false;
program=NULL;
gameStarted=false;
switchTeamConfirmMessageBox.setEnabled(false);
exitGamePopupMenuIndex = -1;
joinTeamPopupMenuIndex = -1;
}
Game::Game(Program *program, const GameSettings *gameSettings):
@ -110,6 +117,10 @@ Game::Game(Program *program, const GameSettings *gameSettings):
originalDisplayMsgCallback = NULL;
thisGamePtr = this;
switchTeamConfirmMessageBox.setEnabled(false);
exitGamePopupMenuIndex = -1;
joinTeamPopupMenuIndex = -1;
this->gameSettings= *gameSettings;
scrollSpeed = Config::getInstance().getFloat("UiScrollSpeed","1.5");
photoModeEnabled = Config::getInstance().getBool("PhotoMode","false");
@ -879,6 +890,26 @@ void Game::init(bool initForPreviewOnly)
if(SystemFlags::getSystemSettingType(SystemFlags::debugPathFinder).enabled) SystemFlags::OutputDebug(SystemFlags::debugPathFinder,"================ STARTING GAME ================\n");
if(SystemFlags::getSystemSettingType(SystemFlags::debugPathFinder).enabled) SystemFlags::OutputDebug(SystemFlags::debugPathFinder,"PathFinderType: %s\n", (getGameSettings()->getPathFinderType() ? "RoutePlanner" : "PathFinder"));
//PopupMenu popupMenu;
std::vector<string> menuItems;
menuItems.push_back(lang.get("ExitGame?"));
exitGamePopupMenuIndex = menuItems.size()-1;
if((gameSettings.getFlagTypes1() & ft1_allow_team_switching) == ft1_allow_team_switching) {
menuItems.push_back(lang.get("JoinOtherTeam"));
joinTeamPopupMenuIndex = menuItems.size()-1;
}
menuItems.push_back(lang.get("Exit"));
popupMenu.setW(200);
popupMenu.setH(200);
popupMenu.init(lang.get("GameMenuTitle"),menuItems);
popupMenu.setEnabled(false);
popupMenu.setVisible(false);
popupMenuSwitchTeams.setEnabled(false);
popupMenuSwitchTeams.setVisible(false);
gameStarted = true;
if(SystemFlags::getSystemSettingType(SystemFlags::debugSystem).enabled) SystemFlags::OutputDebug(SystemFlags::debugSystem,"In [%s::%s Line: %d] ==== START GAME ==== getCurrentPixelByteCount() = %llu\n",__FILE__,__FUNCTION__,__LINE__,(long long unsigned int)renderer.getCurrentPixelByteCount());
@ -904,6 +935,20 @@ void Game::update() {
return;
}
if(world.getThisFaction()->getFirstSwitchTeamVote() != NULL) {
const SwitchTeamVote *vote = world.getThisFaction()->getFirstSwitchTeamVote();
GameSettings *settings = world.getGameSettingsPtr();
char szBuf[1024]="";
sprintf(szBuf,"Allow player [%s] to join your team\n(changing from team# %d to team# %d)?",settings->getNetworkPlayerName(vote->factionIndex).c_str(),vote->oldTeam,vote->newTeam);
Lang &lang= Lang::getInstance();
switchTeamConfirmMessageBox.setText(szBuf);
switchTeamConfirmMessageBox.init(lang.get("Yes"), lang.get("No"));
switchTeamConfirmMessageBox.setEnabled(true);
world.getThisFactionPtr()->setCurrentSwitchTeamVoteFactionIndex(vote->factionIndex);
}
//misc
updateFps++;
mouse2d= (mouse2d+1) % Renderer::maxMouse2dAnim;
@ -1173,6 +1218,24 @@ void Game::tick() {
// ==================== events ====================
int Game::getFirstUnusedTeamNumber() {
std::map<int,bool> uniqueTeamNumbersUsed;
for(unsigned int i = 0; i < world.getFactionCount(); ++i) {
Faction *faction = world.getFaction(i);
uniqueTeamNumbersUsed[faction->getTeam()]=true;
}
int result = -1;
for(int i = 0; i < GameConstants::maxPlayers; ++i) {
if(uniqueTeamNumbersUsed.find(i) == uniqueTeamNumbersUsed.end()) {
result = i;
break;
}
}
return result;
}
void Game::mouseDownLeft(int x, int y) {
try {
if(gameStarted == false) {
@ -1185,6 +1248,106 @@ void Game::mouseDownLeft(int x, int y) {
NetworkManager &networkManager= NetworkManager::getInstance();
bool messageBoxClick= false;
if(popupMenu.mouseClick(x, y)) {
std::pair<int,string> result = popupMenu.mouseClickedMenuItem(x, y);
//printf("In popup callback menuItemSelected [%s] menuIndexSelected = %d\n",result.second.c_str(),result.first);
popupMenu.setEnabled(false);
popupMenu.setVisible(false);
// Exit game
if(result.first == exitGamePopupMenuIndex) {
showMessageBox(Lang::getInstance().get("ExitGame?"), "", true);
}
else if(result.first == joinTeamPopupMenuIndex) {
switchTeamIndexMap.clear();
std::map<int,bool> uniqueTeamNumbersUsed;
std::vector<string> menuItems;
for(unsigned int i = 0; i < world.getFactionCount(); ++i) {
Faction *faction = world.getFaction(i);
if(uniqueTeamNumbersUsed.find(faction->getTeam()) == uniqueTeamNumbersUsed.end()) {
uniqueTeamNumbersUsed[faction->getTeam()] = true;
}
if(world.getThisFaction()->getIndex() != faction->getIndex() &&
world.getThisFaction()->getTeam() != faction->getTeam()) {
char szBuf[1024]="";
sprintf(szBuf,"Join player #%d - %s on Team: %d",faction->getIndex(),this->gameSettings.getNetworkPlayerName(i).c_str(),faction->getTeam());
menuItems.push_back(szBuf);
switchTeamIndexMap[menuItems.size()-1] = faction->getTeam();
}
}
if(uniqueTeamNumbersUsed.size() < 8) {
menuItems.push_back("Create New Team");
switchTeamIndexMap[menuItems.size()-1] = CREATE_NEW_TEAM;
}
menuItems.push_back("Cancel");
switchTeamIndexMap[menuItems.size()-1] = CANCEL_SWITCH_TEAM;
popupMenuSwitchTeams.setW(400);
popupMenuSwitchTeams.setH(400);
popupMenuSwitchTeams.init("Switch Teams",menuItems);
popupMenuSwitchTeams.setEnabled(true);
popupMenuSwitchTeams.setVisible(true);
}
}
else if(popupMenuSwitchTeams.mouseClick(x, y)) {
//popupMenuSwitchTeams
std::pair<int,string> result = popupMenuSwitchTeams.mouseClickedMenuItem(x, y);
//printf("In popup callback menuItemSelected [%s] menuIndexSelected = %d\n",result.second.c_str(),result.first);
popupMenuSwitchTeams.setEnabled(false);
popupMenuSwitchTeams.setVisible(false);
bool isNetworkGame = this->gameSettings.isNetworkGame();
int teamIndex = switchTeamIndexMap[result.first];
switch(teamIndex) {
case CREATE_NEW_TEAM:
{
int newTeam = getFirstUnusedTeamNumber();
if(isNetworkGame == true) {
const Faction *faction = world.getThisFaction();
commander.trySwitchTeam(faction,newTeam);
}
else {
const Faction *faction = world.getThisFaction();
commander.trySwitchTeam(faction,newTeam);
}
}
break;
case CANCEL_SWITCH_TEAM:
break;
default:
if(isNetworkGame == true) {
const Faction *faction = world.getThisFaction();
commander.trySwitchTeam(faction,teamIndex);
}
else {
const Faction *faction = world.getThisFaction();
commander.trySwitchTeam(faction,teamIndex);
}
break;
}
}
if(switchTeamConfirmMessageBox.getEnabled() == true) {
int button= -1;
if(switchTeamConfirmMessageBox.mouseClick(x,y,button)) {
switchTeamConfirmMessageBox.setEnabled(false);
SwitchTeamVote *vote = world.getThisFactionPtr()->getSwitchTeamVote(world.getThisFaction()->getCurrentSwitchTeamVoteFactionIndex());
vote->voted = true;
vote->allowSwitchTeam = (button == 1);
const Faction *faction = world.getThisFaction();
commander.trySwitchTeamVote(faction,vote);
}
}
//scrip message box, only if the exit box is not enabled
if( mainMessageBox.getEnabled() == false &&
errorMessageBox.getEnabled() == false &&
@ -1408,6 +1571,9 @@ void Game::mouseMove(int x, int y, const MouseState *ms) {
return;
}
popupMenu.mouseMove(x, y);
popupMenuSwitchTeams.mouseMove(x, y);
const Metrics &metrics = Metrics::getInstance();
mouseX = x;
@ -1467,6 +1633,10 @@ void Game::mouseMove(int x, int y, const MouseState *ms) {
}
}
if(switchTeamConfirmMessageBox.getEnabled() == true) {
switchTeamConfirmMessageBox.mouseMove(x,y);
}
if (mainMessageBox.getEnabled()) {
mainMessageBox.mouseMove(x, y);
}
@ -1672,7 +1842,10 @@ void Game::keyDown(SDL_KeyboardEvent key) {
//exit
//else if(key == configKeys.getCharKey("ExitKey")) {
else if(isKeyPressed(configKeys.getSDLKey("ExitKey"),key, false) == true) {
showMessageBox(lang.get("ExitGame?"), "", true);
//showMessageBox(lang.get("ExitGame?"), "", true);
popupMenu.setEnabled(!popupMenu.getEnabled());
popupMenu.setVisible(popupMenu.getEnabled());
}
//group
//else if(key>='0' && key<'0'+Selection::maxGroups){
@ -2012,6 +2185,10 @@ void Game::render2d(){
//selection
renderer.renderSelectionQuad();
if(switchTeamConfirmMessageBox.getEnabled() == true) {
renderer.renderMessageBox(&switchTeamConfirmMessageBox);
}
//exit message box
if(errorMessageBox.getEnabled()) {
renderer.renderMessageBox(&errorMessageBox);
@ -2043,6 +2220,9 @@ void Game::render2d(){
}
}
renderer.renderPopupMenu(&popupMenu);
renderer.renderPopupMenu(&popupMenuSwitchTeams);
if(program != NULL) program->renderProgramMsgBox();
renderer.renderChatManager(&chatManager);

View File

@ -127,6 +127,15 @@ private:
time_t lastMaxUnitCalcTime;
PopupMenu popupMenu;
PopupMenu popupMenuSwitchTeams;
std::map<int,int> switchTeamIndexMap;
GraphicMessageBox switchTeamConfirmMessageBox;
int exitGamePopupMenuIndex;
int joinTeamPopupMenuIndex;
public:
Game();
Game(Program *program, const GameSettings *gameSettings);
@ -223,6 +232,8 @@ private:
void ReplaceDisconnectedNetworkPlayersWithAI(bool isNetworkGame, NetworkRole role);
void calcCameraMoveX();
void calcCameraMoveZ();
int getFirstUnusedTeamNumber();
};
}}//end namespace

View File

@ -27,8 +27,8 @@ namespace Glest{ namespace Game{
enum FlagTypes1 {
ft1_none = 0x00,
ft1_show_map_resources = 0x01
//ft1_xx = 0x02,
ft1_show_map_resources = 0x01,
ft1_allow_team_switching = 0x02
//ft1_xx = 0x04,
//ft1_xx = 0x08,
//ft1_xx = 0x10,
@ -77,6 +77,8 @@ private:
int32 techCRC;
vector<pair<string,int32> > factionCRCList;
int aiAcceptSwitchTeamPercentChance;
public:
GameSettings() {
@ -111,6 +113,7 @@ public:
tilesetCRC = 0;
techCRC = 0;
factionCRCList.clear();
aiAcceptSwitchTeamPercentChance = 30;
}
// default copy constructor will do fine, and will maintain itself ;)
@ -231,6 +234,9 @@ public:
void setFactionCRCList(vector<pair<string,int32> > value) { factionCRCList = value; }
int getAiAcceptSwitchTeamPercentChance() const { return aiAcceptSwitchTeamPercentChance;}
void setAiAcceptSwitchTeamPercentChance(int value) { aiAcceptSwitchTeamPercentChance = value; }
string toString() const {
string result = "";
@ -275,6 +281,8 @@ public:
result += "factionCRCList name [" + factionCRCList[i].first + "] CRC = " + intToStr(factionCRCList[i].second) + "\n";
}
result += "aiAcceptSwitchTeamPercentChance = " + intToStr(aiAcceptSwitchTeamPercentChance) + "\n";
return result;
}
};

View File

@ -6793,4 +6793,107 @@ void Renderer::renderFPSWhenEnabled(int lastFps) {
}
}
void Renderer::renderPopupMenu(PopupMenu *menu) {
if(menu->getVisible() == false || menu->getEnabled() == false) {
return;
}
//background
glPushAttrib(GL_ENABLE_BIT | GL_CURRENT_BIT);
glEnable(GL_BLEND);
glColor4f(0.0f, 0.0f, 0.0f, 0.8f) ;
glBegin(GL_TRIANGLE_STRIP);
glVertex2i(menu->getX(), menu->getY() + 9 * menu->getH() / 10);
glVertex2i(menu->getX(), menu->getY());
glVertex2i(menu->getX() + menu->getW(), menu->getY() + 9 * menu->getH() / 10);
glVertex2i(menu->getX() + menu->getW(), menu->getY());
glEnd();
glColor4f(0.0f, 0.0f, 0.0f, 0.8f) ;
glBegin(GL_TRIANGLE_STRIP);
glVertex2i(menu->getX(), menu->getY() + menu->getH());
glVertex2i(menu->getX(), menu->getY() + 9 * menu->getH() / 10);
glVertex2i(menu->getX() + menu->getW(), menu->getY() + menu->getH());
glVertex2i(menu->getX() + menu->getW(), menu->getY() + 9 * menu->getH() / 10);
glEnd();
glBegin(GL_LINE_LOOP);
glColor4f(0.5f, 0.5f, 0.5f, 0.25f) ;
glVertex2i(menu->getX(), menu->getY());
glColor4f(0.0f, 0.0f, 0.0f, 0.25f) ;
glVertex2i(menu->getX() + menu->getW(), menu->getY());
glColor4f(0.5f, 0.5f, 0.5f, 0.25f) ;
glVertex2i(menu->getX() + menu->getW(), menu->getY() + menu->getH());
glColor4f(0.25f, 0.25f, 0.25f, 0.25f) ;
glVertex2i(menu->getX(), menu->getY() + menu->getH());
glEnd();
glBegin(GL_LINE_STRIP);
glColor4f(1.0f, 1.0f, 1.0f, 0.25f) ;
glVertex2i(menu->getX(), menu->getY() + 90*menu->getH()/100);
glColor4f(0.5f, 0.5f, 0.5f, 0.25f) ;
glVertex2i(menu->getX()+ menu->getW(), menu->getY() + 90*menu->getH()/100);
glEnd();
glPopAttrib();
Vec4f fontColor;
//if(game!=NULL){
// fontColor=game->getGui()->getDisplay()->getColor();
//}
//else {
// white shadowed is default ( in the menu for example )
fontColor=Vec4f(1.f, 1.f, 1.f, 1.0f);
//}
if(renderText3DEnabled == true) {
//text
renderTextBoundingBox3D(
menu->getHeader(), menu->getFont3D(),fontColor,
menu->getX(), menu->getY()+93*menu->getH()/100,menu->getW(),0,
true,false );
}
else {
//text
renderTextShadow(
menu->getHeader(), menu->getFont(),fontColor,
menu->getX()+15, menu->getY()+93*menu->getH()/100,
true);
}
//buttons
// int maxButtonWidth = -1;
std::vector<GraphicButton> &menuItems = menu->getMenuItems();
// for(unsigned int i = 0; i < menuItems.size(); ++i) {
// GraphicButton *button = &menuItems[i];
// int currentButtonWidth = -1;
// if(renderText3DEnabled == true) {
// FontMetrics *fontMetrics= menu->getFont3D()->getMetrics();
// currentButtonWidth = fontMetrics->getTextWidth(button->getText());
// }
// else {
// FontMetrics *fontMetrics= menu->getFont()->getMetrics();
// currentButtonWidth = fontMetrics->getTextWidth(button->getText());
// }
//
// if(maxButtonWidth < 0 || currentButtonWidth > maxButtonWidth) {
// maxButtonWidth = currentButtonWidth + 5;
// }
// }
for(unsigned int i = 0; i < menuItems.size(); ++i) {
GraphicButton *button = &menuItems[i];
//button->setW(maxButtonWidth);
renderButton(button);
}
}
}}//end namespace

View File

@ -435,6 +435,7 @@ public:
void renderScrollBar(const GraphicScrollBar *sb);
void renderListBox(GraphicListBox *listBox);
void renderMessageBox(GraphicMessageBox *listBox);
void renderPopupMenu(PopupMenu *menu);
//complex rendering
void renderSurface(const int renderFps);

View File

@ -189,6 +189,28 @@ MenuStateConnectedGame::MenuStateConnectedGame(Program *program, MainMenu *mainM
listBoxEnableObserverMode.setEditable(false);
labelEnableObserverMode.setText(lang.get("EnableObserverMode"));
// Allow Switch Team Mode
labelEnableSwitchTeamMode.registerGraphicComponent(containerName,"labelEnableSwitchTeamMode");
labelEnableSwitchTeamMode.init(xoffset+150, aHeadPos+40, 80);
labelEnableSwitchTeamMode.setText(lang.get("EnableSwitchTeamMode"));
listBoxEnableSwitchTeamMode.registerGraphicComponent(containerName,"listBoxEnableSwitchTeamMode");
listBoxEnableSwitchTeamMode.init(xoffset+150, aPos+40, 80);
listBoxEnableSwitchTeamMode.pushBackItem(lang.get("Yes"));
listBoxEnableSwitchTeamMode.pushBackItem(lang.get("No"));
listBoxEnableSwitchTeamMode.setSelectedItemIndex(1);
labelAISwitchTeamAcceptPercent.registerGraphicComponent(containerName,"labelAISwitchTeamAcceptPercent");
labelAISwitchTeamAcceptPercent.init(xoffset+250, aHeadPos+40, 80);
labelAISwitchTeamAcceptPercent.setText(lang.get("AISwitchTeamAcceptPercent"));
listBoxAISwitchTeamAcceptPercent.registerGraphicComponent(containerName,"listBoxAISwitchTeamAcceptPercent");
listBoxAISwitchTeamAcceptPercent.init(xoffset+250, aPos+40, 80);
for(int i = 0; i <= 100; i = i + 10) {
listBoxAISwitchTeamAcceptPercent.pushBackItem(intToStr(i));
}
listBoxAISwitchTeamAcceptPercent.setSelectedItem(intToStr(30));
labelPathFinderType.registerGraphicComponent(containerName,"labelPathFinderType");
labelPathFinderType.init(xoffset+450, aHeadPos, 80);
labelPathFinderType.setText(lang.get("PathFinderType"));
@ -1019,6 +1041,9 @@ void MenuStateConnectedGame::render() {
renderer.renderLabel(&labelEnableObserverMode);
renderer.renderLabel(&labelPathFinderType);
renderer.renderLabel(&labelEnableSwitchTeamMode);
renderer.renderLabel(&labelAISwitchTeamAcceptPercent);
renderer.renderListBox(&listBoxEnableObserverMode);
renderer.renderListBox(&listBoxPathFinderType);
@ -1029,6 +1054,9 @@ void MenuStateConnectedGame::render() {
renderer.renderLabel(&labelNetworkPauseGameForLaggedClients);
renderer.renderListBox(&listBoxNetworkPauseGameForLaggedClients);
renderer.renderListBox(&listBoxEnableSwitchTeamMode);
renderer.renderListBox(&listBoxAISwitchTeamAcceptPercent);
MutexSafeWrapper safeMutexFTPProgress((ftpClientThread != NULL ? ftpClientThread->getProgressMutex() : NULL),string(__FILE__) + "_" + intToStr(__LINE__));
if(fileFTPProgressList.empty() == false) {
Lang &lang= Lang::getInstance();
@ -1780,6 +1808,14 @@ void MenuStateConnectedGame::update() {
listBoxAllowObservers.setSelectedItemIndex(0);
}
if((gameSettings->getFlagTypes1() & ft1_allow_team_switching) == ft1_allow_team_switching){
listBoxEnableSwitchTeamMode.setSelectedItemIndex(0);
}
else {
listBoxEnableSwitchTeamMode.setSelectedItemIndex(1);
}
listBoxAISwitchTeamAcceptPercent.setSelectedItem(intToStr(gameSettings->getAiAcceptSwitchTeamPercentChance()));
if(gameSettings->getEnableObserverModeAtEndGame()) {
listBoxEnableObserverMode.setSelectedItemIndex(0);
}

View File

@ -169,6 +169,11 @@ private:
std::map<string,pair<int,string> > fileFTPProgressList;
GraphicButton buttonCancelDownloads;
GraphicLabel labelEnableSwitchTeamMode;
GraphicListBox listBoxEnableSwitchTeamMode;
GraphicLabel labelAISwitchTeamAcceptPercent;
GraphicListBox listBoxAISwitchTeamAcceptPercent;
public:
MenuStateConnectedGame(Program *program, MainMenu *mainMenu, JoinMenu joinMenuInfo=jmSimple, bool openNetworkSlots= false);

View File

@ -305,6 +305,28 @@ MenuStateCustomGame::MenuStateCustomGame(Program *program, MainMenu *mainMenu, b
listBoxEnableObserverMode.pushBackItem(lang.get("No"));
listBoxEnableObserverMode.setSelectedItemIndex(0);
// Allow Switch Team Mode
labelEnableSwitchTeamMode.registerGraphicComponent(containerName,"labelEnableSwitchTeamMode");
labelEnableSwitchTeamMode.init(xoffset+310, aHeadPos+40, 80);
labelEnableSwitchTeamMode.setText(lang.get("EnableSwitchTeamMode"));
listBoxEnableSwitchTeamMode.registerGraphicComponent(containerName,"listBoxEnableSwitchTeamMode");
listBoxEnableSwitchTeamMode.init(xoffset+310, aPos+40, 80);
listBoxEnableSwitchTeamMode.pushBackItem(lang.get("Yes"));
listBoxEnableSwitchTeamMode.pushBackItem(lang.get("No"));
listBoxEnableSwitchTeamMode.setSelectedItemIndex(1);
labelAISwitchTeamAcceptPercent.registerGraphicComponent(containerName,"labelAISwitchTeamAcceptPercent");
labelAISwitchTeamAcceptPercent.init(xoffset+460, aHeadPos+40, 80);
labelAISwitchTeamAcceptPercent.setText(lang.get("AISwitchTeamAcceptPercent"));
listBoxAISwitchTeamAcceptPercent.registerGraphicComponent(containerName,"listBoxAISwitchTeamAcceptPercent");
listBoxAISwitchTeamAcceptPercent.init(xoffset+460, aPos+40, 80);
for(int i = 0; i <= 100; i = i + 10) {
listBoxAISwitchTeamAcceptPercent.pushBackItem(intToStr(i));
}
listBoxAISwitchTeamAcceptPercent.setSelectedItem(intToStr(30));
// Which Pathfinder
labelPathFinderType.registerGraphicComponent(containerName,"labelPathFinderType");
labelPathFinderType.init(xoffset+650, aHeadPos, 80);
@ -768,6 +790,32 @@ void MenuStateCustomGame::mouseClick(int x, int y, MouseButton mouseButton){
lastSetChangedGameSettings = time(NULL);
}
}
else if (listBoxAdvanced.getSelectedItemIndex() == 1 && listBoxEnableSwitchTeamMode.mouseClick(x, y)) {
MutexSafeWrapper safeMutex((publishToMasterserverThread != NULL ? publishToMasterserverThread->getMutexThreadObjectAccessor() : NULL),string(__FILE__) + "_" + intToStr(__LINE__));
if(listBoxPublishServer.getSelectedItemIndex() == 0) {
needToRepublishToMasterserver = true;
}
if(hasNetworkGameSettings() == true)
{
needToSetChangedGameSettings = true;
lastSetChangedGameSettings = time(NULL);
}
}
else if (listBoxAdvanced.getSelectedItemIndex() == 1 && listBoxAISwitchTeamAcceptPercent.getEnabled() && listBoxAISwitchTeamAcceptPercent.mouseClick(x, y)) {
MutexSafeWrapper safeMutex((publishToMasterserverThread != NULL ? publishToMasterserverThread->getMutexThreadObjectAccessor() : NULL),string(__FILE__) + "_" + intToStr(__LINE__));
if(listBoxPublishServer.getSelectedItemIndex() == 0) {
needToRepublishToMasterserver = true;
}
if(hasNetworkGameSettings() == true)
{
needToSetChangedGameSettings = true;
lastSetChangedGameSettings = time(NULL);
}
}
else if (listBoxAdvanced.getSelectedItemIndex() == 1 && listBoxPathFinderType.mouseClick(x, y)) {
MutexSafeWrapper safeMutex((publishToMasterserverThread != NULL ? publishToMasterserverThread->getMutexThreadObjectAccessor() : NULL),string(__FILE__) + "_" + intToStr(__LINE__));
@ -1309,6 +1357,9 @@ void MenuStateCustomGame::mouseMove(int x, int y, const MouseState *ms){
//labelNetworkFramePeriod.mouseMove(x, y);
//listBoxNetworkFramePeriod.mouseMove(x, y);
listBoxEnableSwitchTeamMode.mouseMove(x, y);
listBoxAISwitchTeamAcceptPercent.mouseMove(x, y);
labelNetworkPauseGameForLaggedClients.mouseMove(x, y);
listBoxNetworkPauseGameForLaggedClients.mouseMove(x, y);
@ -1443,10 +1494,16 @@ void MenuStateCustomGame::render() {
renderer.renderLabel(&labelEnableObserverMode);
renderer.renderLabel(&labelPathFinderType);
renderer.renderLabel(&labelEnableSwitchTeamMode);
renderer.renderLabel(&labelAISwitchTeamAcceptPercent);
renderer.renderListBox(&listBoxFogOfWar);
renderer.renderListBox(&listBoxAllowObservers);
renderer.renderListBox(&listBoxEnableObserverMode);
renderer.renderListBox(&listBoxPathFinderType);
renderer.renderListBox(&listBoxEnableSwitchTeamMode);
renderer.renderListBox(&listBoxAISwitchTeamAcceptPercent);
}
renderer.renderLabel(&labelTileset);
renderer.renderLabel(&labelMapFilter);
@ -1747,6 +1804,8 @@ void MenuStateCustomGame::update() {
GameSettings gameSettings;
loadGameSettings(&gameSettings);
listBoxAISwitchTeamAcceptPercent.setEnabled(listBoxEnableSwitchTeamMode.getSelectedItemIndex() == 0);
int factionCount = 0;
for(int i= 0; i< mapInfo.players; ++i) {
if(hasNetworkGameSettings() == true) {
@ -2332,6 +2391,17 @@ void MenuStateCustomGame::loadGameSettings(GameSettings *gameSettings,bool force
gameSettings->setEnableObserverModeAtEndGame(listBoxEnableObserverMode.getSelectedItemIndex() == 0);
gameSettings->setPathFinderType(static_cast<PathFinderType>(listBoxPathFinderType.getSelectedItemIndex()));
valueFlags1 = gameSettings->getFlagTypes1();
if(listBoxEnableSwitchTeamMode.getSelectedItemIndex() == 0) {
valueFlags1 |= ft1_allow_team_switching;
gameSettings->setFlagTypes1(valueFlags1);
}
else {
valueFlags1 &= ~ft1_allow_team_switching;
gameSettings->setFlagTypes1(valueFlags1);
}
gameSettings->setAiAcceptSwitchTeamPercentChance(strToInt(listBoxAISwitchTeamAcceptPercent.getSelectedItem()));
// First save Used slots
//for(int i=0; i<mapInfo.players; ++i)
int AIPlayerCount = 0;
@ -2555,6 +2625,9 @@ void MenuStateCustomGame::saveGameSettingsToFile(std::string fileName) {
saveGameFile << "FlagTypes1=" << gameSettings.getFlagTypes1() << std::endl;
saveGameFile << "EnableObserverModeAtEndGame=" << gameSettings.getEnableObserverModeAtEndGame() << std::endl;
saveGameFile << "AiAcceptSwitchTeamPercentChance=" << gameSettings.getAiAcceptSwitchTeamPercentChance() << std::endl;
saveGameFile << "PathFinderType=" << gameSettings.getPathFinderType() << std::endl;
saveGameFile << "EnableServerControlledAI=" << gameSettings.getEnableServerControlledAI() << std::endl;
saveGameFile << "NetworkFramePeriod=" << gameSettings.getNetworkFramePeriod() << std::endl;
@ -2626,6 +2699,9 @@ GameSettings MenuStateCustomGame::loadGameSettingsFromFile(std::string fileName)
gameSettings.setFlagTypes1(properties.getInt("FlagTypes1","0"));
gameSettings.setEnableObserverModeAtEndGame(properties.getBool("EnableObserverModeAtEndGame"));
gameSettings.setAiAcceptSwitchTeamPercentChance(properties.getInt("AiAcceptSwitchTeamPercentChance","30"));
gameSettings.setPathFinderType(static_cast<PathFinderType>(properties.getInt("PathFinderType",intToStr(pfBasic).c_str())));
gameSettings.setEnableServerControlledAI(properties.getBool("EnableServerControlledAI","true"));
gameSettings.setNetworkFramePeriod(properties.getInt("NetworkFramePeriod",intToStr(GameConstants::networkFramePeriod).c_str()));
@ -2717,6 +2793,10 @@ void MenuStateCustomGame::setupUIFromGameSettings(const GameSettings &gameSettin
listBoxAllowObservers.setSelectedItem(gameSettings.getAllowObservers() == true ? lang.get("Yes") : lang.get("No"));
listBoxEnableObserverMode.setSelectedItem(gameSettings.getEnableObserverModeAtEndGame() == true ? lang.get("Yes") : lang.get("No"));
listBoxEnableSwitchTeamMode.setSelectedItem((gameSettings.getFlagTypes1() & ft1_allow_team_switching) == ft1_allow_team_switching ? lang.get("Yes") : lang.get("No"));
listBoxAISwitchTeamAcceptPercent.setSelectedItem(intToStr(gameSettings.getAiAcceptSwitchTeamPercentChance()));
listBoxPathFinderType.setSelectedItemIndex(gameSettings.getPathFinderType());
//listBoxEnableServerControlledAI.setSelectedItem(gameSettings.getEnableServerControlledAI() == true ? lang.get("Yes") : lang.get("No"));

View File

@ -102,6 +102,11 @@ private:
GraphicLabel labelPlayerStatus[GameConstants::maxPlayers];
GraphicListBox listBoxPlayerStatus;
GraphicLabel labelEnableSwitchTeamMode;
GraphicListBox listBoxEnableSwitchTeamMode;
GraphicLabel labelAISwitchTeamAcceptPercent;
GraphicListBox listBoxAISwitchTeamAcceptPercent;
bool needToSetChangedGameSettings;
time_t lastSetChangedGameSettings;
time_t lastMasterserverPublishing;

View File

@ -78,6 +78,17 @@ MenuStateRoot::MenuStateRoot(Program *program, MainMenu *mainMenu):
mainMessageBox.init(lang.get("Yes"), lang.get("No"));
mainMessageBox.setEnabled(false);
//PopupMenu popupMenu;
std::vector<string> menuItems;
menuItems.push_back("1");
menuItems.push_back("2");
menuItems.push_back("3");
popupMenu.setW(100);
popupMenu.setH(100);
popupMenu.init("Test Menu",menuItems);
popupMenu.setEnabled(false);
popupMenu.setVisible(false);
GraphicComponent::applyAllCustomProperties(containerName);
}
@ -86,7 +97,12 @@ void MenuStateRoot::mouseClick(int x, int y, MouseButton mouseButton){
CoreData &coreData= CoreData::getInstance();
SoundRenderer &soundRenderer= SoundRenderer::getInstance();
if(mainMessageBox.getEnabled() == false && buttonNewGame.mouseClick(x, y)){
if(popupMenu.mouseClick(x, y)) {
std::pair<int,string> result = popupMenu.mouseClickedMenuItem(x, y);
printf("In popup callback menuItemSelected [%s] menuIndexSelected = %d\n",result.second.c_str(),result.first);
}
else if(mainMessageBox.getEnabled() == false && buttonNewGame.mouseClick(x, y)){
soundRenderer.playFx(coreData.getClickSoundB());
mainMenu->setState(new MenuStateNewGame(program, mainMenu));
}
@ -125,6 +141,7 @@ void MenuStateRoot::mouseClick(int x, int y, MouseButton mouseButton){
}
void MenuStateRoot::mouseMove(int x, int y, const MouseState *ms){
popupMenu.mouseMove(x, y);
buttonNewGame.mouseMove(x, y);
buttonMods.mouseMove(x, y);
buttonOptions.mouseMove(x, y);
@ -187,6 +204,7 @@ void MenuStateRoot::render() {
currentX += extraLogo->getPixmap()->getW();
}
renderer.renderButton(&buttonNewGame);
renderer.renderButton(&buttonMods);
renderer.renderButton(&buttonOptions);
@ -196,10 +214,13 @@ void MenuStateRoot::render() {
renderer.renderConsole(&console,false,true);
renderer.renderPopupMenu(&popupMenu);
//exit message box
if(mainMessageBox.getEnabled()) {
renderer.renderMessageBox(&mainMessageBox);
}
if(program != NULL) program->renderProgramMsgBox();
}

View File

@ -22,6 +22,7 @@ namespace Glest{ namespace Game{
// ===============================
class GraphicMessageBox;
class PopupMenu;
class MenuStateRoot: public MenuState {
private:
@ -34,6 +35,8 @@ private:
GraphicMessageBox mainMessageBox;
PopupMenu popupMenu;
public:
MenuStateRoot(Program *program, MainMenu *mainMenu);

View File

@ -230,6 +230,7 @@ NetworkMessageLaunch::NetworkMessageLaunch() {
data.factionNameList[i] = "";
data.factionCRCList[i] = 0;
}
data.aiAcceptSwitchTeamPercentChance = 0;
}
NetworkMessageLaunch::NetworkMessageLaunch(const GameSettings *gameSettings,int8 messageType) {
@ -278,6 +279,8 @@ NetworkMessageLaunch::NetworkMessageLaunch(const GameSettings *gameSettings,int8
data.teams[i]= gameSettings->getTeam(i);
data.startLocationIndex[i]= gameSettings->getStartLocationIndex(i);
}
data.aiAcceptSwitchTeamPercentChance = gameSettings->getAiAcceptSwitchTeamPercentChance();
}
void NetworkMessageLaunch::buildGameSettings(GameSettings *gameSettings) const {
@ -322,6 +325,8 @@ void NetworkMessageLaunch::buildGameSettings(GameSettings *gameSettings) const {
gameSettings->setTeam(i, data.teams[i]);
gameSettings->setStartLocationIndex(i, data.startLocationIndex[i]);
}
gameSettings->setAiAcceptSwitchTeamPercentChance(data.aiAcceptSwitchTeamPercentChance);
}
vector<pair<string,int32> > NetworkMessageLaunch::getFactionCRCList() const {

View File

@ -232,6 +232,8 @@ private:
int8 networkPauseGameForLaggedClients;
int8 pathFinderType;
uint32 flagTypes1;
int8 aiAcceptSwitchTeamPercentChance;
};
private:

View File

@ -65,7 +65,9 @@ public:
enum NetworkCommandType {
nctGiveCommand,
nctCancelCommand,
nctSetMeetingPoint
nctSetMeetingPoint,
nctSwitchTeam,
nctSwitchTeamVote
//nctNetworkCommand
};

View File

@ -34,17 +34,60 @@ CommandGroupSorter::CommandGroupSorter() {
this->unit = NULL;
}
CommandGroupSorter::~CommandGroupSorter() {
this->unit = NULL;
}
CommandGroupSorter::CommandGroupSorter(Unit *unit) {
this->unit = unit;
}
bool CommandGroupSorter::operator< (const CommandGroupSorter *j) const {
return operator<(*j);
CommandGroupSorter::CommandGroupSorter(const CommandGroupSorter &obj) {
copyAll(obj);
}
CommandGroupSorter::CommandGroupSorter(const CommandGroupSorter *obj) {
if(obj != NULL) {
copyAll(*obj);
}
}
CommandGroupSorter & CommandGroupSorter::operator=(const CommandGroupSorter &obj) {
copyAll(obj);
return *this;
}
bool CommandGroupSorter::compare(const CommandGroupSorter *l, const CommandGroupSorter *r) {
return (*l < *r);
void CommandGroupSorter::copyAll(const CommandGroupSorter &obj) {
if(this != &obj) {
this->unit = obj.unit;
}
}
bool CommandGroupSorter::comparePtr(const CommandGroupSorter *l, const CommandGroupSorter *r) {
if(!l) {
printf("Error l == NULL\n");
}
if(!r) {
printf("Error r == NULL\n");
}
assert(l && r);
if(l->unit == NULL || r->unit == NULL)
printf("Unit l [%s - %d] r [%s - %d]\n",
(l->unit != NULL ? l->unit->getType()->getName().c_str() : "null"),
(l->unit != NULL ? l->unit->getId() : -1),
(r->unit != NULL ? r->unit->getType()->getName().c_str() : "null"),
(r->unit != NULL ? r->unit->getId() : -1));
const CommandGroupSorter &lRef = *l;
const CommandGroupSorter &rRef = *r;
return (lRef < rRef);
}
bool CommandGroupSorter::compare(const CommandGroupSorter &l, const CommandGroupSorter &r) {
return (l < r);
}
bool CommandGroupSorter::operator< (const CommandGroupSorter &j) const {
@ -1456,6 +1499,35 @@ int Faction::getFrameCount() {
return frameCount;
}
const SwitchTeamVote * Faction::getFirstSwitchTeamVote() const {
const SwitchTeamVote *vote = NULL;
if(switchTeamVotes.size() > 0) {
for(std::map<int,SwitchTeamVote>::const_iterator iterMap = switchTeamVotes.begin();
iterMap != switchTeamVotes.end(); ++iterMap) {
const SwitchTeamVote &curVote = iterMap->second;
if(curVote.voted == false) {
vote = &curVote;
break;
}
}
}
return vote;
}
SwitchTeamVote * Faction::getSwitchTeamVote(int factionIndex) {
SwitchTeamVote *vote = NULL;
if(switchTeamVotes.find(factionIndex) != switchTeamVotes.end()) {
vote = &switchTeamVotes[factionIndex];
}
return vote;
}
void Faction::setSwitchTeamVote(SwitchTeamVote &vote) {
switchTeamVotes[vote.factionIndex] = vote;
}
std::string Faction::toString() const {
std::string result = "";

View File

@ -54,10 +54,17 @@ public:
Unit *unit;
CommandGroupSorter();
~CommandGroupSorter();
CommandGroupSorter(Unit *unit);
CommandGroupSorter(const CommandGroupSorter &obj);
CommandGroupSorter(const CommandGroupSorter *obj);
CommandGroupSorter & operator=(const CommandGroupSorter &obj);
bool operator< (const CommandGroupSorter &j) const;
bool operator< (const CommandGroupSorter *j) const;
bool static compare(const CommandGroupSorter *l, const CommandGroupSorter *r);
static bool comparePtr(const CommandGroupSorter *l, const CommandGroupSorter *r);
static bool compare(const CommandGroupSorter &l, const CommandGroupSorter &r);
protected:
void copyAll(const CommandGroupSorter &obj);
};
class FactionThread : public BaseThread {
@ -80,6 +87,16 @@ public:
bool isSignalPathfinderCompleted(int frameIndex);
};
class SwitchTeamVote {
public:
int factionIndex;
int oldTeam;
int newTeam;
bool voted;
bool allowSwitchTeam;
};
class Faction {
private:
typedef vector<Resource> Resources;
@ -119,6 +136,9 @@ private:
RandomGen random;
FactionThread *workerThread;
std::map<int,SwitchTeamVote> switchTeamVotes;
int currentSwitchTeamVoteFactionIndex;
public:
Faction();
~Faction();
@ -137,7 +157,16 @@ public:
int getStoreAmount(const ResourceType *rt) const;
const FactionType *getType() const {return factionType;}
int getIndex() const {return index;}
int getTeam() const {return teamIndex;}
void setTeam(int team) {teamIndex=team;}
const SwitchTeamVote * getFirstSwitchTeamVote() const;
SwitchTeamVote * getSwitchTeamVote(int factionIndex);
void setSwitchTeamVote(SwitchTeamVote &vote);
int getCurrentSwitchTeamVoteFactionIndex() const { return currentSwitchTeamVoteFactionIndex; }
void setCurrentSwitchTeamVoteFactionIndex(int index) { currentSwitchTeamVoteFactionIndex = index; }
bool getCpuControl(bool enableServerControlledAI, bool isNetworkGame, NetworkRole role) const;
bool getCpuControl() const;
bool getCpuEasyControl() const {return control==ctCpuEasy;}

View File

@ -818,6 +818,62 @@ const ProducibleType *MorphCommandType::getProduced() const{
return morphUnit;
}
// =====================================================
// class SwitchTeamCommandType
// =====================================================
//varios
SwitchTeamCommandType::SwitchTeamCommandType(){
commandTypeClass= ccSwitchTeam;
clicks= cOne;
}
void SwitchTeamCommandType::update(UnitUpdater *unitUpdater, Unit *unit, int frameIndex) const {
unitUpdater->updateSwitchTeam(unit, frameIndex);
}
void SwitchTeamCommandType::load(int id, const XmlNode *n, const string &dir,
const TechTree *tt, const FactionType *ft, const UnitType &ut,
std::map<string,vector<pair<string, string> > > &loadedFileList, string parentLoader) {
CommandType::load(id, n, dir, tt, ft, ut, loadedFileList, parentLoader);
//morph skill
//string skillName= n->getChild("morph-skill")->getAttribute("value")->getRestrictedValue();
//morphSkillType= static_cast<const MorphSkillType*>(ut.getSkillType(skillName, scMorph));
if(SystemFlags::getSystemSettingType(SystemFlags::debugSystem).enabled) SystemFlags::OutputDebug(SystemFlags::debugSystem,"In [%s::%s Line: %d]\n",__FILE__,__FUNCTION__,__LINE__);
}
string SwitchTeamCommandType::getDesc(const TotalUpgrade *totalUpgrade) const{
string str= name+"\n";
Lang &lang= Lang::getInstance();
//prod speed
//str+= lang.get("MorphSpeed")+": "+ intToStr(morphSkillType->getSpeed())+"\n";
//mpcost
// if(morphSkillType->getEpCost()!=0){
// str+= lang.get("EpCost")+": "+intToStr(morphSkillType->getEpCost())+"\n";
// }
// if(morphSkillType->getHpCost()!=0){
// str+= lang.get("HpCost")+": "+intToStr(morphSkillType->getHpCost())+"\n";
// }
//
// //discount
// if(discount!=0){
// str+= lang.get("Discount")+": "+intToStr(discount)+"%\n";
// }
//
// str+= "\n"+getProduced()->getReqDesc();
return str;
}
string SwitchTeamCommandType::toString() const{
Lang &lang= Lang::getInstance();
return lang.get("SwitchTeam");
}
// =====================================================
// class CommandFactory
// =====================================================
@ -833,6 +889,7 @@ CommandTypeFactory::CommandTypeFactory(){
registerClass<ProduceCommandType>("produce");
registerClass<UpgradeCommandType>("upgrade");
registerClass<MorphCommandType>("morph");
registerClass<SwitchTeamCommandType>("switch_team");
}
CommandTypeFactory &CommandTypeFactory::getInstance(){

View File

@ -42,6 +42,7 @@ enum CommandClass {
ccProduce,
ccUpgrade,
ccMorph,
ccSwitchTeam,
ccCount,
ccNull
@ -381,6 +382,24 @@ public:
int getDiscount() const {return discount;}
};
// ===============================
// class SwitchTeamCommandType
// ===============================
class SwitchTeamCommandType: public CommandType {
private:
public:
SwitchTeamCommandType();
virtual void update(UnitUpdater *unitUpdater, Unit *unit, int frameIndex) const;
virtual void load(int id, const XmlNode *n, const string &dir,
const TechTree *tt, const FactionType *ft, const UnitType &ut,
std::map<string,vector<pair<string, string> > > &loadedFileList, string parentLoader);
virtual string getDesc(const TotalUpgrade *totalUpgrade) const;
virtual string toString() const;
};
// ===============================
// class CommandFactory
// ===============================

View File

@ -1882,6 +1882,62 @@ void UnitUpdater::updateMorph(Unit *unit, int frameIndex) {
if(SystemFlags::getSystemSettingType(SystemFlags::debugPerformance).enabled && chrono.getMillis() > 0) SystemFlags::OutputDebug(SystemFlags::debugPerformance,"In [%s::%s] Line: %d took msecs: %lld --------------------------- [END OF METHOD] ---------------------------\n",__FILE__,__FUNCTION__,__LINE__,chrono.getMillis());
}
// ==================== updateMove ====================
void UnitUpdater::updateSwitchTeam(Unit *unit, int frameIndex) {
// Chrono chrono;
// if(SystemFlags::getSystemSettingType(SystemFlags::debugPerformance).enabled) chrono.start();
//
// Command *command= unit->getCurrCommand();
// const MoveCommandType *mct= static_cast<const MoveCommandType*>(command->getCommandType());
//
// Vec2i pos= command->getUnit()!=NULL? command->getUnit()->getCenteredPos(): command->getPos();
//
// if(SystemFlags::getSystemSettingType(SystemFlags::debugWorldSynch).enabled == true && frameIndex < 0) {
// char szBuf[4096]="";
// sprintf(szBuf,"[updateMove] pos [%s] unit [%d - %s] cmd [%s]",pos.getString().c_str(),unit->getId(),unit->getFullName().c_str(),command->toString().c_str());
// unit->logSynchData(__FILE__,__LINE__,szBuf);
// }
//
// if(SystemFlags::getSystemSettingType(SystemFlags::debugPerformance).enabled && chrono.getMillis() > 0) SystemFlags::OutputDebug(SystemFlags::debugPerformance,"In [%s::%s Line: %d] took msecs: %lld\n",__FILE__,__FUNCTION__,__LINE__,chrono.getMillis());
//
// TravelState tsValue = tsImpossible;
// switch(this->game->getGameSettings()->getPathFinderType()) {
// case pfBasic:
// tsValue = pathFinder->findPath(unit, pos, NULL, frameIndex);
// break;
// case pfRoutePlanner:
// tsValue = routePlanner->findPath(unit, pos);
// break;
// default:
// throw runtime_error("detected unsupported pathfinder type!");
// }
//
// if(SystemFlags::getSystemSettingType(SystemFlags::debugPerformance).enabled && chrono.getMillis() > 0) SystemFlags::OutputDebug(SystemFlags::debugPerformance,"In [%s::%s Line: %d] took msecs: %lld\n",__FILE__,__FUNCTION__,__LINE__,chrono.getMillis());
//
// if(frameIndex < 0) {
// switch (tsValue) {
// case tsMoving:
// unit->setCurrSkill(mct->getMoveSkillType());
// break;
//
// case tsBlocked:
// unit->setCurrSkill(scStop);
// if(unit->getPath()->isBlocked()){
// unit->finishCommand();
// }
// break;
//
// default:
// unit->finishCommand();
// }
// }
// if(SystemFlags::getSystemSettingType(SystemFlags::debugPerformance).enabled && chrono.getMillis() > 0) SystemFlags::OutputDebug(SystemFlags::debugPerformance,"In [%s::%s] Line: %d took msecs: %lld --------------------------- [END OF METHOD] ---------------------------\n",__FILE__,__FUNCTION__,__LINE__,chrono.getMillis());
}
// ==================== updateAttack ====================
// ==================== PRIVATE ====================
// ==================== attack ====================

View File

@ -111,6 +111,7 @@ public:
void updateProduce(Unit *unit, int frameIndex);
void updateUpgrade(Unit *unit, int frameIndex);
void updateMorph(Unit *unit, int frameIndex);
void updateSwitchTeam(Unit *unit, int frameIndex);
void clearUnitPrecache(Unit *unit);
void removeUnitPrecache(Unit *unit);

View File

@ -306,7 +306,7 @@ void World::updateAllFactionUnits() {
}
if(unitListToSort.empty() == false) {
//printf("About to Sort...\n");
std::sort(unitListToSort.begin(),unitListToSort.end(),CommandGroupSorter::compare);
std::sort(unitListToSort.begin(),unitListToSort.end(),CommandGroupSorter::comparePtr);
}
if(SystemFlags::getSystemSettingType(SystemFlags::debugWorldSynch).enabled == true) {
@ -332,8 +332,8 @@ void World::updateAllFactionUnits() {
}
if(sortedUnitsAllowed == true) {
std::vector<CommandGroupSorter *> &unitListSorted = unitsInFactionsSorted[faction->getIndex()];
faction->signalWorkerThread(frameCount,&unitListSorted);
std::vector<CommandGroupSorter *> *unitListSorted = &unitsInFactionsSorted[faction->getIndex()];
faction->signalWorkerThread(frameCount,unitListSorted);
}
else {
faction->signalWorkerThread(frameCount,NULL);
@ -394,11 +394,6 @@ void World::updateAllFactionUnits() {
}
unitUpdater.updateUnit(unit);
if(sortedUnitsAllowed == true) {
delete (*unitListSorted)[j];
(*unitListSorted)[j] = NULL;
}
}
// int unitCount = faction->getUnitCount();
@ -412,7 +407,31 @@ void World::updateAllFactionUnits() {
// }
}
unitsInFactionsSorted.clear();
if(sortedUnitsAllowed == true) {
if(workThreadsFinished == false) {
sleep(0);
}
for(int i = 0; i < factionCount; ++i) {
Faction *faction = getFaction(i);
if(faction == NULL) {
throw runtime_error("faction == NULL");
}
std::vector<CommandGroupSorter *> *unitListSorted = &unitsInFactionsSorted[faction->getIndex()];
unsigned int unitCount = unitListSorted->size();
for(int j = 0; j < unitCount; ++j) {
Unit *unit = (*unitListSorted)[j]->unit;
if(unit == NULL) {
throw runtime_error("unit == NULL");
}
delete (*unitListSorted)[j];
(*unitListSorted)[j] = NULL;
}
}
unitsInFactionsSorted.clear();
}
if(SystemFlags::VERBOSE_MODE_ENABLED && chrono.getMillis() >= 20) printf("In [%s::%s Line: %d] *** Faction MAIN thread processing took [%lld] msecs for %d factions for frameCount = %d.\n",__FILE__,__FUNCTION__,__LINE__,(long long int)chrono.getMillis(),factionCount,frameCount);
}
@ -1713,6 +1732,10 @@ void World::computeFow(int factionIdxToTick) {
}
}
GameSettings * World::getGameSettingsPtr() {
return (game != NULL ? game->getGameSettings() : NULL);
}
const GameSettings * World::getGameSettings() const {
return (game != NULL ? game->getReadOnlyGameSettings() : NULL);
}

View File

@ -150,8 +150,13 @@ public:
//get
int getMaxPlayers() const {return map.getMaxPlayers();}
int getThisFactionIndex() const {return thisFactionIndex;}
int getThisTeamIndex() const {return thisTeamIndex;}
void setThisTeamIndex(int team) { thisTeamIndex=team;}
const Faction *getThisFaction() const {return &factions[thisFactionIndex];}
Faction *getThisFactionPtr() {return &factions[thisFactionIndex];}
int getFactionCount() const {return factions.size();}
const Map *getMap() const {return &map;}
const Tileset *getTileset() const {return &tileset;}
@ -223,6 +228,8 @@ public:
Game * getGame() { return game; }
const GameSettings * getGameSettings() const;
GameSettings * getGameSettingsPtr();
std::vector<std::string> validateFactionTypes();
std::vector<std::string> validateResourceTypes();