/** ******************************************************************************* @file /gui/contexts/MultiJoin.cpp @brief Obrazovka klienta multiplayeru @author Pavel @version 0.1 ******************************************************************************/ // #include "gui/contexts/MultiJoin.h" #include "gui/common/ActiveObjects.h" #include "gui/common/BasicFonts.h" #include "gui/GUI.h" #include "gui/common/Defs.h" // #include "common/rm/rminit.h" #include "common/compatibility.h" #include "common/Log.h" #include "gui/common/colors.h" namespace gui{ #define TEXT_HEIGHT 16 #define BORDER 20 #define SMALL_BUTTON_WIDTH 100 #define SMALL_BUTTON_HEIGHT 20 #define MAINWINDOW_WIDTH 700 #define MAINWINDOW_HEIGHT 500 #define MAINWINDOW_X ((SCREEN_WIDTH-MAINWINDOW_WIDTH)/2) #define MAINWINDOW_Y ((SCREEN_HEIGHT-MAINWINDOW_HEIGHT)/2) #define BUTTON_WIDTH 150 #define BUTTON_HEIGHT 35 #define BUTTON_NEXT_X (BUTTON_WIDTH+BORDER) #define BUTTON_Y (MAINWINDOW_HEIGHT-(BORDER+BUTTON_HEIGHT)) #define BUTTON_X (320 + 2*BORDER) #define INFO_WIDTH 320 #define INFO_HEIGHT (4+(2+TEXT_HEIGHT)*3) #define INFO_Y BORDER #define INFO_X BORDER #define ENDGAME_X BORDER #define ENDGAME_Y (INFO_HEIGHT + INFO_Y + TEXT_HEIGHT + BORDER - 10) #define ENDGAME_WIDTH INFO_WIDTH #define ENDGAME_HEIGHT (5*16+2); #define ROLES_X BORDER #define ROLES_Y (INFO_HEIGHT + INFO_Y + TEXT_HEIGHT + BORDER + 62) #define ROLES_WIDTH INFO_WIDTH #define ROLES_HEIGHT (128-62) #define OPTIONS_X BORDER #define OPTIONS_Y (ROLES_Y+ROLES_HEIGHT+BORDER) #define OPTIONS_HEIGHT (200) #define OPTIONS_WIDTH (ROLES_WIDTH) #define OPTIONS_RADIO_SIZE 0 #define OPTIONS_OP_Y (OPTIONS_Y + BORDER + TEXT_HEIGHT) #define OPTIONS_OP_TF_LEN 16 #define OPTIONS_AIP_Y (OPTIONS_Y + BORDER + TEXT_HEIGHT + 80+10) #define DESCRIPTION_X (ROLES_WIDTH + 2*BORDER) #define CHAT_X DESCRIPTION_X #define CHAT_Y 250 #define CHAT_WIDTH 320 #define CHAT_HEIGHT 180 #define ITEM_HEIGHT 20 #define ITEM_BORDER 2 #define DIFICULTY_WIDTH 150 #define DIFICULTY_HEIGHT (3*ITEM_HEIGHT+2) #define CONNECTED_WIDTH 150 #define CONNECTED_HEIGHT (3*ITEM_HEIGHT+2) #define ROLE_RIGHT_LENGTH OPTIONS_OP_TF_LEN #define ROLE_LEFT_LENGTH 11 /*****************************************************************************/ TMultiJoinWindow::TMultiJoinWindow() : TWindow(AO_UNMOVABLE, MAINWINDOW_X, MAINWINDOW_Y, MAINWINDOW_WIDTH, MAINWINDOW_HEIGHT) { wchar_t wtemp[MAP_DESC_LEN]; int i; // rmtxti = (rm::TRM_txt_i*)KSendGlobalMessage(MSG_GET_RM_TXT_I, MOD_GUI, MOD_RM, NULL); // Maps ... nadpis lmapcaption = new TLabel(rmtxti->getWChar(wtemp, LABEL_MAX_LENGTH, TEXT_MAP), BORDER, INFO_Y); Add(lmapcaption); // seznam informaci ginfo = new TGroupBar(AO_NORMAL, BORDER, INFO_Y + TEXT_HEIGHT, INFO_WIDTH, INFO_HEIGHT); Add(ginfo); // rmmapi = (rm::TRM_map_i*)KSendGlobalMessage(MSG_GET_RM_MAP_I,MOD_GUI,MOD_RM,NULL); rmmapi->loadMapsInfo(MAP_TYPE_NEW_GAME, 0); // jmeno mapy lmapname = new TLabel(L"", 4, 2); ginfo->Add(lmapname); // pocet hracu lplayerscountcaption = new TLabel(rmtxti->getWChar(wtemp, LABEL_MAX_LENGTH, TEXT_ROLES), 4, 2+(TEXT_HEIGHT+2)); ginfo->Add(lplayerscountcaption); lplayerscount = new TLabel(L"", 100, 2+(TEXT_HEIGHT+2)); ginfo->Add(lplayerscount); // rozmery mapy lsizecaption = new TLabel(rmtxti->getWChar(wtemp, LABEL_MAX_LENGTH, TEXT_SIZE), 4, 2+(TEXT_HEIGHT+2)*2); ginfo->Add(lsizecaption); lsize = new TLabel(L"", 100, 2+(TEXT_HEIGHT+2)*2); ginfo->Add(lsize); descriptioncaption = new TLabel(rmtxti->getWChar(wtemp, LABEL_MAX_LENGTH, TEXT_MAPDESCRIPTION), DESCRIPTION_X, BORDER); Add(descriptioncaption); TGroupBar* gdescription = new TGroupBar(AO_NORMAL, DESCRIPTION_X, BORDER+TEXT_HEIGHT, OPTIONS_WIDTH, 200); Add(gdescription); mldescription = new TMultiLabel(AO_NORMAL, 0, 0, OPTIONS_WIDTH, 200); gdescription->Add(mldescription); // UTF8toWideChar(info->description, wtemp, MAP_DESC_LEN); mldescription->setText(L""); // Options ... nadpis loptionscaption = new TLabel(rmtxti->getWChar(wtemp, LABEL_MAX_LENGTH, TEXT_ROLEOPTIONS), OPTIONS_X, OPTIONS_Y); Add(loptionscaption); // seznam nastaveni goptions = new TGroupBar(AO_NORMAL, OPTIONS_X, OPTIONS_Y + TEXT_HEIGHT, OPTIONS_WIDTH, OPTIONS_HEIGHT); Add(goptions); lotherplayer = new TLabel(rmtxti->getWChar(wtemp, LABEL_MAX_LENGTH, TEXT_HUMANPLAYER), OPTIONS_X + BORDER, OPTIONS_OP_Y); Add(lotherplayer); //jmeno lotherplayername = new TLabel(rmtxti->getWChar(wtemp, LABEL_MAX_LENGTH, TEXT_NAME), OPTIONS_X + 2*BORDER, OPTIONS_OP_Y + TEXT_HEIGHT); Add(lotherplayername); lbconnected = new TListBar(AO_NORMAL, 10+OPTIONS_X + 75 + 2*BORDER, OPTIONS_OP_Y + TEXT_HEIGHT, CONNECTED_WIDTH , CONNECTED_HEIGHT); Add(lbconnected); lai = new TLabel(rmtxti->getWChar(wtemp, LABEL_MAX_LENGTH, TEXT_AI), OPTIONS_X + BORDER, OPTIONS_AIP_Y); Add(lai); ldificulty = new TLabel(rmtxti->getWChar(wtemp, LABEL_MAX_LENGTH, TEXT_DIFICULTY), OPTIONS_X + 2*BORDER , OPTIONS_AIP_Y + TEXT_HEIGHT); Add(ldificulty); lbdificulty = new TListBar(AO_NORMAL, 10+OPTIONS_X + 75 + 2*BORDER, OPTIONS_AIP_Y + TEXT_HEIGHT, DIFICULTY_WIDTH , DIFICULTY_HEIGHT); Add(lbdificulty); iai1 = new TItem(AO_UNSELECTABLE, ITEM_HEIGHT); lbdificulty->Add(iai1); lai1 = new TLabel(rmtxti->getWChar(wtemp, LABEL_MAX_LENGTH, TEXT_AI_1), ITEM_BORDER, ITEM_BORDER); iai1->Add(lai1); iai2 = new TItem(AO_UNSELECTABLE, ITEM_HEIGHT); lbdificulty->Add(iai2); lai2 = new TLabel(rmtxti->getWChar(wtemp, LABEL_MAX_LENGTH, TEXT_AI_2), ITEM_BORDER, ITEM_BORDER); iai2->Add(lai2); iai3 = new TItem(AO_UNSELECTABLE, ITEM_HEIGHT); lbdificulty->Add(iai3); lai3 = new TLabel(rmtxti->getWChar(wtemp, LABEL_MAX_LENGTH, TEXT_AI_3), ITEM_BORDER, ITEM_BORDER); iai3->Add(lai3); // konec hry lendgamec = new TLabel(rmtxti->getWChar(wtemp, LABEL_MAX_LENGTH, TEXT_ENDGAME_CAPTION), ENDGAME_X, ENDGAME_Y); Add(lendgamec); gendgame = new TGroupBar(AO_NORMAL, ENDGAME_X, ENDGAME_Y + 18, ENDGAME_WIDTH, 6 + 2 * 20); Add(gendgame); rendgame1 = new TRadioBox(AO_UNSELECTABLE, 2, 4, 20, 18); gendgame->Add(rendgame1); rendgame2 = new TRadioBox(AO_UNSELECTABLE, 2, 24, 20, 18); gendgame->Add(rendgame2); lendgame1 = new TLabel(rmtxti->getWChar(wtemp, LABEL_MAX_LENGTH, TEXT_ENDGAME_1), 22, 6); gendgame->Add(lendgame1); lendgame2 = new TLabel(rmtxti->getWChar(wtemp, LABEL_MAX_LENGTH, TEXT_ENDGAME_2), 22, 6+20); gendgame->Add(lendgame2); // role ... nadpis lrolescaption = new TLabel(rmtxti->getWChar(wtemp, LABEL_MAX_LENGTH, TEXT_ROLES), ROLES_X, ROLES_Y); Add(lrolescaption); // seznam roli v mape roleslist = new TListBar(AO_NORMAL, ROLES_X, ROLES_Y + TEXT_HEIGHT, ROLES_WIDTH , ROLES_HEIGHT); Add(roleslist); chatbox = new TChatBox(rmtxti, CHAT_X, CHAT_Y, CHAT_WIDTH, CHAT_HEIGHT); Add(chatbox); // Odpojit se bdisconnect = new TSoundedTextButton(AO_NORMAL, rmtxti->getWChar(wtemp, LABEL_MAX_LENGTH, TEXT_DISCONNECT), BUTTON_X+BUTTON_NEXT_X, BUTTON_Y, BUTTON_WIDTH, BUTTON_HEIGHT, SAMPLE_CLICK); Add(bdisconnect); bdisconnect->setShortcutKey(SDLK_ESCAPE); //pozadi setBgImage(RASTER_PANEL); players_c = 0; for (i = 1; i <= MAX_PLAYERS; i++) { connected[i].enabled = false; players[i].type = MPT_UNUSED; } // lbconectedRestore(); updateLocalGameForm(); } void TMultiJoinWindow::printMapInfo() { wchar_t wtemp[MAP_DESC_LEN]; players_c = info.players; UTF8toWideChar(info.name, lmapname->text, K8_MAX_FILE_NAME_LEN); snwprintf(lplayerscount->text, K8_MAX_FILE_NAME_LEN, L"%d", info.players); snwprintf(lsize->text, K8_MAX_FILE_NAME_LEN, L"%dx%d", info.sizex - 2 * MAP_BOUND_X, info.sizey - 2 * MAP_BOUND_Y); UTF8toWideChar(info.description, wtemp, MAP_DESC_LEN); mldescription->setText(wtemp); } int TMultiJoinWindow::lbconectedRestore() { TItem *item; wchar_t wtemp[MAP_DESC_LEN]; lbconnected->DelNFreeAll(); int con = 0, i; for (i = 1; i <= 8; i++) { if (connected[i].enabled) { item = new TItem(AO_UNSELECTABLE, ITEM_HEIGHT); UTF8toWideChar(connected[i].caption, wtemp, ROLE_RIGHT_LENGTH); item->Add(new TLabel(wtemp, ITEM_BORDER, ITEM_BORDER)); con++; } else { item = new TItem(AO_UNSELECTABLE, 0); } lbconnected->Add(item); connected[i].item = item; } return con; } void TMultiJoinWindow::updateLocalGameForm() { int selpla = roleslist->getSelection(); if (selpla < 0) selpla = 0; roleslist->DelNFreeAll(); TItem *item; TLabel *label; wchar_t wtemp[LABEL_MAX_LENGTH]; int i; // seznam roli for (i = 1; i < MAX_PLAYERS+1; i++) { if (players[i].type != MPT_UNUSED) { if (selpla == 0) item = new TItem(AO_YES, ITEM_HEIGHT); else item = new TItem(AO_NO, ITEM_HEIGHT); roleslist->Add(item); UTF8toWideChar(info.roles[i]->name, wtemp, ROLE_LEFT_LENGTH); label = new TLabel(wtemp, ITEM_BORDER, ITEM_BORDER); label->setColor(ColorPlayer[i][0]/255.f, ColorPlayer[i][1]/255.f, ColorPlayer[i][2]/255.f, 1); item->Add(label); switch (players[i].type){ case MPT_HUMAN: UTF8toWideChar(connected[players[i].connected_id].caption, wtemp, ROLE_RIGHT_LENGTH); break; case MPT_AI_1: rmtxti->getWChar(wtemp, LABEL_MAX_LENGTH, TEXT_AI_1); break; case MPT_AI_2: rmtxti->getWChar(wtemp, LABEL_MAX_LENGTH, TEXT_AI_2); break; case MPT_AI_3: rmtxti->getWChar(wtemp, LABEL_MAX_LENGTH, TEXT_AI_3); break; default: wcscpy(wtemp, L"undefined"); break; } label = new TLabel(wtemp, 100, ITEM_BORDER); label->setColor(ColorPlayer[i][0]/255.f, ColorPlayer[i][1]/255.f, ColorPlayer[i][2]/255.f, 1); item->Add(label); selpla--; } } // nastaveni int role = getSelectedRole(); switch (players[role].type){ case MPT_HUMAN: for (i = 1; i <= 8; i++) connected[i].item->setState(AO_NO); connected[players[role].connected_id].item->setState(AO_YES); iai1->setState(AO_NO); iai2->setState(AO_NO); iai3->setState(AO_NO); break; case MPT_AI_1: case MPT_AI_2: case MPT_AI_3: for (i = 1; i <= 8; i++) connected[i].item->setState(AO_NO); iai1->setState(AO_NO); iai2->setState(AO_NO); iai3->setState(AO_NO); switch (players[role].type){ case MPT_AI_1: iai1->setState(AO_YES); break; case MPT_AI_2: iai2->setState(AO_YES); break; case MPT_AI_3: iai3->setState(AO_YES); break; } break; } } int TMultiJoinWindow::getSelectedRole() { int role = 0; int i = roleslist->getSelection(); while (i >= 0) { role++; if (players[role].type != MPT_UNUSED) i--; } return role; } TMultiJoinWindow::~TMultiJoinWindow() { delete rmmapi; delete rmtxti; } void TMultiJoinWindow::receiveNetData(TPackage *p) { char ctemp[20]; int i; switch (p->getInt("msgtype", 0, NULL)) { case 1: p->getChar(info.name, MAP_NAME_LEN, "mapinfo", 0, "name",0, NULL); info.players = p->getInt("mapinfo", 0, "players", 0, NULL); p->getChar(info.description, MAP_DESC_LEN, "mapinfo", 0, "description", 0, NULL); info.sizex = p->getInt("mapinfo", 0, "width", 0, NULL); info.sizey = p->getInt("mapinfo", 0, "height", 0, NULL); for (i = 1; i <= 8; i++) { sprintf(ctemp, "role%d", i); if (p->getInt("mapinfo", 0, ctemp, 0, NULL)) { sprintf(ctemp, "role%dname", i); p->getChar(roles[i].name, K8_MAX_NAME_LEN, "mapinfo", 0, ctemp, 0, NULL); roles[i].id = i; info.roles[i] = &roles[i]; } else info.roles[i] = 0; } printMapInfo(); break; case 2: if (p->getInt("endgametype", 0, NULL) == 0) { rendgame1->setState(AO_YES); rendgame2->setState(AO_NO); } else { rendgame1->setState(AO_NO); rendgame2->setState(AO_YES); } for (i = 1; i <= MAX_PLAYERS; i++) { snprintf(ctemp, 100, "connected%d", i); if (connected[i].enabled = 0!=p->getInt(ctemp, 0, NULL) ) { snprintf(ctemp, 100, "connected%dname", i); p->getChar(connected[i].caption, K8_MAX_NAME_LEN, ctemp, 0, NULL); } } for (i = 1; i <= MAX_PLAYERS; i++) { snprintf(ctemp, 100, "players%dtype", i); if ((players[i].type = (MYROLETYPE)p->getInt(ctemp, 0, NULL) ) == MPT_HUMAN) { snprintf(ctemp, 100, "players%id", i); players[i].connected_id = p->getInt(ctemp, 0, NULL); } } lbconectedRestore(); updateLocalGameForm(); break; case 3: TGUI::gui_inst->screen->selectContext("GAMELOADINGCONTEXT", TContextParameter(context_networkgame, 0) ); break; } delete p; } /*****************************************************************************/ TMultiJoin::TMultiJoin(TContextParameter contextparameter) { rmtxti = (rm::TRM_txt_i*)KSendGlobalMessage(MSG_GET_RM_TXT_I, MOD_GUI, MOD_RM, NULL); } TMultiJoin::~TMultiJoin() { // vypusti a odalokuje vsechny aktivni prvky v sobe (rekursivne) DelNFreeAll(); // delete rmtxti; } TContext* TMultiJoin::createContext(...){ TMultiJoin* n = new TMultiJoin(TContextParameter()); strcpy(n->szName,"MULTIJOIN"); return n; } void TMultiJoin::activateContext(TContextParameter contextparameter) { // kdyz je kurzor na kraji obrazovky tak se nezmeni jeho obrazek na sipku TaoKernel::aoKernel->cursor->scrolling = false; gui::TGUI::gui_inst->IMHost = false; mainwindow = new TMultiJoinWindow(); Add(mainwindow); disconnectedwindow = NULL; } void TMultiJoin::deactivateContext() { DelNFreeAll(); } void TMultiJoin::drawContext(){ TFrame::drawObject(); } int TMultiJoin::workInput(INPUT *input) { int ret=TContext::workInput(input); // hlavni menu if (mainwindow) { if CLICKED(mainwindow->bdisconnect) { KSendGlobalMsg(MSG_NET_STOPCLIENT, ANNONYMOUS, MOD_NET, NULL); TGUI::gui_inst->screen->selectContext("MAINMENU", TContextParameter(context_networkjoingame, 0) ); return ret; } if CLICKED(mainwindow->roleslist) { mainwindow->updateLocalGameForm(); return ret; } } if (disconnectedwindow) { if CLICKED(disconnectedwindow->bok) { KSendGlobalMsg(MSG_NET_STOPCLIENT, ANNONYMOUS, BROADCAST, NULL); TGUI::gui_inst->screen->selectContext("MAINMENU", TContextParameter(context_mainmenu, 0) ); return ret; } } return ret; } void TMultiJoin::disconnect() { DelNFreeAll(); mainwindow = 0; disconnectedwindow = new TErrorWindow(TEXT_DISCONNECTED, ewtNotice, true); Add(disconnectedwindow); } void TMultiJoin::receiveNetData(TPackage *p) { if (mainwindow) mainwindow->receiveNetData(p); } void TMultiJoin::chatMsg(TPackage *p) { if (mainwindow) { if (mainwindow->chatbox) mainwindow->chatbox->receiveMsg(p); } } }//namespace /*****************************************************************************/