/** ******************************************************************************* @file /gui/contexts/LocalMulti.cpp @brief Obrazovka klienta multiplayeru @author Pavel @version 0.1 ******************************************************************************/ // #include "gui/contexts/LocalMulti.h" #include "gui/contexts/LoadingScreen.h" #include "gui/common/ActiveObjects.h" #include "gui/common/Sounds.h" #include "gui/common/BasicFonts.h" #include "gui/GUI.h" #include "gui/common/Defs.h" // #include "common/rm/rminit.h" #include "common/Interface.h" #include "common/Log.h" #include "common/compatibility.h" #include "gui/common/colors.h" // #include "world/world_messages.h" namespace gui{ #define TEXT_HEIGHT 16 #define BORDER 20 #define SMALL_BUTTON_WIDTH 100 #define SMALL_BUTTON_HEIGHT 20 #define BUTTON_WIDTH 200 #define BUTTON_HEIGHT 35 #define BUTTON_NEXT_X (BUTTON_WIDTH+BORDER) #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 INFO_WIDTH 250 #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) #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) + 82) #define ROLES_WIDTH INFO_WIDTH #define ROLES_HEIGHT (275 - 82) #define OPTIONS_X (ROLES_WIDTH + 2*BORDER) #define OPTIONS_Y (INFO_HEIGHT + INFO_Y + TEXT_HEIGHT + BORDER + 50) #define OPTIONS_HEIGHT (275-50) #define OPTIONS_WIDTH (MAINWINDOW_WIDTH - INFO_WIDTH - 3*BORDER) #define OPTIONS_RADIO_SIZE 18 #define OPTIONS_PP_Y (OPTIONS_Y + BORDER + TEXT_HEIGHT) #define OPTIONS_OP_Y (OPTIONS_Y + BORDER + TEXT_HEIGHT + 30) #define OPTIONS_OP_TF_LEN 16 #define OPTIONS_AIP_Y (OPTIONS_Y + BORDER + TEXT_HEIGHT + 80) #define ITEM_HEIGHT 20 #define ITEM_BORDER 2 #define DIFICULTY_WIDTH 150 #define DIFICULTY_HEIGHT (3*ITEM_HEIGHT+2) /*****************************************************************************/ TLocalMultiWindow::TLocalMultiWindow(int _mapnumber) : TWindow(AO_UNMOVABLE, MAINWINDOW_X, MAINWINDOW_Y, MAINWINDOW_WIDTH, MAINWINDOW_HEIGHT) { wchar_t wtemp[MAP_DESC_LEN]; mapnumber = _mapnumber; 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); rmmapi->getMapInfo(&info, mapnumber); players_c = info->players; // jmeno mapy UTF8toWideChar(info->name, wtemp, K8_MAX_FILE_NAME_LEN); lmapname = new TLabel(wtemp, 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); snwprintf(wtemp, K8_MAX_FILE_NAME_LEN, L"%d", info->players); lplayerscount = new TLabel(wtemp, 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); snwprintf(wtemp, K8_MAX_FILE_NAME_LEN, L"%dx%d", info->sizex - 2 * MAP_BOUND_X, info->sizey - 2 * MAP_BOUND_Y); lsize = new TLabel(wtemp, 100, 2+(TEXT_HEIGHT+2)*2); ginfo->Add(lsize); // Popis descriptioncaption = new TLabel(rmtxti->getWChar(wtemp, LABEL_MAX_LENGTH, TEXT_MAPDESCRIPTION), OPTIONS_X, BORDER); Add(descriptioncaption); TGroupBar* gdescription = new TGroupBar(AO_NORMAL, OPTIONS_X, BORDER+TEXT_HEIGHT, OPTIONS_WIDTH, 120); Add(gdescription); mldescription = new TMultiLabel(AO_NORMAL, 0, 0, OPTIONS_WIDTH, 120); gdescription->Add(mldescription); UTF8toWideChar(info->description, wtemp, MAP_DESC_LEN); mldescription->setText(wtemp); // 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); //PRIMARNI HRAC rbprimaryplayer = new TRadioBox(AO_SELECTED, OPTIONS_X + BORDER, OPTIONS_PP_Y, OPTIONS_RADIO_SIZE, OPTIONS_RADIO_SIZE); Add(rbprimaryplayer); lprimaryplayer = new TLabel(rmtxti->getWChar(wtemp, LABEL_MAX_LENGTH, TEXT_PRIMARYPLAYER), OPTIONS_X + 2*BORDER + OPTIONS_RADIO_SIZE, OPTIONS_PP_Y); Add(lprimaryplayer); //DALSI HRAC rbotherplayer = new TRadioBox(0, OPTIONS_X + BORDER, OPTIONS_OP_Y, OPTIONS_RADIO_SIZE, OPTIONS_RADIO_SIZE); Add(rbotherplayer); lotherplayer = new TLabel(rmtxti->getWChar(wtemp, LABEL_MAX_LENGTH, TEXT_OTHERPLAYER), OPTIONS_X + 2*BORDER + OPTIONS_RADIO_SIZE, OPTIONS_OP_Y); Add(lotherplayer); //jmeno lotherplayername = new TLabel(rmtxti->getWChar(wtemp, LABEL_MAX_LENGTH, TEXT_NAME), OPTIONS_X + 3*BORDER + OPTIONS_RADIO_SIZE, OPTIONS_OP_Y + TEXT_HEIGHT); Add(lotherplayername); tfotherplayename = new TLineTextField(20+OPTIONS_X + 75 + 3*BORDER + OPTIONS_RADIO_SIZE, OPTIONS_OP_Y+ TEXT_HEIGHT, OPTIONS_OP_TF_LEN); Add(tfotherplayename); //AI rbai = new TRadioBox(0, OPTIONS_X + BORDER, OPTIONS_AIP_Y, OPTIONS_RADIO_SIZE, OPTIONS_RADIO_SIZE); Add(rbai); lai = new TLabel(rmtxti->getWChar(wtemp, LABEL_MAX_LENGTH, TEXT_AI), OPTIONS_X + 2*BORDER + OPTIONS_RADIO_SIZE, OPTIONS_AIP_Y); Add(lai); ldificulty = new TLabel(rmtxti->getWChar(wtemp, LABEL_MAX_LENGTH, TEXT_DIFICULTY), OPTIONS_X + 3*BORDER + OPTIONS_RADIO_SIZE, OPTIONS_AIP_Y + TEXT_HEIGHT); Add(ldificulty); lbdificulty = new TListBar(AO_NORMAL, 20+OPTIONS_X + 75 + 3*BORDER + OPTIONS_RADIO_SIZE, OPTIONS_AIP_Y + TEXT_HEIGHT, DIFICULTY_WIDTH , DIFICULTY_HEIGHT); Add(lbdificulty); iai1 = new TItem(AO_NO, 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_NO, 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_NO, 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_CHECKED, 2, 4, 20, 18); gendgame->Add(rendgame1); rendgame2 = new TRadioBox(AO_NO, 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); bool firstplayer = true; for (int i = 1; i < MAX_PLAYERS+1; i++) { if (info->roles[i] == NULL) players[i].type = MPT_UNUSED; else { if (firstplayer){ players[i].type = MPT_MAINHUMAN; strcpy(players[i].name, TGUI::gui_inst->profile->name); firstplayer = false; } else { players[i].type = MPT_HUMAN; sprintf(players[i].name, "Noname%02d", i); } }//else }//for // start bplay = new TSoundedTextButton(AO_NORMAL, rmtxti->getWChar(wtemp, LABEL_MAX_LENGTH, TEXT_PLAY), BORDER, MAINWINDOW_HEIGHT-BUTTON_HEIGHT-BORDER, BUTTON_WIDTH, BUTTON_HEIGHT, SAMPLE_CLICK); Add(bplay); // bplay->setShortcutKey(SDLK_RETURN); //back bback = new TSoundedTextButton(AO_NORMAL, rmtxti->getWChar(wtemp, LABEL_MAX_LENGTH, TEXT_BACK), BORDER + BUTTON_NEXT_X, MAINWINDOW_HEIGHT-BUTTON_HEIGHT-BORDER, BUTTON_WIDTH, BUTTON_HEIGHT, SAMPLE_CLICK); Add(bback); bback->setShortcutKey(SDLK_ESCAPE); //pozadi setBgImage(RASTER_PANEL); // updateLocalGameForm(); } #define ROLE_RIGHT_LENGTH OPTIONS_OP_TF_LEN #define ROLE_LEFT_LENGTH 11 void TLocalMultiWindow::updateLocalGameForm() { int selpla = roleslist->getSelection(); if (selpla < 0) selpla = 0; roleslist->DelNFreeAll(); TItem *item; TLabel *label; wchar_t wtemp[LABEL_MAX_LENGTH]; for (int 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_MAINHUMAN: UTF8toWideChar(TGUI::gui_inst->profile->name, wtemp, ROLE_RIGHT_LENGTH); break; case MPT_HUMAN: UTF8toWideChar(players[i].name, 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; } 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--; } } int role = getSelectedRole(); switch (players[role].type){ case MPT_MAINHUMAN: rbprimaryplayer->setState(AO_YES); rbotherplayer->setState(AO_NO); rbai->setState(AO_NO); tfotherplayename->setText(L""); iai1->setState(AO_NO); iai2->setState(AO_NO); iai3->setState(AO_NO); break; case MPT_HUMAN: rbprimaryplayer->setState(AO_NO); rbotherplayer->setState(AO_YES); rbai->setState(AO_NO); UTF8toWideChar(players[role].name, wtemp, ROLE_RIGHT_LENGTH); tfotherplayename->setText(wtemp); 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: rbprimaryplayer->setState(AO_NO); rbotherplayer->setState(AO_NO); rbai->setState(AO_YES); tfotherplayename->setText(L""); 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 TLocalMultiWindow::getSelectedRole() { int role = 0; int i = roleslist->getSelection(); while (i >= 0) { role++; if (players[role].type != MPT_UNUSED) i--; } return role; } TLocalMultiWindow::~TLocalMultiWindow() { delete rmmapi; delete rmtxti; } /*****************************************************************************/ void TLocalMulti::addClient(int cli){ //pripojen novy mainwindow->players_connected++; //jestli pripojeni vsichni, tak zaciname if(mainwindow->players_connected == mainwindow->players_c) { //zacni hru PACKET_GAME_START pgs; pgs.map_id = mapnumber; //vyber podminky konce hry if (SELECTED(mainwindow->rendgame1)) pgs.end_game_condition = EGC_CONQUER; else pgs.end_game_condition = EGC_DEATHMATCH; //projdi role int clid = 0; for (int j = 1; j <= MAX_PLAYERS ; j++){ if (mainwindow->players[j].type != MPT_UNUSED){ //cislo role pgs.players[clid].player_id = j; pgs.players[clid].client_id = gui::TGUI::gui_inst->clientsinfo.cinfo[clid].clientid; //jmeno a typ switch (mainwindow->players[j].type){ case MPT_HUMAN: strcpy(pgs.players[clid].name, mainwindow->players[j].name); pgs.players[clid].type = World::PT_HUMAN; pgs.players[clid].acommands=World::PAC_ALL; break; case MPT_MAINHUMAN: pgs.players[clid].type = World::PT_HUMAN; pgs.players[clid].acommands=World::PAC_ALL; strcpy(pgs.players[clid].name, TGUI::gui_inst->profile->name); break; case MPT_AI_1: case MPT_AI_2: case MPT_AI_3: switch (mainwindow->players[j].type){ case MPT_AI_1: pgs.players[clid].type = World::PT_AI_1; break; case MPT_AI_2: pgs.players[clid].type = World::PT_AI_2; break; case MPT_AI_3: pgs.players[clid].type = World::PT_AI_3; break; } pgs.players[clid].acommands=World::PAC_ALL; strcpy(pgs.players[clid].name, mainwindow->info->roles[j]->name); break; }//switch clid++; }//if }//for //dopln zbytek for(int k = clid; k < MAX_PLAYERS; k++){ pgs.players[k].client_id = -1; pgs.players[k].player_id = 0; } //ukaz hodiny TGUI::gui_inst->screen->selectContext("GAMELOADINGCONTEXT", TContextParameter(context_localgame, 0) ); //zaciname TPacket_SyncResult* result = (TPacket_SyncResult*)KSendGlobalMsg(MSG_GAME_START, ANNONYMOUS, BROADCAST, &pgs); if(result){ if(result->status){ delete result; THROW(E_8K_GUI, "Failed to start the game!"); } delete result; } } } TLocalMulti::TLocalMulti(TContextParameter contextparameter) { rmtxti = (rm::TRM_txt_i*)KSendGlobalMessage(MSG_GET_RM_TXT_I, MOD_GUI, MOD_RM, NULL); } TLocalMulti::~TLocalMulti() { // vypusti a odalokuje vsechny aktivni prvky v sobe (rekursivne) DelNFreeAll(); delete rmtxti; } TContext* TLocalMulti::createContext(...){ TLocalMulti* n = new TLocalMulti(TContextParameter()); strcpy(n->szName,"LOCALMULTI"); return n; } void TLocalMulti::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 = true; // cislo mapy mapnumber = *((int*)&contextparameter.iSecondary); //hlavni okno mainwindow = new TLocalMultiWindow(mapnumber); Add(mainwindow); //noticka notice = NULL; } void TLocalMulti::deactivateContext() { DelNFreeAll(); } void TLocalMulti::drawContext(){ TFrame::drawObject(); } int TLocalMulti::workInput(INPUT *input) { int ret=TContext::workInput(input); //zpravicka if(notice){ if CLICKED(notice->bok) { Del(notice); delete notice; notice = NULL; } } // hlavni menu if (mainwindow) { if CLICKED(mainwindow->bplay) { // kontrola, ze je prirazen lidskej hrac bool playerused = false; for (int i = 1; i <= MAX_PLAYERS ; i++){ if (mainwindow->players[i].type == MPT_MAINHUMAN || mainwindow->players[i].type == MPT_HUMAN){ playerused = true; break; } } if (!playerused) { notice = new TErrorWindow(TEXT_HUMAN_PLAYER, ewtNotice, true); Add(notice); return ret; } // vynuluj pripojene mainwindow->players_connected = 0; // pripoj asynchronne lokalni klienty for (int j = 1; j < MAX_PLAYERS+1 ; j++){ if (mainwindow->players[j].type != MPT_UNUSED){ //osetri prazdna jmena if (strlen(mainwindow->players[j].name) == 0) snprintf(mainwindow->players[j].name, ROLE_RIGHT_LENGTH, "Noname%02d", j); //vytor lokalniho KSendGlobalMsg(MSG_ADD_LOCAL_CLIENT, ANNONYMOUS, MOD_NET, (PARAM)mainwindow->players[j].name); } }//for return ret; }//if if CLICKED(mainwindow->bback) { KSendGlobalMsg(MSG_NET_STOP, ANNONYMOUS, MOD_NET, NULL); TGUI::gui_inst->screen->selectContext("MAINMENU", TContextParameter(context_localmultigame, 0) ); return ret; } if CLICKED(mainwindow->roleslist) { mainwindow->updateLocalGameForm(); return ret; } if CLICKED(mainwindow->rbprimaryplayer){ int oldmain = 1, newmain; while ((oldmain <= MAX_PLAYERS) && (mainwindow->players[oldmain].type != MPT_MAINHUMAN)) oldmain++; newmain = mainwindow->getSelectedRole(); if (oldmain <= MAX_PLAYERS) { mainwindow->players[oldmain].type = mainwindow->players[newmain].type; strcpy(mainwindow->players[oldmain].name, mainwindow->players[newmain].name); } strcpy(mainwindow->players[newmain].name, ""); mainwindow->players[newmain].type = MPT_MAINHUMAN; mainwindow->updateLocalGameForm(); return ret; } if (CLICKED(mainwindow->rbotherplayer) || CLICKED(mainwindow->tfotherplayename)) { int newother = mainwindow->getSelectedRole(); mainwindow->players[newother].type = MPT_HUMAN; WideChartoUTF8(mainwindow->tfotherplayename->getText(), mainwindow->players[newother].name, MAX_STRLEN); mainwindow->updateLocalGameForm(); return ret; } if (CLICKED(mainwindow->rbai) || CLICKED(mainwindow->lbdificulty)){ int newai = mainwindow->getSelectedRole(); int wai = mainwindow->lbdificulty->getSelection(); if (wai == -1) { mainwindow->iai2->setState(AO_YES); wai = 1; } mainwindow->players[newai].type = (MYROLETYPE)((int)MPT_AI_1 + wai); mainwindow->updateLocalGameForm(); return ret; } if ((input->type == INPUT_KEY_DOWN) && FOCUSED(mainwindow->tfotherplayename)) { int newother = mainwindow->getSelectedRole(); WideChartoUTF8(mainwindow->tfotherplayename->getText(), mainwindow->players[newother].name, MAX_STRLEN); mainwindow->updateLocalGameForm(); } }//if mainwindow return ret; } }//namespace /*****************************************************************************/