mirror of
https://github.com/kevinbentley/Descent3.git
synced 2025-01-22 19:55:23 +00:00
916 lines
28 KiB
C++
916 lines
28 KiB
C++
/*
|
|
* Descent 3
|
|
* Copyright (C) 2024 Parallax Software
|
|
*
|
|
* This program is free software: you can redistribute it and/or modify
|
|
* it under the terms of the GNU General Public License as published by
|
|
* the Free Software Foundation, either version 3 of the License, or
|
|
* (at your option) any later version.
|
|
*
|
|
* This program is distributed in the hope that it will be useful,
|
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
* GNU General Public License for more details.
|
|
*
|
|
* You should have received a copy of the GNU General Public License
|
|
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
|
|
|
--- HISTORICAL COMMENTS FOLLOW ---
|
|
|
|
* $Logfile: /DescentIII/Main/Dmfc/dmfcui.cpp $
|
|
* $Revision: 1.1.1.1 $
|
|
* $Date: 2003/08/26 03:57:21 $
|
|
* $Author: kevinb $
|
|
*
|
|
* UI Code for DMFC dialogs
|
|
*
|
|
* $Log: dmfcui.cpp,v $
|
|
* Revision 1.1.1.1 2003/08/26 03:57:21 kevinb
|
|
* initial 1.5 import
|
|
*
|
|
*
|
|
* 26 7/09/99 2:54p Jeff
|
|
* handle gametime better (pause it when needed) if the server is 'waiting
|
|
* for players'
|
|
*
|
|
* 25 5/19/99 2:40a Jeff
|
|
* use correct calls of NewUIGameWindow
|
|
*
|
|
* 24 5/18/99 7:14p Jeff
|
|
* error checking
|
|
*
|
|
* 23 4/27/99 12:36p Jeff
|
|
* fixed dialog due to new art
|
|
*
|
|
* 22 4/24/99 11:13p Jeff
|
|
* added flags for creating a newui window for a title bar
|
|
*
|
|
* 21 4/09/99 3:28p Jeff
|
|
* fixed some bugs in wait for players dlg
|
|
*
|
|
* 20 4/03/99 9:26p Jeff
|
|
* changed dialogs that weren't using UID_OK and UID_CANCEL to use and
|
|
* handle them properly
|
|
*
|
|
* 19 3/17/99 12:25p Jeff
|
|
* converted DMFC to be COM interface
|
|
*
|
|
* 18 2/11/99 12:51a Jeff
|
|
* changed names of exported variables
|
|
*
|
|
* 17 2/09/99 3:32p Jeff
|
|
* table file parser takes quotes strings for force keywords
|
|
*
|
|
* 16 2/07/99 1:18a Jeff
|
|
* peppered UI dialogs that were missing NEWUIRES_FORCEQUIT to handle it
|
|
*
|
|
* 15 2/05/99 8:24p Jeff
|
|
* added table file parser macros
|
|
*
|
|
* 14 1/19/99 3:55a Jeff
|
|
* all strings localized out
|
|
*
|
|
* 13 1/14/99 7:55p Jeff
|
|
* changed icons for team selection dialog, added real powerball
|
|
*
|
|
* 12 1/12/99 2:55p Jeff
|
|
* added/finished the waiting for player's to join dialog
|
|
*
|
|
* 11 1/11/99 6:54p Jeff
|
|
* fixed bug with wait4player dialog
|
|
*
|
|
* 10 1/10/99 7:41p Jeff
|
|
* added initial version of waitforplayers dialog
|
|
*
|
|
* 9 12/08/98 3:29p Jeff
|
|
* updated the team control dialog so the server can determine if they
|
|
* want to make the clients wait
|
|
*
|
|
* 8 12/08/98 12:17p Jeff
|
|
* various changes that include an improved Team Control dialog (doesn't
|
|
* switch teams until exit..) and spew/respawn players that change teams
|
|
*
|
|
* 7 11/19/98 5:56p Jeff
|
|
* added slider exported and improved Hoard
|
|
*
|
|
* 6 11/17/98 6:29p Jeff
|
|
* mod can specify whether or not to display the team setup dialog on team
|
|
* game start. Added a menu item to display team setup dialog in mid-game
|
|
*
|
|
* 5 11/17/98 12:35p Jeff
|
|
* fixed bug where team placement window didn't update second time
|
|
* displayed
|
|
*
|
|
* 4 11/16/98 5:35p Jeff
|
|
* removed log functions, added support for changing team names, fixed ctf
|
|
* to work better with different team names
|
|
*
|
|
* 3 11/11/98 7:19p Jeff
|
|
* changes made so that a dedicated server's team is always -1 (team game
|
|
* or not)
|
|
*
|
|
* 2 10/29/98 7:01p Jeff
|
|
* creation of team placement dialog. Moved TranslateEvent into DMFC
|
|
*
|
|
* $NoKeywords: $
|
|
*/
|
|
|
|
#include "gamedll_header.h"
|
|
#include "DMFC.h"
|
|
#include "dmfcinternal.h"
|
|
|
|
extern DMFCBase *basethis;
|
|
|
|
struct tTeamPlacementDialogInfo {
|
|
void *lb[DLLMAX_TEAMS];
|
|
void *text[DLLMAX_PLAYERS];
|
|
int trans[DLLMAX_TEAMS][DLLMAX_PLAYERS];
|
|
void (*old_callback)();
|
|
};
|
|
tTeamPlacementDialogInfo tpdi;
|
|
|
|
#define TS_NOTINGAME -2
|
|
int8_t TeamDlgInitialTeamSettings[DLLMAX_PLAYERS];
|
|
int8_t TeamDlgFinalTeamSettings[DLLMAX_PLAYERS];
|
|
|
|
// UpdateTeamPlacementDialog
|
|
//
|
|
// Call to update the listboxes, etc in the team placement
|
|
void UpdateTeamPlacementDialog(void) {
|
|
int selected_num[DLLMAX_TEAMS];
|
|
int i;
|
|
|
|
for (i = 0; i < DLLMAX_TEAMS; i++) {
|
|
selected_num[i] = -1;
|
|
|
|
// remove everything from the listboxes
|
|
// save the selected names, and reselect them if they are on the same listbox
|
|
if (tpdi.lb[i]) {
|
|
int sel = DLLListGetSelectedIndex(tpdi.lb[i]);
|
|
|
|
if (sel >= 0 && sel < DLLMAX_PLAYERS)
|
|
selected_num[i] = tpdi.trans[i][sel];
|
|
|
|
DLLListRemoveAll(tpdi.lb[i]);
|
|
}
|
|
}
|
|
|
|
int curr_lb_count[DLLMAX_TEAMS];
|
|
for (i = 0; i < DLLMAX_TEAMS; i++) {
|
|
curr_lb_count[i] = 0;
|
|
for (int p = 0; p < DLLMAX_PLAYERS; p++) {
|
|
tpdi.trans[i][p] = -1;
|
|
}
|
|
}
|
|
|
|
// now rebuild the listboxes with correct placement
|
|
for (i = 0; i < DLLMAX_PLAYERS; i++) {
|
|
|
|
if (tpdi.text[i]) {
|
|
DLLRemoveUITextItem(tpdi.text[i]);
|
|
tpdi.text[i] = NULL;
|
|
}
|
|
|
|
// as we go through all the players, we need to update the trans[][]
|
|
if (basethis->CheckPlayerNum(i)) {
|
|
// the player is in the game, get their team
|
|
int team;
|
|
|
|
if (TeamDlgFinalTeamSettings[i] != TS_NOTINGAME) {
|
|
// ok this guy was in the game when the dialog first got displayed, so
|
|
// use his current status, and not his real team
|
|
team = TeamDlgFinalTeamSettings[i];
|
|
} else {
|
|
// he wasn't in the game to start and his team hasn't changed yet
|
|
team = basethis->GetPlayerTeam(i);
|
|
}
|
|
|
|
// add them to a team
|
|
if (tpdi.lb[team]) {
|
|
tpdi.text[i] = DLLCreateNewUITextItem(basethis->Players[i].callsign, basethis->GetTeamColor(team), -1);
|
|
if (tpdi.text[i]) {
|
|
DLLListAddItem(tpdi.lb[team], tpdi.text[i]);
|
|
tpdi.trans[team][curr_lb_count[team]] = i; // update the translator
|
|
curr_lb_count[team]++;
|
|
} else
|
|
mprintf(0, "Couldn't create text item\n");
|
|
} else {
|
|
mprintf(0, "Listbox not valid!\n");
|
|
}
|
|
} else {
|
|
TeamDlgInitialTeamSettings[i] = TeamDlgFinalTeamSettings[i] = TS_NOTINGAME;
|
|
}
|
|
}
|
|
|
|
// go through all the listboxes, and reselect previously selected
|
|
for (i = 0; i < DLLMAX_TEAMS; i++) {
|
|
if (selected_num[i] != -1 && basethis->CheckPlayerNum(selected_num[i])) {
|
|
|
|
if (((TeamDlgFinalTeamSettings[selected_num[i]] == TS_NOTINGAME) &&
|
|
(basethis->GetPlayerTeam(selected_num[i]) == i)) ||
|
|
(TeamDlgFinalTeamSettings[selected_num[i]] == i)) {
|
|
// this player was on this team last update, is still on the team, is a valid player in the game and was
|
|
// selected so select them again
|
|
for (int j = 0; j < DLLMAX_PLAYERS; j++) {
|
|
if (tpdi.trans[i][j] == selected_num[i]) {
|
|
// we found em, reselect
|
|
if (tpdi.lb[i]) {
|
|
DLLListSetSelectedIndex(tpdi.lb[i], j);
|
|
}
|
|
break;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
static float Team_placement_lastcall = 0;
|
|
void TeamPlacementCallback(void) {
|
|
float time = *basethis->Gametime;
|
|
|
|
if (time > Team_placement_lastcall + 0.5f) {
|
|
UpdateTeamPlacementDialog();
|
|
Team_placement_lastcall = time;
|
|
}
|
|
|
|
if (tpdi.old_callback)
|
|
(*tpdi.old_callback)();
|
|
}
|
|
|
|
void TeamPlacementChangeTeam(int old_team, int new_team) {
|
|
int sel = DLLListGetSelectedIndex(tpdi.lb[old_team]);
|
|
if (sel < 0)
|
|
return;
|
|
|
|
int pnum = tpdi.trans[old_team][sel];
|
|
if (!basethis->CheckPlayerNum(pnum)) {
|
|
TeamDlgInitialTeamSettings[pnum] = TeamDlgFinalTeamSettings[pnum] = TS_NOTINGAME;
|
|
return;
|
|
}
|
|
|
|
TeamDlgFinalTeamSettings[pnum] = new_team;
|
|
}
|
|
|
|
#define REDTOBLUE 0xC0
|
|
#define REDTOGREEN 0xC1
|
|
#define REDTOYELLOW 0xC2
|
|
#define BLUETORED 0xC3
|
|
#define BLUETOGREEN 0xC4
|
|
#define BLUETOYELLOW 0xC5
|
|
#define GREENTORED 0xC6
|
|
#define GREENTOBLUE 0xC7
|
|
#define GREENTOYELLOW 0xC8
|
|
#define YELLOWTORED 0xC9
|
|
#define YELLOWTOBLUE 0xCA
|
|
#define YELLOWTOGREEN 0xCB
|
|
|
|
// DMFCBase::DoDMFCUITeamPlacement
|
|
//
|
|
// Displays the dialog for doing team placement in DMFC
|
|
void DMFCBase::DoDMFCUITeamPlacement(bool clients_wait, bool called_by_level_start) {
|
|
if (GetLocalRole() != LR_SERVER)
|
|
return;
|
|
|
|
if (IAmDedicatedServer())
|
|
return;
|
|
|
|
Team_placement_lastcall = 0;
|
|
|
|
// turn on client waiting
|
|
if (clients_wait) {
|
|
// Pause realgametime,
|
|
ENABLE_FLAGS(m_iProtectedFlags, DMFC_PRF_PAUSETIME);
|
|
SendControlMessageToPlayer(SP_ALL, CM_PAUSETIME);
|
|
MakeClientsWait(true);
|
|
}
|
|
|
|
int i;
|
|
|
|
// build the initial team list, so we know what players changed teams in the process
|
|
for (i = 0; i < DLLMAX_PLAYERS; i++) {
|
|
if (CheckPlayerNum(i)) {
|
|
TeamDlgFinalTeamSettings[i] = TeamDlgInitialTeamSettings[i] = Players[i].team;
|
|
} else {
|
|
TeamDlgFinalTeamSettings[i] = TeamDlgInitialTeamSettings[i] = TS_NOTINGAME;
|
|
}
|
|
}
|
|
|
|
bool exit_menu = false;
|
|
void *list_red = NULL, *list_blue = NULL, *list_green = NULL, *list_yellow = NULL;
|
|
void *icon_b_hs[DLLMAX_TEAMS][DLLMAX_TEAMS - 1];
|
|
void *icon_hs[DLLMAX_TEAMS][DLLMAX_TEAMS - 1];
|
|
void *team_text[DLLMAX_TEAMS];
|
|
|
|
int count;
|
|
int id_list[DLLMAX_TEAMS * (DLLMAX_TEAMS - 1)];
|
|
|
|
int team_icons[DLLMAX_TEAMS];
|
|
const char *team_icon_names[DLLMAX_TEAMS] = {"toredteamicon.ogf", "toblueteamicon.ogf", "togreenteamicon.ogf", "toyellowteamicon.ogf"};
|
|
/*
|
|
$$TABLE_GAMEFILE "toredteamicon.ogf"
|
|
$$TABLE_GAMEFILE "toblueteamicon.ogf"
|
|
$$TABLE_GAMEFILE "togreenteamicon.ogf"
|
|
$$TABLE_GAMEFILE "toyellowteamicon.ogf"
|
|
*/
|
|
for (i = 0; i < DLLMAX_TEAMS; i++) {
|
|
team_icons[i] = DLLbm_AllocLoadFileBitmap(IGNORE_TABLE(team_icon_names[i]), 0, BITMAP_FORMAT_1555);
|
|
if (team_icons[i] <= BAD_BITMAP_HANDLE)
|
|
team_icons[i] = BAD_BITMAP_HANDLE;
|
|
}
|
|
|
|
for (i = 0; i < DLLMAX_TEAMS; i++) {
|
|
count = 0;
|
|
for (int j = 0; j < DLLMAX_TEAMS; j++) {
|
|
if (i != j) {
|
|
icon_b_hs[i][count] = DLLCreateNewUIBmpItem(team_icons[j], 255);
|
|
icon_hs[i][count] = NULL;
|
|
count++;
|
|
}
|
|
}
|
|
}
|
|
|
|
for (i = 0; i < DLLMAX_TEAMS * (DLLMAX_TEAMS - 1); i++) {
|
|
id_list[i] = 0xC0 + i;
|
|
}
|
|
|
|
for (i = 0; i < DLLMAX_TEAMS; i++) {
|
|
team_text[i] = NULL;
|
|
}
|
|
|
|
//////////////////////////////////////////////////
|
|
// Text Items
|
|
void *start_game_text_off =
|
|
DLLCreateNewUITextItem((called_by_level_start) ? DTXT_UI_STARTGAME : DTXT_UI_RETURNTOGAME, UICOL_HOTSPOT_LO, -1);
|
|
void *start_game_text_on =
|
|
DLLCreateNewUITextItem((called_by_level_start) ? DTXT_UI_STARTGAME : DTXT_UI_RETURNTOGAME, UICOL_HOTSPOT_HI, -1);
|
|
void *client_wait_txt = DLLCreateNewUITextItem(DTXT_UI_CLIENTSWAIT, UICOL_HOTSPOT_LO, -1);
|
|
void *window_title = DLLCreateNewUITextItem(DTXT_UI_TEAMSETUP, UICOL_WINDOW_TITLE, -1);
|
|
|
|
///////////////////////////////////////////////////
|
|
// Main Window
|
|
void *main_wnd = DLLNewUIGameWindowCreate(0, 0, 512, 384, UIF_PROCESS_ALL | UIF_CENTER | NUWF_TITLEMED);
|
|
|
|
///////////////////////////////////////////////////
|
|
// Item placement
|
|
int cury;
|
|
count = GetNumTeams();
|
|
|
|
void *start_game_hs = DLLHotSpotCreate(main_wnd, UID_OK, K_ENTER, start_game_text_off, start_game_text_on, 40,
|
|
384 - OKCANCEL_YOFFSET, 130, 15, UIF_CENTER);
|
|
void *window_title_text = DLLTextCreate(main_wnd, window_title, 0, 7, UIF_CENTER | UIF_FIT);
|
|
void *client_wait_cb;
|
|
|
|
if (count > 2) {
|
|
client_wait_cb = DLLCheckBoxCreate(main_wnd, 128, client_wait_txt, 256 - (DLLGetUIItemWidth(client_wait_txt) / 2),
|
|
192 - (DLLGetUIItemHeight(client_wait_txt) / 2), 130, 15, UIF_FIT);
|
|
cury = 60;
|
|
} else {
|
|
client_wait_cb = DLLCheckBoxCreate(main_wnd, 128, client_wait_txt, 30, 384 - OKCANCEL_YOFFSET, 130, 15, UIF_FIT);
|
|
cury = 80;
|
|
}
|
|
|
|
DLLCheckBoxSetCheck(client_wait_cb, clients_wait);
|
|
|
|
int left_x, right_x;
|
|
int top_y, bottom_y;
|
|
int icon_width = DLLbm_w(team_icons[0], 0);
|
|
int icon_height = DLLbm_h(team_icons[0], 0);
|
|
int curr_y;
|
|
int *id_list_ptr;
|
|
|
|
left_x = 168 + 10;
|
|
right_x = 512 - 178 - icon_width;
|
|
|
|
int total_height = (count - 1) * (icon_height + 3);
|
|
top_y = cury + (64 - (total_height / 2));
|
|
bottom_y = cury + 163 + (64 - (total_height / 2));
|
|
|
|
switch (count) {
|
|
case 4:
|
|
list_yellow = DLLListCreate(main_wnd, 1, 512 - 168, cury + 163, 128, 128, 0);
|
|
team_text[YELLOW_TEAM] = DLLEditCreate(main_wnd, -1, 512 - 168, cury + 131, 128, 32, 0);
|
|
|
|
// put in the hotspots for yellow
|
|
curr_y = bottom_y;
|
|
id_list_ptr = &id_list[YELLOW_TEAM * (DLLMAX_TEAMS - 1)];
|
|
for (i = 0; i < count - 1; i++) {
|
|
icon_hs[YELLOW_TEAM][i] =
|
|
DLLHotSpotCreate(main_wnd, id_list_ptr[i], -1, icon_b_hs[YELLOW_TEAM][i], icon_b_hs[YELLOW_TEAM][i], right_x,
|
|
curr_y, icon_width, icon_height, 0);
|
|
curr_y += icon_height + 3;
|
|
}
|
|
case 3:
|
|
list_green = DLLListCreate(main_wnd, 1, 40, cury + 163, 128, 128, 0);
|
|
team_text[GREEN_TEAM] = DLLEditCreate(main_wnd, -1, 40, cury + 131, 128, 32, 0);
|
|
|
|
list_red = DLLListCreate(main_wnd, 0, 40, cury, 128, 128, 0);
|
|
team_text[RED_TEAM] = DLLEditCreate(main_wnd, -1, 40, cury - 32, 128, 32, 0);
|
|
|
|
list_blue = DLLListCreate(main_wnd, 1, 512 - 168, cury, 128, 128, 0);
|
|
team_text[BLUE_TEAM] = DLLEditCreate(main_wnd, -1, 512 - 168, cury - 32, 128, 32, 0);
|
|
|
|
// put in the hotspots for green
|
|
curr_y = bottom_y;
|
|
id_list_ptr = &id_list[GREEN_TEAM * (DLLMAX_TEAMS - 1)];
|
|
for (i = 0; i < count - 1; i++) {
|
|
icon_hs[GREEN_TEAM][i] = DLLHotSpotCreate(main_wnd, id_list_ptr[i], -1, icon_b_hs[GREEN_TEAM][i],
|
|
icon_b_hs[GREEN_TEAM][i], left_x, curr_y, icon_width, icon_height, 0);
|
|
curr_y += icon_height + 3;
|
|
}
|
|
|
|
// put in the hotspots for blue
|
|
curr_y = top_y;
|
|
id_list_ptr = &id_list[BLUE_TEAM * (DLLMAX_TEAMS - 1)];
|
|
for (i = 0; i < count - 1; i++) {
|
|
icon_hs[BLUE_TEAM][i] = DLLHotSpotCreate(main_wnd, id_list_ptr[i], -1, icon_b_hs[BLUE_TEAM][i],
|
|
icon_b_hs[BLUE_TEAM][i], right_x, curr_y, icon_width, icon_height, 0);
|
|
curr_y += icon_height + 3;
|
|
}
|
|
|
|
// put in the hotspots for red
|
|
curr_y = top_y;
|
|
id_list_ptr = &id_list[RED_TEAM * (DLLMAX_TEAMS - 1)];
|
|
for (i = 0; i < count - 1; i++) {
|
|
icon_hs[RED_TEAM][i] = DLLHotSpotCreate(main_wnd, id_list_ptr[i], -1, icon_b_hs[RED_TEAM][i],
|
|
icon_b_hs[RED_TEAM][i], left_x, curr_y, icon_width, icon_height, 0);
|
|
curr_y += icon_height + 3;
|
|
}
|
|
|
|
break;
|
|
case 2:
|
|
list_red = DLLListCreate(main_wnd, 0, 40, cury, 128, 224, 0);
|
|
team_text[RED_TEAM] = DLLEditCreate(main_wnd, -1, 40, cury - 32, 128, 32, 0);
|
|
|
|
list_blue = DLLListCreate(main_wnd, 1, 512 - 168, cury, 128, 224, 0);
|
|
team_text[BLUE_TEAM] = DLLEditCreate(main_wnd, -1, 512 - 168, cury - 32, 128, 32, 0);
|
|
|
|
// recalc the top y value
|
|
top_y = cury + (118 - (total_height / 2));
|
|
|
|
// put in the hotspots for blue
|
|
curr_y = top_y;
|
|
id_list_ptr = &id_list[BLUE_TEAM * (DLLMAX_TEAMS - 1)];
|
|
for (i = 0; i < count - 1; i++) {
|
|
icon_hs[BLUE_TEAM][i] = DLLHotSpotCreate(main_wnd, id_list_ptr[i], -1, icon_b_hs[BLUE_TEAM][i],
|
|
icon_b_hs[BLUE_TEAM][i], right_x, curr_y, icon_width, icon_height, 0);
|
|
curr_y += icon_height + 3;
|
|
}
|
|
|
|
// put in the hotspots for red
|
|
curr_y = top_y;
|
|
id_list_ptr = &id_list[RED_TEAM * (DLLMAX_TEAMS - 1)];
|
|
for (i = 0; i < count - 1; i++) {
|
|
icon_hs[RED_TEAM][i] = DLLHotSpotCreate(main_wnd, id_list_ptr[i], -1, icon_b_hs[RED_TEAM][i],
|
|
icon_b_hs[RED_TEAM][i], left_x, curr_y, icon_width, icon_height, 0);
|
|
curr_y += icon_height + 3;
|
|
}
|
|
|
|
break;
|
|
case 0:
|
|
case 1:
|
|
// the wait is over, let them in
|
|
if (clients_wait) {
|
|
// UnPause realgametime,
|
|
DISABLE_FLAGS(m_iProtectedFlags, DMFC_PRF_PAUSETIME);
|
|
SendControlMessageToPlayer(SP_ALL, CM_UNPAUSETIME);
|
|
MakeClientsWait(false);
|
|
}
|
|
|
|
// Unpause realgametime,
|
|
DISABLE_FLAGS(m_iProtectedFlags, DMFC_PRF_PAUSETIME);
|
|
SendControlMessageToPlayer(SP_ALL, CM_UNPAUSETIME);
|
|
return;
|
|
break;
|
|
}
|
|
|
|
// Set information for the team name edit boxes
|
|
for (i = 0; i < DLLMAX_TEAMS; i++) {
|
|
if (team_text[i]) {
|
|
DLLSetOldEditBufferLen(team_text[i], MAX_TEAMNAME_LEN - 1);
|
|
DLLEditSetText(team_text[i], DMFC_team_names[i]);
|
|
}
|
|
}
|
|
|
|
tpdi.lb[RED_TEAM] = list_red;
|
|
tpdi.lb[BLUE_TEAM] = list_blue;
|
|
tpdi.lb[GREEN_TEAM] = list_green;
|
|
tpdi.lb[YELLOW_TEAM] = list_yellow;
|
|
for (i = 0; i < DLLMAX_PLAYERS; i++) {
|
|
tpdi.text[i] = NULL;
|
|
for (int t = 0; t < DLLMAX_TEAMS; t++) {
|
|
tpdi.trans[t][i] = -1;
|
|
}
|
|
}
|
|
DLLGetUICallback((void **)&tpdi.old_callback);
|
|
DLLSetUICallback(TeamPlacementCallback);
|
|
|
|
//////////////////////////////////////////////////
|
|
// Process all
|
|
DLLNewUIGameWindowOpen(main_wnd);
|
|
|
|
UpdateTeamPlacementDialog();
|
|
|
|
bool canceled = false;
|
|
|
|
while (!exit_menu) {
|
|
int res;
|
|
res = DLLPollUI();
|
|
|
|
if (res == -1)
|
|
continue;
|
|
|
|
// handle all UI results.
|
|
switch (res) {
|
|
case REDTOBLUE:
|
|
TeamPlacementChangeTeam(RED_TEAM, BLUE_TEAM);
|
|
UpdateTeamPlacementDialog();
|
|
break;
|
|
case REDTOGREEN:
|
|
TeamPlacementChangeTeam(RED_TEAM, GREEN_TEAM);
|
|
UpdateTeamPlacementDialog();
|
|
break;
|
|
case REDTOYELLOW:
|
|
TeamPlacementChangeTeam(RED_TEAM, YELLOW_TEAM);
|
|
UpdateTeamPlacementDialog();
|
|
break;
|
|
case BLUETORED:
|
|
TeamPlacementChangeTeam(BLUE_TEAM, RED_TEAM);
|
|
UpdateTeamPlacementDialog();
|
|
break;
|
|
case BLUETOGREEN:
|
|
TeamPlacementChangeTeam(BLUE_TEAM, GREEN_TEAM);
|
|
UpdateTeamPlacementDialog();
|
|
break;
|
|
case BLUETOYELLOW:
|
|
TeamPlacementChangeTeam(BLUE_TEAM, YELLOW_TEAM);
|
|
UpdateTeamPlacementDialog();
|
|
break;
|
|
case GREENTORED:
|
|
TeamPlacementChangeTeam(GREEN_TEAM, RED_TEAM);
|
|
UpdateTeamPlacementDialog();
|
|
break;
|
|
case GREENTOBLUE:
|
|
TeamPlacementChangeTeam(GREEN_TEAM, BLUE_TEAM);
|
|
UpdateTeamPlacementDialog();
|
|
break;
|
|
case GREENTOYELLOW:
|
|
TeamPlacementChangeTeam(GREEN_TEAM, YELLOW_TEAM);
|
|
UpdateTeamPlacementDialog();
|
|
break;
|
|
case YELLOWTORED:
|
|
TeamPlacementChangeTeam(YELLOW_TEAM, RED_TEAM);
|
|
UpdateTeamPlacementDialog();
|
|
break;
|
|
case YELLOWTOBLUE:
|
|
TeamPlacementChangeTeam(YELLOW_TEAM, BLUE_TEAM);
|
|
UpdateTeamPlacementDialog();
|
|
break;
|
|
case YELLOWTOGREEN:
|
|
TeamPlacementChangeTeam(YELLOW_TEAM, GREEN_TEAM);
|
|
UpdateTeamPlacementDialog();
|
|
break;
|
|
case UID_OK: // start game
|
|
// get the team names and save them
|
|
for (i = 0; i < DLLMAX_TEAMS; i++) {
|
|
if (team_text[i]) {
|
|
char buff[MAX_TEAMNAME_LEN + 1];
|
|
DLLEditGetText(team_text[i], buff, MAX_TEAMNAME_LEN);
|
|
SetTeamName(i, buff, true);
|
|
}
|
|
}
|
|
|
|
exit_menu = true;
|
|
break;
|
|
case NEWUIRES_FORCEQUIT:
|
|
exit_menu = true;
|
|
canceled = true;
|
|
break;
|
|
case 128: // make clients wait on/off
|
|
{
|
|
if (DLLCheckBoxIsChecked(client_wait_cb)) {
|
|
// make the clients wait
|
|
clients_wait = true;
|
|
|
|
// Pause realgametime,
|
|
ENABLE_FLAGS(m_iProtectedFlags, DMFC_PRF_PAUSETIME);
|
|
SendControlMessageToPlayer(SP_ALL, CM_PAUSETIME);
|
|
} else {
|
|
// they no longer have to wait
|
|
clients_wait = false;
|
|
|
|
// UnPause realgametime,
|
|
DISABLE_FLAGS(m_iProtectedFlags, DMFC_PRF_PAUSETIME);
|
|
SendControlMessageToPlayer(SP_ALL, CM_UNPAUSETIME);
|
|
}
|
|
|
|
MakeClientsWait(clients_wait);
|
|
} break;
|
|
};
|
|
}
|
|
|
|
// Place all changed players!!!
|
|
if (!canceled) {
|
|
for (i = 0; i < DLLMAX_PLAYERS; i++) {
|
|
if (CheckPlayerNum(i)) {
|
|
// the player is in the game, update his team if needed
|
|
if (TeamDlgInitialTeamSettings[i] == TS_NOTINGAME) {
|
|
// this player was NOT in the game when we brought up the dialog
|
|
|
|
if (TeamDlgFinalTeamSettings[i] != TS_NOTINGAME) {
|
|
// we've changed his team though
|
|
int new_team;
|
|
new_team = TeamDlgFinalTeamSettings[i];
|
|
RequestTeamChange(new_team, i, false); // no need to spew his stuff
|
|
} else {
|
|
// we haven't changed his team, so he's ok on the team he's on
|
|
}
|
|
} else {
|
|
// this player was in the game when we brought up the dialog
|
|
if (TeamDlgInitialTeamSettings[i] != TeamDlgFinalTeamSettings[i]) {
|
|
// he has changed teams!!
|
|
int new_team;
|
|
if (TeamDlgFinalTeamSettings[i] != TS_NOTINGAME) {
|
|
new_team = TeamDlgFinalTeamSettings[i];
|
|
} else {
|
|
// weird...they are out of sync?
|
|
FatalError("Team Dialog Out Of Sync"); // remove later
|
|
}
|
|
RequestTeamChange(new_team, i, true); // spew his stuff also
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
// the wait is over, let them in
|
|
if (clients_wait) {
|
|
// UnPause realgametime,
|
|
DISABLE_FLAGS(m_iProtectedFlags, DMFC_PRF_PAUSETIME);
|
|
SendControlMessageToPlayer(SP_ALL, CM_UNPAUSETIME);
|
|
MakeClientsWait(false);
|
|
}
|
|
|
|
DLLNewUIGameWindowClose(main_wnd);
|
|
DLLNewUIGameWindowDestroy(main_wnd);
|
|
|
|
////////////////////////////////////////////
|
|
// Remove text items
|
|
DLLRemoveUITextItem(start_game_text_on);
|
|
DLLRemoveUITextItem(start_game_text_off);
|
|
DLLRemoveUITextItem(window_title);
|
|
DLLRemoveUITextItem(client_wait_txt);
|
|
for (i = 0; i < DLLMAX_PLAYERS; i++) {
|
|
if (tpdi.text[i]) {
|
|
DLLRemoveUITextItem(tpdi.text[i]);
|
|
tpdi.text[i] = NULL;
|
|
}
|
|
}
|
|
for (i = 0; i < DLLMAX_TEAMS; i++) {
|
|
for (int j = 0; j < DLLMAX_TEAMS - 1; j++) {
|
|
if (icon_b_hs[i][j])
|
|
DLLRemoveUIBmpItem(icon_b_hs[i][j]);
|
|
if (icon_hs[i][j])
|
|
DLLDeleteUIItem(icon_hs[i][j]);
|
|
}
|
|
}
|
|
|
|
////////////////////////////////////////////
|
|
// Remove all items
|
|
if (list_red)
|
|
DLLDeleteUIItem(list_red);
|
|
if (list_blue)
|
|
DLLDeleteUIItem(list_blue);
|
|
if (list_green)
|
|
DLLDeleteUIItem(list_green);
|
|
if (list_yellow)
|
|
DLLDeleteUIItem(list_yellow);
|
|
DLLDeleteUIItem(main_wnd);
|
|
DLLDeleteUIItem(start_game_hs);
|
|
DLLDeleteUIItem(window_title_text);
|
|
DLLDeleteUIItem(client_wait_cb);
|
|
|
|
for (i = 0; i < DLLMAX_TEAMS; i++) {
|
|
if (team_icons[i] > BAD_BITMAP_HANDLE)
|
|
DLLbm_FreeBitmap(team_icons[i]);
|
|
}
|
|
|
|
for (i = 0; i < DLLMAX_TEAMS; i++) {
|
|
if (team_text[i])
|
|
DLLDeleteUIItem(team_text[i]);
|
|
}
|
|
|
|
DLLSetUICallback(tpdi.old_callback);
|
|
}
|
|
|
|
//============================================================================
|
|
// Wait for Players Dialog
|
|
//============================================================================
|
|
struct tWaitForPlayers {
|
|
float last_update;
|
|
void (*old_callback)(void);
|
|
void *listbox;
|
|
void *text[DLLMAX_PLAYERS];
|
|
int indexmap[DLLMAX_PLAYERS];
|
|
};
|
|
tWaitForPlayers wfpi;
|
|
|
|
void UpdateWaitForPlayersDialog(void) {
|
|
int pnum = -1;
|
|
|
|
int sel = DLLListGetSelectedIndex(wfpi.listbox);
|
|
if (sel >= 0) {
|
|
pnum = wfpi.indexmap[sel];
|
|
}
|
|
|
|
int index = 0;
|
|
DLLListRemoveAll(wfpi.listbox);
|
|
for (int i = 0; i < DLLMAX_PLAYERS; i++) {
|
|
if (wfpi.text[i]) {
|
|
DLLRemoveUITextItem(wfpi.text[i]);
|
|
wfpi.text[i] = NULL;
|
|
}
|
|
|
|
if (basethis->CheckPlayerNum(i)) {
|
|
wfpi.indexmap[index] = i;
|
|
index++;
|
|
wfpi.text[i] = DLLCreateNewUITextItem(basethis->Players[i].callsign, basethis->Player_colors[i], -1);
|
|
DLLListAddItem(wfpi.listbox, wfpi.text[i]);
|
|
if (pnum == i) {
|
|
DLLListSetSelectedIndex(wfpi.listbox, i);
|
|
}
|
|
}
|
|
}
|
|
}
|
|
void WaitForPlayersCallback(void) {
|
|
float time = *basethis->Gametime;
|
|
|
|
if (time > wfpi.last_update + 0.5f) {
|
|
UpdateWaitForPlayersDialog();
|
|
wfpi.last_update = time;
|
|
}
|
|
|
|
if (wfpi.old_callback)
|
|
(*wfpi.old_callback)();
|
|
}
|
|
|
|
// DMFCBase::DoDMFCUIWaitForPlayers
|
|
//
|
|
// Displays the dialog for in the beginning of the level, waiting for all the players
|
|
void DMFCBase::DoDMFCUIWaitForPlayers(bool clients_wait) {
|
|
if (GetLocalRole() != LR_SERVER)
|
|
return;
|
|
|
|
if (IAmDedicatedServer())
|
|
return;
|
|
|
|
wfpi.last_update = 0;
|
|
int i;
|
|
for (i = 0; i < DLLMAX_PLAYERS; i++)
|
|
wfpi.text[i] = NULL;
|
|
|
|
// turn on client waiting
|
|
if (clients_wait) {
|
|
// Pause realgametime,
|
|
ENABLE_FLAGS(m_iProtectedFlags, DMFC_PRF_PAUSETIME);
|
|
SendControlMessageToPlayer(SP_ALL, CM_PAUSETIME);
|
|
MakeClientsWait(true);
|
|
}
|
|
|
|
for (i = 0; i < DLLMAX_PLAYERS; i++)
|
|
wfpi.indexmap[i] = 0;
|
|
|
|
///////////////////////////////////////////////////
|
|
// Text Items
|
|
void *start_game_text_off = DLLCreateNewUITextItem(DTXT_UI_STARTGAME, UICOL_HOTSPOT_LO, -1);
|
|
void *start_game_text_on = DLLCreateNewUITextItem(DTXT_UI_STARTGAME, UICOL_HOTSPOT_HI, -1);
|
|
void *client_wait_txt = DLLCreateNewUITextItem(DTXT_UI_CLIENTSWAIT, UICOL_HOTSPOT_LO, -1);
|
|
void *window_title = DLLCreateNewUITextItem(DTXT_UI_WAITFORPLAYERS, UICOL_WINDOW_TITLE, -1);
|
|
void *kick_text_off = DLLCreateNewUITextItem(DTXT_UI_KICKPLAYER, UICOL_HOTSPOT_LO, -1);
|
|
void *kick_text_on = DLLCreateNewUITextItem(DTXT_UI_KICKPLAYER, UICOL_HOTSPOT_HI, -1);
|
|
void *ban_text_off = DLLCreateNewUITextItem(DTXT_UI_BANPLAYER, UICOL_HOTSPOT_LO, -1);
|
|
void *ban_text_on = DLLCreateNewUITextItem(DTXT_UI_BANPLAYER, UICOL_HOTSPOT_HI, -1);
|
|
|
|
///////////////////////////////////////////////////
|
|
// Main Window
|
|
void *main_wnd = DLLNewUIGameWindowCreate(0, 0, 512, 384, UIF_PROCESS_ALL | UIF_CENTER | NUWF_TITLEMED);
|
|
|
|
///////////////////////////////////////////////////
|
|
// Item placement
|
|
int cury = 30;
|
|
bool exit_menu = false;
|
|
|
|
void *start_game_hs = DLLHotSpotCreate(main_wnd, UID_OK, K_ENTER, start_game_text_off, start_game_text_on, 40,
|
|
384 - OKCANCEL_YOFFSET, 130, 15, UIF_CENTER);
|
|
void *window_title_text = DLLTextCreate(main_wnd, window_title, 0, 7, UIF_CENTER | UIF_FIT);
|
|
void *client_wait_cb =
|
|
DLLCheckBoxCreate(main_wnd, 128, client_wait_txt, 30, 369 - OKCANCEL_YOFFSET, 130, 15, UIF_FIT | UIF_CENTER);
|
|
wfpi.listbox = DLLListCreate(main_wnd, -1, 40, cury, 256, 288, UIF_CENTER);
|
|
DLLCheckBoxSetCheck(client_wait_cb, clients_wait);
|
|
|
|
int l_x, l_y, l_w, l_h;
|
|
DLLGetUIItemPosition(wfpi.listbox, &l_x, &l_y, &l_w, &l_h);
|
|
l_x = l_x + l_w + 10;
|
|
l_y = (l_y + (l_h / 2)) - 15;
|
|
void *kick_hs = DLLHotSpotCreate(main_wnd, 10, -1, kick_text_off, kick_text_on, l_x, l_y, 130, 15, UIF_FIT);
|
|
l_y += 15;
|
|
void *ban_hs = DLLHotSpotCreate(main_wnd, 20, -1, ban_text_off, ban_text_on, l_x, l_y, 130, 15, UIF_FIT);
|
|
|
|
//////////////////////////////////////////////////
|
|
// Process all
|
|
DLLGetUICallback((void **)&wfpi.old_callback);
|
|
DLLSetUICallback(WaitForPlayersCallback);
|
|
|
|
DLLNewUIGameWindowOpen(main_wnd);
|
|
|
|
UpdateWaitForPlayersDialog();
|
|
|
|
mprintf(0, "1:Entering UI Loop\n");
|
|
|
|
while (!exit_menu) {
|
|
int res;
|
|
res = DLLPollUI();
|
|
|
|
if (res == -1) {
|
|
continue;
|
|
}
|
|
switch (res) {
|
|
case NEWUIRES_FORCEQUIT:
|
|
mprintf(0, "1:Got a force quit\n");
|
|
exit_menu = true;
|
|
break;
|
|
case UID_OK: // exit menu
|
|
mprintf(0, "1:Got a regular quit\n");
|
|
exit_menu = true;
|
|
break;
|
|
case 10: // kick player
|
|
{
|
|
int cursel = DLLListGetSelectedIndex(wfpi.listbox);
|
|
int pnum = wfpi.indexmap[cursel];
|
|
KickPlayer(pnum);
|
|
} break;
|
|
case 20: // ban player
|
|
{
|
|
int cursel = DLLListGetSelectedIndex(wfpi.listbox);
|
|
int pnum = wfpi.indexmap[cursel];
|
|
BanPlayer(pnum);
|
|
} break;
|
|
case 128: // make clients wait on/off
|
|
{
|
|
if (DLLCheckBoxIsChecked(client_wait_cb)) {
|
|
// make the clients wait
|
|
clients_wait = true;
|
|
// Pause realgametime,
|
|
ENABLE_FLAGS(m_iProtectedFlags, DMFC_PRF_PAUSETIME);
|
|
SendControlMessageToPlayer(SP_ALL, CM_PAUSETIME);
|
|
} else {
|
|
// they no longer have to wait
|
|
clients_wait = false;
|
|
// UnPause realgametime,
|
|
DISABLE_FLAGS(m_iProtectedFlags, DMFC_PRF_PAUSETIME);
|
|
SendControlMessageToPlayer(SP_ALL, CM_UNPAUSETIME);
|
|
}
|
|
MakeClientsWait(clients_wait);
|
|
} break;
|
|
};
|
|
}
|
|
|
|
mprintf(0, "1:Out of UI Loop\n");
|
|
|
|
// the wait is over, let them in
|
|
if (clients_wait) {
|
|
// Unpause realgametime,
|
|
DISABLE_FLAGS(m_iProtectedFlags, DMFC_PRF_PAUSETIME);
|
|
SendControlMessageToPlayer(SP_ALL, CM_UNPAUSETIME);
|
|
MakeClientsWait(false);
|
|
}
|
|
|
|
DLLNewUIGameWindowClose(main_wnd);
|
|
DLLNewUIGameWindowDestroy(main_wnd);
|
|
|
|
DLLRemoveUITextItem(start_game_text_on);
|
|
DLLRemoveUITextItem(start_game_text_off);
|
|
DLLRemoveUITextItem(kick_text_off);
|
|
DLLRemoveUITextItem(kick_text_on);
|
|
DLLRemoveUITextItem(ban_text_off);
|
|
DLLRemoveUITextItem(ban_text_on);
|
|
DLLRemoveUITextItem(window_title);
|
|
DLLRemoveUITextItem(client_wait_txt);
|
|
for (i = 0; i < DLLMAX_PLAYERS; i++) {
|
|
if (wfpi.text[i]) {
|
|
DLLRemoveUITextItem(wfpi.text[i]);
|
|
wfpi.text[i] = NULL;
|
|
}
|
|
}
|
|
|
|
DLLDeleteUIItem(main_wnd);
|
|
DLLDeleteUIItem(start_game_hs);
|
|
DLLDeleteUIItem(window_title_text);
|
|
DLLDeleteUIItem(client_wait_cb);
|
|
DLLDeleteUIItem(wfpi.listbox);
|
|
DLLDeleteUIItem(kick_hs);
|
|
DLLDeleteUIItem(ban_hs);
|
|
|
|
DLLSetUICallback(wfpi.old_callback);
|
|
}
|