示例#1
0
/**
 * @brief Pops a window from the window stack
 * @param[in] all If true pop all windows from stack
 * @sa UI_PopWindow_f
 */
void UI_PopWindow (bool all)
{
	uiNode_t *oldfirst = ui_global.windowStack[0];

	if (all) {
		UI_CloseAllWindow();
	} else {
		uiNode_t *mainWindow = ui_global.windowStack[ui_global.windowStackPos - 1];
		if (!ui_global.windowStackPos)
			return;
		if (WINDOWEXTRADATA(mainWindow).parent)
			mainWindow = WINDOWEXTRADATA(mainWindow).parent;
		UI_CloseWindowByRef(mainWindow);

		if (ui_global.windowStackPos == 0) {
			/* ui_sys_main contains the window that is the very first window and should be
			 * pushed back onto the stack (otherwise there would be no window at all
			 * right now) */
			if (Q_streq(oldfirst->name, ui_sys_main->string)) {
				if (ui_sys_active->string[0] != '\0')
					UI_PushWindow(ui_sys_active->string);
				if (!ui_global.windowStackPos)
					UI_PushWindow(ui_sys_main->string);
			} else {
				if (ui_sys_main->string[0] != '\0')
					UI_PushWindow(ui_sys_main->string);
				if (!ui_global.windowStackPos)
					UI_PushWindow(ui_sys_active->string);
			}
		}
	}

	/* change from e.g. console mode to game input mode (fetch input) */
	Key_SetDest(key_game);
}
示例#2
0
/**
 * @brief Console function to push a child window onto the window stack
 * @sa UI_PushWindow
 */
static void UI_PushChildWindow_f (void)
{
	if (Cmd_Argc() > 1)
		UI_PushWindow(Cmd_Argv(1), Cmd_Argv(2));
	else
		Com_Printf("Usage: %s <name> <parentname>\n", Cmd_Argv(0));
}
示例#3
0
/**
 * @brief Popup on geoscape
 * @note Only use static strings here - or use popupText if you really have to
 * build the string
 */
void UI_Popup (const char *title, const char *text)
{
	Cvar_Set("ui_sys_popup_title", title);
	UI_RegisterText(TEXT_POPUP_INFO, text);
	if (!UI_IsWindowOnStack(POPUP_WINDOW_NAME))
		UI_PushWindow(POPUP_WINDOW_NAME, NULL, NULL);
}
示例#4
0
/**
 * @brief Console function to push a dropdown window at a position. It work like UI_PushWindow but move the window at the right position
 * @sa UI_PushWindow
 * @note The usage is "ui_push_dropdown sourcenode pointposition destinationnode pointposition"
 * sourcenode must be a node into the window we want to push,
 * we will move the window to have sourcenode over destinationnode
 * pointposition select for each node a position (like a corner).
 */
static void UI_PushDropDownWindow_f (void)
{
	vec2_t source;
	vec2_t destination;
	uiNode_t *node;
	int direction;
	size_t writtenBytes;
	int result;

	if (Cmd_Argc() != 4 && Cmd_Argc() != 5) {
		Com_Printf("Usage: %s <source-anchor> <point-in-source-anchor> <dest-anchor> <point-in-dest-anchor>\n", Cmd_Argv(0));
		return;
	}

	/* get the source anchor */
	node = UI_GetNodeByPath(Cmd_Argv(1));
	if (node == NULL) {
		Com_Printf("UI_PushDropDownWindow_f: Node '%s' doesn't exist\n", Cmd_Argv(1));
		return;
	}
	result = Com_ParseValue(&direction, Cmd_Argv(2), V_INT, 0, sizeof(direction), &writtenBytes);
	if (result != RESULT_OK) {
		Com_Printf("UI_PushDropDownWindow_f: '%s' in not a V_INT\n", Cmd_Argv(2));
		return;
	}
	UI_NodeGetPoint(node, source, direction);
	UI_NodeRelativeToAbsolutePoint(node, source);

	/* get the destination anchor */
	if (Q_streq(Cmd_Argv(4), "mouse")) {
		destination[0] = mousePosX;
		destination[1] = mousePosY;
	} else {
		/* get the source anchor */
		node = UI_GetNodeByPath(Cmd_Argv(3));
		if (node == NULL) {
			Com_Printf("UI_PushDropDownWindow_f: Node '%s' doesn't exist\n", Cmd_Argv(3));
			return;
		}
		result = Com_ParseValue(&direction, Cmd_Argv(4), V_INT, 0, sizeof(direction), &writtenBytes);
		if (result != RESULT_OK) {
			Com_Printf("UI_PushDropDownWindow_f: '%s' in not a V_INT\n", Cmd_Argv(4));
			return;
		}
		UI_NodeGetPoint(node, destination, direction);
		UI_NodeRelativeToAbsolutePoint(node, destination);
	}

	/* update the window and push it */
	node = UI_GetNodeByPath(Cmd_Argv(1));
	if (node == NULL) {
		Com_Printf("UI_PushDropDownWindow_f: Node '%s' doesn't exist\n", Cmd_Argv(1));
		return;
	}
	node = node->root;
	node->box.pos[0] += destination[0] - source[0];
	node->box.pos[1] += destination[1] - source[1];
	UI_PushWindow(node->name);
}
示例#5
0
/**
 * @brief Pushes the webauth window if the password is not yet set
 * @return @c true if the user is authenticated, @c false otherwise
 */
bool WEB_CheckAuth (void)
{
	if (Q_strnull(web_password->string)) {
		UI_PushWindow("webauth");
		return false;
	}
	return true;
}
示例#6
0
/**
 * @brief Check cvars for some initial values that should/must be set
 */
static void CL_CheckCvars_f (void)
{
	for (cvarList_t* c = checkcvar; c->name != nullptr; c++) {
		cvar_t* var = Cvar_Get(c->name);
		if (var->string[0] == '\0') {
			Com_Printf("%s has no value\n", var->name);
			UI_PushWindow("checkcvars");
			break;
		}
	}
}
示例#7
0
/**
 * @brief Checks whether there is a quicksave file and opens the quickload menu if there is one
 * @note This does not work while we are in the battlescape
 */
static void SAV_GameQuickLoadInit_f (void)
{
	qFILE f;

	if (cgi->CL_OnBattlescape()) {
		return;
	}

	FS_OpenFile(va("save/slotquick.%s", SAVEGAME_EXTENSION), &f, FILE_READ);
	if (f.f || f.z) {
		UI_PushWindow("quickload", NULL, NULL);
		FS_CloseFile(&f);
	}
}
/**
 * @brief Open research menu.
 */
static void AC_ResearchAlien_f (void)
{
	const technology_t *tech;

	/* Can be called from everywhere. */
	if (!aliencontCurrent)
		return;

	tech = aliencontCurrent->tech;
	if (!tech)
		Com_Error(ERR_DROP, "aliencontCurrent without tech pointer");

	if (!RS_IsResearched_ptr(tech))
		UI_PushWindow("research", NULL, NULL);
}
示例#9
0
/**
 * @brief Generates a popup that contains up to 3 buttons.
 * @param[in] title Title of the popup.
 * @param[in] text Text to display in the popup (use popupText if text is NULL).
 * @param[in] clickAction1 Action to perform when one clicked on the first button.
 * @param[in] clickText1 String that will be written in first button.
 * @param[in] tooltip1 Tooltip of first button.
 * @param[in] clickAction2 Action to perform when one clicked on the second button.
 * @param[in] clickText2 String that will be written in second button.
 * @param[in] tooltip2 Tooltip of second button.
 * @param[in] clickAction3 Action to perform when one clicked on the third button.
 * @param[in] clickText3 String that will be written in third button.
 * @param[in] tooltip3 Tooltip of third button.
 * @note clickAction AND clickText must be NULL if button should be invisible.
 */
void UI_PopupButton (const char *title, const char *text,
	const char *clickAction1, const char *clickText1, const char *tooltip1,
	const char *clickAction2, const char *clickText2, const char *tooltip2,
	const char *clickAction3, const char *clickText3, const char *tooltip3)
{
	uiNode_t* window;

	Cvar_Set("ui_sys_popup_title", title);
	if (text)
		UI_RegisterText(TEXT_POPUP_INFO, text);
	else
		UI_RegisterText(TEXT_POPUP_INFO, popupText);

	window = UI_GetWindow(POPUPBUTTON_WINDOW_NAME);
	if (!window)
		Com_Error(ERR_FATAL, "Could not get \""POPUPBUTTON_WINDOW_NAME"\" window");

	Cvar_Set("ui_sys_popup_button_text1", clickText1);
	Cvar_Set("ui_sys_popup_button_tooltip1", tooltip1);
	if (!clickAction1 && !clickText1) {
		UI_SetOneButton(window, va("%s1", POPUPBUTTON_NODE_NAME),
			NULL);
	} else {
		UI_SetOneButton(window, va("%s1", POPUPBUTTON_NODE_NAME),
			clickAction1 ? clickAction1 : popupAction1);
	}

	Cvar_Set("ui_sys_popup_button_text2", clickText2);
	Cvar_Set("ui_sys_popup_button_tooltip2", tooltip2);
	if (!clickAction2 && !clickText2) {
		UI_SetOneButton(window, va("%s2", POPUPBUTTON_NODE_NAME), NULL);
	} else {
		UI_SetOneButton(window, va("%s2", POPUPBUTTON_NODE_NAME),
			clickAction2 ? clickAction2 : popupAction2);
	}

	Cvar_Set("ui_sys_popup_button_text3", clickText3);
	Cvar_Set("ui_sys_popup_button_tooltip3", tooltip3);
	if (!clickAction3 && !clickText3) {
		UI_SetOneButton(window, va("%s3", POPUPBUTTON_NODE_NAME), NULL);
	} else {
		UI_SetOneButton(window, va("%s3", POPUPBUTTON_NODE_NAME),
			clickAction3 ? clickAction3 : popupAction3);
	}

	if (!UI_IsWindowOnStack(window->name))
		UI_PushWindow(window->name, NULL, NULL);
}
示例#10
0
/**
 * @brief Console function to push a window onto the window stack
 * @sa UI_PushWindow
 */
static void UI_PushWindow_f (void)
{
	linkedList_t *params = NULL;
	int i;

	if (Cmd_Argc() == 0) {
		Com_Printf("Usage: %s <name> <params>\n", Cmd_Argv(0));
		return;
	}

	for (i = 2; i < Cmd_Argc(); i++) {
		LIST_AddString(&params, Cmd_Argv(i));
	}
	UI_PushWindow(Cmd_Argv(1), NULL, params);
	LIST_Delete(&params);
}
示例#11
0
文件: ui_main.cpp 项目: ufoai/ufoai
/**
 * @brief Reloads the ui scripts and reinitializes the ui
 */
static void UI_Restart_f (void)
{
	typedef std::vector<std::string> Names;
	Names names;
	for (int i = 0; i < ui_global.windowStackPos; i++) {
		names.push_back(std::string(ui_global.windowStack[i]->name));
	}

	UI_Shutdown();
	CLMN_Shutdown();
	R_FontShutdown();
	UI_Init();
	R_FontInit();
	Com_Printf("%i ui script files\n", FS_BuildFileList("ufos/ui/*.ufo"));
	FS_NextScriptHeader(nullptr, nullptr, nullptr);
	const char* type, *name, *text;
	text = nullptr;
	while ((type = FS_NextScriptHeader("ufos/*.ufo", &name, &text)) != nullptr) {
		if (Q_streq(type, "font"))
			UI_ParseFont(name, &text);
		else if (Q_streq(type, "menu_model"))
			UI_ParseUIModel(name, &text);
		else if (Q_streq(type, "sprite"))
			UI_ParseSprite(name, &text);
	}
	UI_Reinit();
	FS_NextScriptHeader(nullptr, nullptr, nullptr);
	text = nullptr;
	while ((type = FS_NextScriptHeader("ufos/ui/*.ufo", &name, &text)) != nullptr) {
		if (Q_streq(type, "window"))
			UI_ParseWindow(type, name, &text);
		else if (Q_streq(type, "component"))
			UI_ParseComponent(type, name, &text);
		else if (Q_streq(type, "menu_model"))
			UI_ParseUIModel(name, &text);
		else if (Q_streq(type, "sprite"))
			UI_ParseSprite(name, &text);
		else if (Q_streq(type, "lua"))
			UI_ParseAndLoadLuaScript(name, &text);
	}

	CLMN_Init();

	for (Names::iterator i = names.begin(); i != names.end(); ++i) {
		UI_PushWindow(i->c_str());
	}
}
示例#12
0
/**
 * @brief Init the stack to start with a window, and have an alternative window with ESC
 * @param[in] activeWindow The first active window of the stack, else NULL
 * @param[in] mainWindow The alternative window, else NULL if nothing
 * @param[in] popAll If true, clean up the stack first
 * @param[in] pushActive If true, push the active window into the stack
 * @todo remove Cvar_Set we have direct access to the cvar
 * @todo check why activeWindow can be NULL. It should never be NULL: a stack must not be empty
 * @todo We should only call it a very few time. When we switch from/to this different par of the game: main-option-interface / geoscape-and-base / battlescape
 * @todo Update the code: popAll should be every time true
 * @todo Update the code: pushActive should be every time true
 * @todo Illustration about when/how we should use UI_InitStack http://ufoai.org/wiki/index.php/Image:UI_InitStack.jpg
 */
void UI_InitStack (const char* activeWindow, const char* mainWindow, bool popAll, bool pushActive)
{
	UI_FinishInit();

	if (popAll)
		UI_PopWindow(true);
	if (activeWindow) {
		Cvar_Set("ui_sys_active", activeWindow);
		/* prevent calls before UI script initialization */
		if (ui_global.numWindows != 0) {
			if (pushActive)
				UI_PushWindow(activeWindow);
		}
	}

	if (mainWindow)
		Cvar_Set("ui_sys_main", mainWindow);
}
示例#13
0
/**
 * @brief Generates a popup that contains a list of selectable choices.
 * @param[in] title Title of the popup.
 * @param[in] headline First line of text written in the popup.
 * @param[in] entries List of the selectables choices.
 * @param[in] clickAction Action to perform when one clicked on the popup.
 */
uiNode_t *UI_PopupList (const char *title, const char *headline, linkedList_t* entries, const char *clickAction)
{
	uiNode_t* window;
	uiNode_t* listNode;

	Cvar_Set("ui_sys_popup_title", title);
	UI_RegisterText(TEXT_POPUP_INFO, headline);

	/* make sure, that we are using the linked list */
	UI_ResetData(TEXT_LIST);
	UI_RegisterLinkedListText(TEXT_LIST, entries);

	window = UI_GetWindow(POPUPLIST_WINDOW_NAME);
	if (!window)
		Com_Error(ERR_FATAL, "Could not get "POPUPLIST_WINDOW_NAME" window");
	listNode = UI_GetNode(window, POPUPLIST_NODE_NAME);
	if (!listNode)
		Com_Error(ERR_FATAL, "Could not get "POPUPLIST_NODE_NAME" node in "POPUPLIST_WINDOW_NAME" window");

	/* free previous actions */
	if (listNode->onClick) {
		assert(listNode->onClick->d.terminal.d1.data);
		Mem_Free(listNode->onClick->d.terminal.d1.data);
		Mem_Free(listNode->onClick);
		listNode->onClick = NULL;
	}

	if (clickAction) {
		UI_PoolAllocAction(&listNode->onClick, EA_CMD, clickAction);
	} else {
		listNode->onClick = NULL;
	}

	if (!UI_IsWindowOnStack(window->name))
		UI_PushWindow(window->name, NULL, NULL);
	return listNode;
}
示例#14
0
文件: cl_radar.cpp 项目: ufoai/ufoai
static void CL_BattlescapeRadarOpen_f (void)
{
	UI_PushWindow("radarwindow");
}
示例#15
0
/**
 * @brief Responses to broadcasts, etc
 * @sa CL_ReadPackets
 * @sa CL_Frame
 * @sa SVC_DirectConnect
 * @param[in,out] msg The client stream message buffer to read from
 */
static void CL_ConnectionlessPacket (dbuffer* msg)
{
	char s[512];
	NET_ReadStringLine(msg, s, sizeof(s));

	Cmd_TokenizeString(s, false);

	const char* c = Cmd_Argv(0);
	Com_DPrintf(DEBUG_CLIENT, "server OOB: %s (%s)\n", c, Cmd_Args());

	/* server connection */
	if (Q_streq(c, CL_CMD_CLIENT_CONNECT)) {
		int i;
		for (i = 1; i < Cmd_Argc(); i++) {
			if (char const* const p = Q_strstart(Cmd_Argv(i), "dlserver=")) {
				Com_sprintf(cls.downloadReferer, sizeof(cls.downloadReferer), "ufo://%s", cls.servername);
				CL_SetHTTPServer(p);
				if (cls.downloadServer[0])
					Com_Printf("HTTP downloading enabled, URL: %s\n", cls.downloadServer);
			}
		}
		if (cls.state == ca_connected) {
			Com_Printf("Dup connect received. Ignored.\n");
			return;
		}
		dbuffer buf(5);
		NET_WriteByte(&buf, clc_stringcmd);
		NET_WriteString(&buf, NET_STATE_NEW "\n");
		NET_WriteMsg(cls.netStream, buf);
		GAME_InitMissionBriefing(_("Loading"));
		return;
	}

	/* remote command from gui front end */
	if (Q_streq(c, CL_CMD_COMMAND)) {
		if (!NET_StreamIsLoopback(cls.netStream)) {
			Com_Printf("Command packet from remote host. Ignored.\n");
			return;
		} else {
			char str[512];
			NET_ReadString(msg, str, sizeof(str));
			Cbuf_AddText("%s\n", str);
		}
		return;
	}

	/* ping from server */
	if (Q_streq(c, CL_CMD_PING)) {
		NET_OOB_Printf(cls.netStream, SV_CMD_ACK);
		return;
	}

	/* echo request from server */
	if (Q_streq(c, CL_CMD_ECHO)) {
		NET_OOB_Printf(cls.netStream, "%s", Cmd_Argv(1));
		return;
	}

	/* print */
	if (Q_streq(c, SV_CMD_PRINT)) {
		NET_ReadString(msg, popupText, sizeof(popupText));
		/* special reject messages needs proper handling */
		if (strstr(popupText, REJ_PASSWORD_REQUIRED_OR_INCORRECT)) {
			UI_PushWindow("serverpassword");
			if (Q_strvalid(Cvar_GetString("password"))) {
				Cvar_Set("password", "");
				CL_Drop();
				UI_Popup(_("Connection failure"), _("The password you specified was wrong."));
			} else {
				CL_Drop();
				UI_Popup(_("Connection failure"), _("This server requires a password."));
			}
		} else if (strstr(popupText, REJ_SERVER_FULL)) {
			CL_Drop();
			UI_Popup(_("Connection failure"), _("This server is full."));
		} else if (strstr(popupText, REJ_BANNED)) {
			CL_Drop();
			UI_Popup(_("Connection failure"), _("You are banned on this server."));
		} else if (strstr(popupText, REJ_GAME_ALREADY_STARTED)) {
			CL_Drop();
			UI_Popup(_("Connection failure"), _("The game has already started."));
		} else if (strstr(popupText, REJ_SERVER_VERSION_MISMATCH)) {
			CL_Drop();
			UI_Popup(_("Connection failure"), _("The server is running a different version of the game."));
		} else if (strstr(popupText, BAD_RCON_PASSWORD)) {
			Cvar_Set("rcon_password", "");
			UI_Popup(_("Bad rcon password"), _("The rcon password you specified was wrong."));
		} else if (strstr(popupText, REJ_CONNECTION_REFUSED)) {
			CL_Drop();
			UI_Popup(_("Connection failure"), _("The server refused the connection."));
		} else if (Q_strvalid(popupText)) {
			UI_Popup(_("Notice"), _(popupText));
		}
		return;
	}

	if (!GAME_HandleServerCommand(c, msg))
		Com_Printf("Unknown command received \"%s\"\n", c);
}
示例#16
0
/**
 * @todo only call/register it when we are on the battlescape
 */
static void CL_HudRadarDown_f (void)
{
	if (!CL_BattlescapeRunning())
		return;
	UI_PushWindow("radarmenu", NULL, NULL);
}
示例#17
0
/**
 * @brief Start Base Attack.
 * @note Base attack mission -- Stage 2
 */
void CP_BaseAttackStartMission (mission_t *mission)
{
	base_t *base = mission->data.base;
	linkedList_t *hiredSoldiersInBase = NULL;
	employee_t *employee;

	assert(base);

	mission->stage = STAGE_BASE_ATTACK;

	CP_MissionDisableTimeLimit(mission);

	if (mission->ufo) {
		/* ufo becomes invisible on geoscape, but don't remove it from ufo global array (may reappear)*/
		CP_UFORemoveFromGeoscape(mission, qfalse);
	}

	/* we always need at least one command centre in the base - because the
	 * phalanx soldiers have their starting positions here.
	 * There should also always be an entrance - the aliens start there
	 * but we don't need to check that as entrance can't be destroyed */
	if (!B_GetNumberOfBuildingsInBaseByBuildingType(base, B_COMMAND)) {
		/** @todo handle command centre properly */
		Com_DPrintf(DEBUG_CLIENT, "CP_BaseAttackStartMission: Base '%s' has no Command Center: it can't defend itself. Destroy base.\n", base->name);
		CP_BaseAttackMissionDestroyBase(mission);
		return;
	}

	base->baseStatus = BASE_UNDER_ATTACK;
	ccs.campaignStats.basesAttacked++;

#if 0
	/** @todo implement onattack: add it to basemanagement.ufo and implement functions */
	if (base->onAttack[0] != '\0')
		/* execute next frame */
		Cbuf_AddText(va("%s %i", base->onAttack, base->id));
#endif

	MAP_SelectMission(mission);
	mission->active = qtrue;
	ccs.mapAction = MA_BASEATTACK;
	Com_DPrintf(DEBUG_CLIENT, "Base attack: %s at %.0f:%.0f\n", mission->id, mission->pos[0], mission->pos[1]);

	/** @todo EMPL_ROBOT */
	E_GetHiredEmployees(base, EMPL_SOLDIER, &hiredSoldiersInBase);

	/* Fill the fake aircraft */
	OBJZERO(baseAttackFakeAircraft);
	baseAttackFakeAircraft.homebase = base;
	/* needed for transfer of alien corpses */
	VectorCopy(base->pos, baseAttackFakeAircraft.pos);
#if 0
	/** @todo active this once more than 8 soldiers are working */
	/* needed to spawn soldiers on map */
	baseAttackFakeAircraft.maxTeamSize = LIST_Count(hiredSoldiersInBase);
#else
	baseAttackFakeAircraft.maxTeamSize = MAX_ACTIVETEAM;
#endif

	if (!hiredSoldiersInBase) {
		Com_DPrintf(DEBUG_CLIENT, "CP_BaseAttackStartMission: Base '%s' has no soldiers: it can't defend itself. Destroy base.\n", base->name);
		CP_BaseAttackMissionDestroyBase(mission);
		return;
	}

	LIST_Foreach(hiredSoldiersInBase, employee_t, employee) {
		if (E_IsAwayFromBase(employee))
			continue;
		AIR_AddToAircraftTeam(&baseAttackFakeAircraft, employee);
	}
	if (AIR_GetTeamSize(&baseAttackFakeAircraft) == 0) {
		Com_DPrintf(DEBUG_CLIENT, "CP_BaseAttackStartMission: Base '%s' has no soldiers at home: it can't defend itself. Destroy base.\n", base->name);
		CP_BaseAttackMissionDestroyBase(mission);
		return;
	}
#if 0
	/** @todo active this once more than 8 soldiers are working */
	/* all soldiers in the base should get used */
	baseAttackFakeAircraft.maxTeamSize = AIR_GetTeamSize(&baseAttackFakeAircraft);
#endif

	LIST_Delete(&hiredSoldiersInBase);
	base->aircraftCurrent = &baseAttackFakeAircraft;
	MAP_SetMissionAircraft(&baseAttackFakeAircraft);
	/** @todo remove me - this is not needed because we are using the base->aircraftCurrent
	 * pointer for resolving the aircraft - only CL_GameAutoGo needs this */
	MAP_SetInterceptorAircraft(&baseAttackFakeAircraft);	/* needed for updating soldier stats sa CL_UpdateCharacterStats*/
	B_SetCurrentSelectedBase(base);						/* needed for equipment menu */

	Com_sprintf(popupText, sizeof(popupText), _("Base '%s' is under attack! What to do ?"), base->name);
	UI_RegisterText(TEXT_POPUP, popupText);

	CL_GameTimeStop();
	UI_PushWindow("popup_baseattack", NULL, NULL);
}