Ejemplo n.º 1
0
/**
 * @brief Resets the ui_global.sharedData pointers from a func node
 * @note You can give this function a parameter to only delete a specific data
 * @sa ui_sharedDataIDNames
 */
static void UI_ResetData_f (void)
{
	if (Cmd_Argc() == 2) {
		const char* dataId = Cmd_Argv(1);
		const int id = UI_GetDataIDByName(dataId);
		if (id == -1)
			Com_Printf("%s: invalid data ID: %s\n", Cmd_Argv(0), dataId);
		else
			UI_ResetData(id);
	} else {
		for (int i = 0; i < UI_MAX_DATAID; i++)
			UI_ResetData(i);
	}
}
Ejemplo n.º 2
0
void GAME_SK_Shutdown (void)
{
	Cmd_RemoveCommand("sk_start");
	Cmd_RemoveCommand("sk_nextequip");
	Cmd_RemoveCommand("sk_prevequip");
	Cmd_RemoveCommand("game_go");

	UI_ResetData(OPTION_DROPSHIPS);
	UI_ResetData(OPTION_UFOS);

	SV_Shutdown("Quitting server.", qfalse);

	chrDisplayList.num = 0;
}
Ejemplo n.º 3
0
void UI_RegisterLineStrip (int dataId, lineStrip_t *lineStrip)
{
	UI_ResetData(dataId);
	ui_global.sharedData[dataId].type = UI_SHARED_LINESTRIP;
	ui_global.sharedData[dataId].data.lineStrip = lineStrip;
	ui_global.sharedData[dataId].versionId++;
}
/**
 * @brief Sets aircraftCurrent and updates related cvars and menutexts.
 * @param[in] aircraft Pointer to given aircraft that should be selected in the menu.
 */
void AIR_AircraftSelect (aircraft_t* aircraft)
{
	static char aircraftInfo[256];
	base_t *base;
	int id;

	if (aircraft != NULL)
		base = aircraft->homebase;
	else
		base = NULL;

	if (!AIR_BaseHasAircraft(base)) {
		UI_ResetData(TEXT_AIRCRAFT_INFO);
		return;
	}

	assert(aircraft);
	assert(aircraft->homebase == base);
	CP_UpdateActorAircraftVar(aircraft, EMPL_SOLDIER);

	Cvar_SetValue("mn_equipsoldierstate", CL_EquipSoldierState(aircraft));
	Cvar_Set("mn_aircraftstatus", AIR_AircraftStatusToName(aircraft));
	Cvar_Set("mn_aircraftinbase", AIR_IsAircraftInBase(aircraft) ? "1" : "0");
	Cvar_Set("mn_aircraftname", aircraft->name);
	if (!aircraft->tech)
		Com_Error(ERR_DROP, "No technology assigned to aircraft '%s'", aircraft->id);
	Cvar_Set("mn_aircraft_model", aircraft->tech->mdl);
	Cvar_Set("mn_aircraft_health", va("%3.0f" , aircraft->stats[AIR_STATS_DAMAGE] > 0 ? (double)aircraft->damage * 100 / aircraft->stats[AIR_STATS_DAMAGE] : 0));

	/* generate aircraft info text */
	Com_sprintf(aircraftInfo, sizeof(aircraftInfo), _("Speed:\t%i km/h\n"),
		AIR_AircraftMenuStatsValues(aircraft->stats[AIR_STATS_SPEED], AIR_STATS_SPEED));
	Q_strcat(aircraftInfo, va(_("Fuel:\t%i/%i\n"), AIR_AircraftMenuStatsValues(aircraft->fuel, AIR_STATS_FUELSIZE),
		AIR_AircraftMenuStatsValues(aircraft->stats[AIR_STATS_FUELSIZE], AIR_STATS_FUELSIZE)), sizeof(aircraftInfo));
	Q_strcat(aircraftInfo, va(_("Operational range:\t%i km\n"), AIR_GetOperationRange(aircraft)), sizeof(aircraftInfo));
	Q_strcat(aircraftInfo, va(_("Weapons:\t%i on %i\n"), AIR_GetSlotItems(AC_ITEM_WEAPON, aircraft), aircraft->maxWeapons), sizeof(aircraftInfo));
	Q_strcat(aircraftInfo, va(_("Armour:\t%i on 1\n"), AIR_GetSlotItems(AC_ITEM_SHIELD, aircraft)), sizeof(aircraftInfo));
	Q_strcat(aircraftInfo, va(_("Electronics:\t%i on %i"), AIR_GetSlotItems(AC_ITEM_ELECTRONICS, aircraft), aircraft->maxElectronics), sizeof(aircraftInfo));

	UI_RegisterText(TEXT_AIRCRAFT_INFO, aircraftInfo);

	/** @todo This shouldn't exists. UI should use the global idx as reference */
	/* compute the ID and... */
	id = 0;
	AIR_ForeachFromBase(aircraftInBase, base) {
		if (aircraft == aircraftInBase)
			break;
		id++;
	}

	base->aircraftCurrent = aircraft;
	Cvar_SetValue("mn_aircraft_id", id);

	/* ...update the GUI */
	UI_ExecuteConfunc("aircraft_change %i", id);
}
Ejemplo n.º 5
0
/**
 * @brief share a text with a data id
 * @note The UI code doesn't manage the text memory, it only save a pointer
 */
void UI_RegisterText (int dataId, const char *text)
{
	UI_ResetData(dataId);

	if (!text)
		return;

	ui_global.sharedData[dataId].type = UI_SHARED_TEXT;
	ui_global.sharedData[dataId].data.text = text;
	ui_global.sharedData[dataId].versionId++;
}
Ejemplo n.º 6
0
void UI_RegisterOption (int dataId, uiNode_t *option)
{
	/** Hack to disable release option memory, if we only want to update the same option */
	if (ui_global.sharedData[dataId].type == UI_SHARED_OPTION && ui_global.sharedData[dataId].data.option == option) {
		ui_global.sharedData[dataId].versionId++;
		return;
	}
	UI_ResetData(dataId);
	ui_global.sharedData[dataId].type = UI_SHARED_OPTION;
	ui_global.sharedData[dataId].data.option = option;
	ui_global.sharedData[dataId].versionId++;
}
Ejemplo n.º 7
0
/**
 * @brief share a linked list of text with a data id
 * @note The UI code manage the linked list memory (linked list is freed by the UI code)
 */
void UI_RegisterLinkedListText (int dataId, linkedList_t *text)
{
	/** @todo FIXME It is a hack to disable release memory, if we only want to update the same list */
	if (ui_global.sharedData[dataId].type == UI_SHARED_LINKEDLISTTEXT && ui_global.sharedData[dataId].data.linkedListText == text) {
		ui_global.sharedData[dataId].versionId++;
		return;
	}
	UI_ResetData(dataId);
	ui_global.sharedData[dataId].type = UI_SHARED_LINKEDLISTTEXT;
	ui_global.sharedData[dataId].data.linkedListText = text;
	ui_global.sharedData[dataId].versionId++;
}
Ejemplo n.º 8
0
/**
 * @brief Draw a text node
 */
static void UI_TextListNodeDraw (uiNode_t *node)
{
	const uiSharedData_t *shared;
	shared = &ui_global.sharedData[EXTRADATA(node).dataID];

	/* nothing set yet? */
	if (shared->type == UI_SHARED_NONE)
		return;
	if (shared->type != UI_SHARED_LINKEDLISTTEXT) {
		Com_Printf("UI_TextListNodeDraw: Only linkedlist text supported (dataid %d).\n", EXTRADATA(node).dataID);
		UI_ResetData(EXTRADATA(node).dataID);
		return;
	}

	UI_TextLineNodeDrawText(node, shared->data.linkedListText);
}
Ejemplo n.º 9
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;
}
Ejemplo n.º 10
0
/**
 * @brief Prints the description for items (weapons, armour, ...)
 * @param[in] od The object definition of the item
 * @note Not only called from UFOpaedia but also from other places to display
 * weapon and ammo statistics
 * @todo Do we need to add checks for @c od->isDummy here somewhere?
 */
void INV_ItemDescription (const objDef_t* od)
{
    static char itemText[UI_MAX_SMALLTEXTLEN];
    int i;
    int count;

    currentDisplayedObject = od;
    Cvar_Set("mn_firemodename", "");
    Cvar_Set("mn_linkname", "");

    if (!od) {	/* If nothing selected return */
        Cvar_Set("mn_itemname", "");
        Cvar_Set("mn_item", "");
        UI_ResetData(TEXT_ITEMDESCRIPTION);
        itemIndex = fireModeIndex = 0;
        UI_ExecuteConfunc("itemdesc_view 0 0;");
        return;
    }

    /* select item */
    Cvar_Set("mn_itemname", "%s", _(od->name));
    Cvar_Set("mn_item", "%s", od->id);

    count = 0;
    if (GAME_ItemIsUseable(od)) {
        if (od->isAmmo()) {
            /* We display the pre/next buttons for changing weapon only if there are at least 2 researched weapons
             * we are counting the number of weapons that are usable with this ammo */
            for (i = 0; i < od->numWeapons; i++)
                if (GAME_ItemIsUseable(od->weapons[i]))
                    count++;
            if (itemIndex >= od->numWeapons || itemIndex < 0)
                itemIndex = 0;
            if (count > 0) {
                while (!GAME_ItemIsUseable(od->weapons[itemIndex])) {
                    itemIndex++;
                    if (itemIndex >= od->numWeapons)
                        itemIndex = 0;
                }
                Cvar_ForceSet("mn_linkname", _(od->weapons[itemIndex]->name));
            }
        } else if (od->weapon) {
            /* We display the pre/next buttons for changing ammo only if there are at least 2 researched ammo
             * we are counting the number of ammo that is usable with this weapon */
            for (i = 0; i < od->numAmmos; i++)
                if (GAME_ItemIsUseable(od->ammos[i]))
                    count++;

            if (itemIndex >= od->numAmmos || itemIndex < 0)
                itemIndex = 0;

            /* Only display ammos if at least one has been researched */
            if (count > 0) {
                /* We have a weapon that uses ammos */
                while (!GAME_ItemIsUseable(od->ammos[itemIndex])) {
                    itemIndex++;
                    if (itemIndex >= od->numAmmos)
                        itemIndex = 0;
                }
                Cvar_ForceSet("mn_linkname", _(od->ammos[itemIndex]->name));
            }
        } else {
            Cvar_ForceSet("mn_linkname", "");
        }
    }

    /* set description text if item has been researched or one of its ammo/weapon has been researched */
    if (count > 0 || GAME_ItemIsUseable(od)) {
        int numFiredefs = 0;

        *itemText = '\0';
        if (od->isArmour()) {
            Com_sprintf(itemText, sizeof(itemText), _("Size:\t%i\n"), od->size);
            Q_strcat(itemText, sizeof(itemText), _("Weight:\t%g Kg\n"), od->weight);
            Q_strcat(itemText, sizeof(itemText), "\n");
            Q_strcat(itemText, sizeof(itemText), _("^BDamage type:\tProtection:\n"));
            for (i = 0; i < csi.numDTs; i++) {
                const damageType_t* dt = &csi.dts[i];
                if (!dt->showInMenu)
                    continue;
                Q_strcat(itemText, sizeof(itemText), _("%s\t%i\n"), _(dt->id), od->ratings[i]);
            }
        } else if ((od->weapon && od->numAmmos) || od->isAmmo()) {
            const objDef_t* odAmmo;

            if (count > 0) {
                int weaponIndex;
                if (od->weapon) {
                    Com_sprintf(itemText, sizeof(itemText), _("%s weapon\n"), (od->fireTwoHanded ? _("Two-handed") : _("One-handed")));
                    if (od->ammo > 0)
                        Q_strcat(itemText, sizeof(itemText), _("Max ammo:\t%i\n"), od->ammo);
                    odAmmo = (od->numAmmos) ? od->ammos[itemIndex] : od;
                    assert(odAmmo);
                    for (weaponIndex = 0; (weaponIndex < odAmmo->numWeapons) && (odAmmo->weapons[weaponIndex] != od); weaponIndex++) {}
                } else {
                    odAmmo = od;
                    weaponIndex = itemIndex;
                }

                Q_strcat(itemText, sizeof(itemText), _("Weight:\t%g Kg\n"), od->weight);
                /** @todo is there ammo with no firedefs? */
                if (GAME_ItemIsUseable(odAmmo) && odAmmo->numFiredefs[weaponIndex] > 0) {
                    const fireDef_t* fd;
                    numFiredefs = odAmmo->numFiredefs[weaponIndex];

                    /* This contains everything common for weapons and ammos */
                    /* We check if the wanted firemode to display exists. */
                    if (fireModeIndex > numFiredefs - 1)
                        fireModeIndex = 0;
                    if (fireModeIndex < 0)
                        fireModeIndex = numFiredefs - 1;

                    fd = &odAmmo->fd[weaponIndex][fireModeIndex];

                    /* We always display the name of the firemode for an ammo */
                    Cvar_Set("mn_firemodename", "%s", _(fd->name));

                    /* We display the characteristics of this firemode */
                    Q_strcat(itemText, sizeof(itemText), _("Skill:\t%s\n"), CL_WeaponSkillToName(fd->weaponSkill));
                    Q_strcat(itemText, sizeof(itemText), _("Damage:\t%i\n"), (int) (fd->damage[0] + fd->spldmg[0]) * fd->shots);
                    Q_strcat(itemText, sizeof(itemText), _("Time units:\t%i\n"), fd->time);
                    Q_strcat(itemText, sizeof(itemText), _("Range:\t%g\n"), fd->range / UNIT_SIZE);
                    Q_strcat(itemText, sizeof(itemText), _("Spreads:\t%g\n"), (fd->spread[0] + fd->spread[1]) / 2);
                }
            } else {
                Com_sprintf(itemText, sizeof(itemText), _("%s. No detailed info available.\n"), od->isAmmo() ? _("Ammunition") : _("Weapon"));
                Q_strcat(itemText, sizeof(itemText), _("Weight:\t%g Kg\n"), od->weight);
            }
        } else if (od->weapon) {
            Com_sprintf(itemText, sizeof(itemText), _("%s ammo-less weapon\n"), (od->fireTwoHanded ? _("Two-handed") : _("One-handed")));
            Q_strcat(itemText, sizeof(itemText), _("Weight:\t%g Kg\n"), od->weight);
        } else {
            /* just an item - only primary definition */
            Com_sprintf(itemText, sizeof(itemText), _("%s auxiliary equipment\n"), (od->fireTwoHanded ? _("Two-handed") : _("One-handed")));
            Q_strcat(itemText, sizeof(itemText), _("Weight:\t%g Kg\n"), od->weight);
            if (od->numWeapons > 0 && od->numFiredefs[0] > 0) {
                const fireDef_t* fd = &od->fd[0][0];
                Q_strcat(itemText, sizeof(itemText), _("Action:\t%s\n"), _(fd->name));
                Q_strcat(itemText, sizeof(itemText), _("Time units:\t%i\n"), fd->time);
                Q_strcat(itemText, sizeof(itemText), _("Range:\t%g\n"), fd->range / UNIT_SIZE);
            }
        }

        UI_RegisterText(TEXT_ITEMDESCRIPTION, itemText);
        UI_ExecuteConfunc("itemdesc_view %i %i;", count, numFiredefs);
    } else {
        Com_sprintf(itemText, sizeof(itemText), _("Unknown - not useable"));
        UI_RegisterText(TEXT_ITEMDESCRIPTION, itemText);
        UI_ExecuteConfunc("itemdesc_view 0 0;");
    }
}
/**
 * @brief Updates the Buy/Sell menu list.
 * @param[in] base Pointer to the base to buy/sell at
 * @sa BS_BuyType_f
 */
static void BS_BuyType (const base_t *base)
{
	const objDef_t *od;
	int i, j = 0;
	char tmpbuf[MAX_VAR];

	if (!base || buyCat >= MAX_FILTERTYPES || buyCat < 0)
		return;

	CP_UpdateCredits(ccs.credits);

	bsMarketNames = NULL;
	bsMarketStorage = NULL;
	bsMarketMarket = NULL;
	bsMarketPrices = NULL;
	UI_ResetData(TEXT_ITEMDESCRIPTION);

	/* hide autosell checkboxes by default */
	for (i = 0; i < MAX_MARKET_MENU_ENTRIES; i++) {
		UI_ExecuteConfunc("buy_autoselli %i", i);
	}

	switch (buyCat) {
	case FILTER_AIRCRAFT:	/* Aircraft */
		{
		const aircraft_t *aircraftTemplate;
		for (i = 0, j = 0, aircraftTemplate = ccs.aircraftTemplates; i < ccs.numAircraftTemplates; i++, aircraftTemplate++) {
			if (!BS_AircraftIsOnMarket(aircraftTemplate))
				continue;
			assert(aircraftTemplate->tech);
			if (BS_GetStorageAmountInBase(base, aircraftTemplate->id) + BS_GetAircraftOnMarket(aircraftTemplate) > 0) {
				if (j >= buyList.scroll && j < MAX_MARKET_MENU_ENTRIES) {
					UI_ExecuteConfunc("buy_show %i", j - buyList.scroll);
				}
				BS_AddToList(aircraftTemplate->name, BS_GetStorageAmountInBase(base, aircraftTemplate->id),
						BS_GetAircraftOnMarket(aircraftTemplate), BS_GetAircraftBuyingPrice(aircraftTemplate));
				if (j >= MAX_BUYLIST)
					Com_Error(ERR_DROP, "Increase the MAX_BUYLIST value to handle that much items\n");
				buyList.l[j].item = NULL;
				buyList.l[j].aircraft = aircraftTemplate;
				buyList.length = j + 1;
				BS_UpdateItem(base, j - buyList.scroll);
				j++;
			}
		}
		}
		break;
	case FILTER_CRAFTITEM:	/* Aircraft items */
		/* get item list */
		for (i = 0, j = 0, od = csi.ods; i < csi.numODs; i++, od++) {
			if (!BS_IsOnMarket(od))
				continue;
			/* Check whether the item matches the proper filter, storage in current base and market. */
			if ((B_ItemInBase(od, base) || ccs.eMarket.numItems[i])
			 && INV_ItemMatchesFilter(od, FILTER_CRAFTITEM)) {
				if (j >= buyList.scroll && j < MAX_MARKET_MENU_ENTRIES) {
					const technology_t *tech = RS_GetTechForItem(od);

					UI_ExecuteConfunc("buy_show %i", j - buyList.scroll);
					if (RS_IsResearched_ptr(tech)) {
						if (ccs.eMarket.autosell[i])
							UI_ExecuteConfunc("buy_autoselle %i", j - buyList.scroll);
						else
							UI_ExecuteConfunc("buy_autoselld %i", j - buyList.scroll);
					}
				}
				BS_AddToList(od->name, B_ItemInBase(od, base), ccs.eMarket.numItems[i], BS_GetItemBuyingPrice(od));
				if (j >= MAX_BUYLIST)
					Com_Error(ERR_DROP, "Increase the MAX_FILTERLIST value to handle that much items\n");
				buyList.l[j].item = od;
				buyList.l[j].aircraft = NULL;
				buyList.length = j + 1;
				BS_UpdateItem(base, j - buyList.scroll);
				j++;
			}
		}
		break;
	default:	/* Normal items */
		if (buyCat < MAX_SOLDIER_FILTERTYPES || buyCat == FILTER_DUMMY) {
			/* get item list */
			for (i = 0, j = 0, od = csi.ods; i < csi.numODs; i++, od++) {
				if (!BS_IsOnMarket(od))
					continue;
				/* Check whether the item matches the proper filter, storage in current base and market. */
				if ((B_ItemInBase(od, base) || ccs.eMarket.numItems[i]) && INV_ItemMatchesFilter(od, buyCat)) {
					BS_AddToList(od->name, B_ItemInBase(od, base), ccs.eMarket.numItems[i], BS_GetItemBuyingPrice(od));
					/* Set state of Autosell button. */
					if (j >= buyList.scroll && j < MAX_MARKET_MENU_ENTRIES) {
						const technology_t *tech = RS_GetTechForItem(od);

						UI_ExecuteConfunc("buy_show %i", j - buyList.scroll);
						if (RS_IsResearched_ptr(tech)) {
							if (ccs.eMarket.autosell[i])
								UI_ExecuteConfunc("buy_autoselle %i", j - buyList.scroll);
							else
								UI_ExecuteConfunc("buy_autoselld %i", j - buyList.scroll);
						}
					}

					if (j >= MAX_BUYLIST)
						Com_Error(ERR_DROP, "Increase the MAX_BUYLIST value to handle that much items\n");
					buyList.l[j].item = od;
					buyList.l[j].aircraft = NULL;
					buyList.length = j + 1;
					BS_UpdateItem(base, j - buyList.scroll);
					j++;
				}
			}
		}
		break;
	}

	for (; j < MAX_MARKET_MENU_ENTRIES; j++) {
		/* Hide the rest of the entries. */
		UI_ExecuteConfunc("buy_hide %i", j);
	}

	/* Update some menu cvars. */
	/* Set up base capacities. */
	Com_sprintf(tmpbuf, sizeof(tmpbuf), "%i/%i", CAP_GetCurrent(base, CAP_ITEMS),
		CAP_GetMax(base, CAP_ITEMS));
	Cvar_Set("mn_bs_storage", tmpbuf);

	/* select first item */
	if (buyList.length) {
		switch (buyCat) {	/** @sa BS_MarketClick_f */
		case FILTER_AIRCRAFT:
			BS_MarketAircraftDescription(buyList.l[0].aircraft);
			break;
		case FILTER_CRAFTITEM:
			Cvar_Set("mn_aircraftname", "");	/** @todo Use craftitem name here? See also BS_MarketClick_f */
			/* Select current item or first one. */
			if (currentSelectedMenuEntry)
				UP_AircraftItemDescription(currentSelectedMenuEntry);
			else
				UP_AircraftItemDescription(buyList.l[0].item);
			break;
		default:
			assert(buyCat != MAX_FILTERTYPES);
			/* Select current item or first one. */
			if (currentSelectedMenuEntry)
				INV_ItemDescription(currentSelectedMenuEntry);
			else
				INV_ItemDescription(buyList.l[0].item);
			break;
		}
	} else {
		/* reset description */
		INV_ItemDescription(NULL);
	}

	UI_RegisterLinkedListText(TEXT_MARKET_NAMES, bsMarketNames);
	UI_RegisterLinkedListText(TEXT_MARKET_STORAGE, bsMarketStorage);
	UI_RegisterLinkedListText(TEXT_MARKET_MARKET, bsMarketMarket);
	UI_RegisterLinkedListText(TEXT_MARKET_PRICES, bsMarketPrices);
}