/**
 * @brief Init function for Buy/Sell menu.
 */
static void BS_BuyType_f (void)
{
	base_t *base = B_GetCurrentSelectedBase();

	if (Cmd_Argc() == 2) {
		buyCat = INV_GetFilterTypeID(Cmd_Argv(1));

		if (buyCat == FILTER_DISASSEMBLY)
			buyCat--;
		if (buyCat < 0) {
			buyCat = MAX_FILTERTYPES - 1;
			if (buyCat == FILTER_DISASSEMBLY)
				buyCat--;
		} else if (buyCat >= MAX_FILTERTYPES) {
			buyCat = 0;
		}

		Cvar_Set("mn_itemtype", INV_GetFilterType(buyCat));
		currentSelectedMenuEntry = NULL;
	}

	BS_BuyType(base);
	buyList.scroll = 0;
	UI_ExecuteConfunc("sync_market_scroll 0 %d", buyList.scroll);
	UI_ExecuteConfunc("market_scroll %d", buyList.scroll);
	UI_ExecuteConfunc("market_click 0");
}
void CL_ActorStateChange (const eventRegister_t *self, struct dbuffer *msg)
{
	le_t *le;
	int entnum, state;
	character_t *chr;

	NET_ReadFormat(msg, self->formatString, &entnum, &state);

	le = LE_Get(entnum);
	if (!le)
		LE_NotFoundError(entnum);

	if (!LE_IsActor(le)) {
		Com_Printf("StateChange message ignored... LE is no actor (number: %i, state: %i, type: %i)\n",
			entnum, state, le->type);
		return;
	}

	/* If standing up or crouching down remove the reserved-state for crouching. */
	if (((state & STATE_CROUCHED) && !LE_IsCrouched(le)) ||
		 (!(state & STATE_CROUCHED) && LE_IsCrouched(le))) {
		if (CL_ActorUsableTUs(le) < TU_CROUCH && CL_ActorReservedTUs(le, RES_CROUCH) >= TU_CROUCH) {
			/* We have not enough non-reserved TUs,
			 * but some reserved for crouching/standing up.
			 * i.e. we only reset the reservation for crouching if it's the very last attempt. */
			CL_ActorReserveTUs(le, RES_CROUCH, 0); /* Reset reserved TUs (0 TUs) */
		}
	}

	/* killed by the server: no animation is played, etc. */
	if ((state & STATE_DEAD) && LE_IsLivingActor(le)) {
		le->state = state;
		FLOOR(le) = NULL;
		LE_SetThink(le, NULL);
		VectorCopy(player_dead_maxs, le->maxs);
		CL_ActorRemoveFromTeamList(le);
		return;
	} else {
		le->state = state;
		LE_SetThink(le, LET_StartIdle);
	}

	/* save those states that the actor should also carry over to other missions */
	chr = CL_ActorGetChr(le);
	if (!chr)
		return;

	chr->state = (le->state & STATE_REACTION);

	/* change reaction button state */
	if (!(le->state & STATE_REACTION)) {
		UI_ExecuteConfunc("disable_reaction");
	} else {
		UI_ExecuteConfunc("startreaction");
	}

	/* state change may have affected move length */
	CL_ActorConditionalMoveCalc(le);
}
Exemple #3
0
/**
 * @brief Console callback for handling the web auth
 * @sa WEB_Auth
 */
static void WEB_Auth_f (void)
{
	if (Cmd_Argc() != 3) {
		Com_Printf("Usage: %s <username> <password>\n", Cmd_Argv(0));
		return;
	}
	if (WEB_Auth(Cmd_Argv(1), Cmd_Argv(2))) {
		UI_ExecuteConfunc("web_authsuccessful");
	} else {
		UI_ExecuteConfunc("web_authfailed");
	}
}
Exemple #4
0
/**
 * @brief Hide the dropship selection or show it with the dropship given in the parameter
 * @param dropships if @c NULL, the dropship selection panel will be hidden, otherwise it
 * will be shown with the given list entries as content.
 */
static inline void GAME_SK_HideDropships (const linkedList_t *dropships)
{
	const qboolean hide = (dropships == NULL);
	if (hide) {
		UI_ExecuteConfunc("skirmish_hide_dropships true");
		Cvar_Set("rm_drop", "");
	} else {
		const char *rma = Com_GetRandomMapAssemblyNameForCraft((const char *)dropships->data);
		Cvar_Set("rm_drop", rma);
		UI_UpdateInvisOptions(UI_GetOption(OPTION_DROPSHIPS), dropships);

		UI_ExecuteConfunc("skirmish_hide_dropships false");
	}
}
Exemple #5
0
/**
 * @brief Hide the ufo selection or show it with the ufos given in the parameter
 * @param ufos if @c NULL, the ufo selection panel will be hidden, otherwise it
 * will be shown with the given list entries as content.
 */
static inline void GAME_SK_HideUFOs (const linkedList_t *ufos)
{
	const qboolean hide = (ufos == NULL);
	if (hide) {
		UI_ExecuteConfunc("skirmish_hide_ufos true");
		Cvar_Set("rm_ufo", "");
	} else {
		const char *rma = Com_GetRandomMapAssemblyNameForCraft((const char *)ufos->data);
		Cvar_Set("rm_ufo", rma);
		UI_UpdateInvisOptions(UI_GetOption(OPTION_UFOS), ufos);

		UI_ExecuteConfunc("skirmish_hide_ufos false");
	}
}
/**
 * @brief Update the GUI by calling a console function
 * @sa BS_BuyType
 */
static void BS_UpdateItem (const base_t *base, int itemNum)
{
	int min, max, value;

	if (BS_GetMinMaxValueByItemID(base, itemNum, &min, &max, &value))
		UI_ExecuteConfunc("buy_updateitem %d %d %d %d", itemNum, value, min, max);
}
/**
 * @brief Update the GUI with the selected item
 */
static void INV_UpdateObject_f (void)
{
    /* check syntax */
    if (Cmd_Argc() < 3) {
        Com_Printf("Usage: %s <objectid> <confunc> [mustwechangetab]\n", Cmd_Argv(0));
        return;
    }

    bool changeTab = true;
    if (Cmd_Argc() == 4)
        changeTab = atoi(Cmd_Argv(3)) >= 1;

    const int num = atoi(Cmd_Argv(1));
    if (num < 0 || num >= csi.numODs) {
        Com_Printf("Id %i out of range 0..%i\n", num, csi.numODs);
        return;
    }
    const objDef_t* obj = INVSH_GetItemByIDX(num);

    /* update tab */
    if (changeTab) {
        const cvar_t* var = Cvar_FindVar("mn_equiptype");
        const int filter = INV_GetFilterFromItem(obj);
        if (var && var->integer != filter) {
            Cvar_SetValue("mn_equiptype", filter);
            UI_ExecuteConfunc("%s", Cmd_Argv(2));
        }
    }

    /* update item description */
    INV_ItemDescription(obj);
}
/**
 * @brief
 * @sa BS_MarketClick_f
 * @sa BS_AddToList
 */
static void BS_MarketScroll_f (void)
{
	int i;
	base_t *base = B_GetCurrentSelectedBase();

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

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

	buyList.scroll = atoi(Cmd_Argv(1));
	assert(buyList.scroll >= 0);
	assert(!((buyList.length > MAX_MARKET_MENU_ENTRIES && buyList.scroll >= buyList.length - MAX_MARKET_MENU_ENTRIES)));

	/* now update the menu pics */
	for (i = 0; i < MAX_MARKET_MENU_ENTRIES; i++) {
		UI_ExecuteConfunc("buy_autoselli %i", i);
	}

	/* get item list */
	for (i = buyList.scroll; i < buyList.length - buyList.scroll; i++) {
		const objDef_t *od = BS_GetObjectDefition(&buyList.l[i]);

		if (i >= MAX_MARKET_MENU_ENTRIES)
			break;

		/* Check whether the item matches the proper filter, storage in current base and market. */
		if (od && (B_ItemInBase(od, base) > 0 || ccs.eMarket.numItems[od->idx]) && INV_ItemMatchesFilter(od, buyCat)) {
			const technology_t *tech = RS_GetTechForItem(od);

			UI_ExecuteConfunc("buy_show %i", i - buyList.scroll);
			BS_UpdateItem(base, i - buyList.scroll);

			/* autosell setting */
			if (!RS_IsResearched_ptr(tech))
				continue;
			if (ccs.eMarket.autosell[od->idx])
				UI_ExecuteConfunc("buy_autoselle %i", i - buyList.scroll);
			else
				UI_ExecuteConfunc("buy_autoselld %i", i - buyList.scroll);
		}
	}
}
Exemple #9
0
/**
 * @brief Prints a list of tab and newline separated string to keylist char array that hold the key and the command desc
 */
static void CLMN_InitKeyList_f (void)
{
	UI_ExecuteConfunc("keybinding_clear");

	CLMN_AddBindings(KEYSPACE_GAME, keyBindings);
	CLMN_AddBindings(KEYSPACE_UI, menuKeyBindings);
	const int uiBindings = CLMN_AddUIBindings(KEYSPACE_UI);
	CLMN_AddBindings(KEYSPACE_BATTLE, battleKeyBindings, uiBindings);
}
/**
 * @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);
}
/**
 * Updates the material editor node for a given image and a given material stage
 * @param image The image to load into the material editor
 * @param materialStage The material stage to display
 */
static void UI_MaterialEditorUpdate (image_t *image, materialStage_t *materialStage)
{
	linkedList_t *materialStagesList = NULL;

	if (image->normalmap == NULL)
		UI_ExecuteConfunc("hideshaders true 0 0 0 0");
	else
		UI_ExecuteConfunc("hideshaders false %f %f %f %f", image->material.bump,
				image->material.hardness, image->material.parallax, image->material.specular);

	if (image->normalmap == NULL)
		Cvar_Set("me_imagename", image->name);
	else
		Cvar_Set("me_imagename", va("%s (nm)", image->name));

	if (!image->material.num_stages) {
		UI_ExecuteConfunc("hidestages true");
	} else {
		int i;
		if (materialStage) {
			const char *stageType = Cvar_GetString("me_stagetype");
			if (stageType[0] == '\0')
				stageType = "stretch";
			UI_ExecuteConfunc("hidestages false %s", stageType);
		} else
			Cvar_Set("me_stage_id", "-1");
		for (i = 0; i < image->material.num_stages; i++) {
			const materialStage_t *stage = UI_MaterialEditorGetStage(&image->material, i);
			char stageName[MAX_VAR] = "stage ";
			if (stage == materialStage) {
				UI_ExecuteConfunc("updatestagevalues %f %f %f %f %f %f %f %f %f %f %f %f %f %f",
						stage->rotate.hz, stage->rotate.deg,
						stage->stretch.hz, stage->stretch.dhz, stage->stretch.amp, stage->stretch.damp,
						stage->pulse.hz, stage->pulse.dhz,
						stage->scroll.ds, stage->scroll.dt, stage->scroll.s, stage->scroll.t,
						stage->scale.s, stage->scale.t);
			}
			UI_MaterialEditorStagesToName(stage, stageName, sizeof(stageName) - 1);
			LIST_AddString(&materialStagesList, stageName);
		}
	}
	UI_RegisterLinkedListText(TEXT_MATERIAL_STAGES, materialStagesList);
}
Exemple #12
0
/**
 * @sa G_ClientStartMatch
 * @sa EV_RESET
 */
void CL_Reset (const eventRegister_t *self, dbuffer *msg)
{
	CL_ActorSelect(nullptr);
	cl.numTeamList = 0;

	/* set the active player */
	NET_ReadFormat(msg, self->formatString, &cls.team, &cl.actTeam);

	Com_Printf("(player %i) It's team %i's turn!\n", cl.pnum, cl.actTeam);

	CL_CompleteRecalcRouting();

	UI_ExecuteConfunc("disable_rescuezone");

	if (cls.isOurRound())
		UI_ExecuteConfunc("startround");
	else
		Com_Printf("You lost the coin-toss for first-turn.\n");
}
Exemple #13
0
static inline void CLMN_AddBindings (keyBindSpace_t scope, char** bindings, int offset = 0)
{
	for (int i = K_FIRST_KEY; i < K_LAST_KEY; i++) {
		if (Q_strnull(bindings[i]))
			continue;
		const char* binding = Cmd_GetCommandDesc(bindings[i]);
		if (Q_strvalid(binding))
			binding = _(binding);
		UI_ExecuteConfunc("keybinding_add %i %i \"%s\" \"%s\"", i + offset, scope, Key_KeynumToString(i), binding);
	}
}
Exemple #14
0
/**
 * @brief This is called if actors are spawned (or at least the spawning commands were send to
 * the server). This callback can e.g. be used to set initial actor states. E.g. request crouch and so on.
 * These events are executed without consuming time
 */
static void GAME_InitializeBattlescape (chrList_t *team)
{
	int i;
	const cgame_export_t *list = GAME_GetCurrentType();

	for (i = 0; i < lengthof(cl.teamList); i++) {
		UI_ExecuteConfunc("huddisable %i", i);
	}

	if (list && list->InitializeBattlescape)
		list->InitializeBattlescape(team);
}
Exemple #15
0
/**
 * @brief Reads the comments from team files
 */
void GAME_TeamSlotComments_f (void)
{
	UI_ExecuteConfunc("teamsaveslotsclear");

	char relSavePath[MAX_OSPATH];
	GAME_GetRelativeSavePath(relSavePath, sizeof(relSavePath));
	char pattern[MAX_OSPATH];
	Q_strncpyz(pattern, relSavePath, sizeof(pattern));
	Q_strcat(pattern, sizeof(pattern), "*.mpt");

	FS_BuildFileList(pattern);
	int i = 0;
	const char* filename;
	while ((filename = FS_NextFileFromFileList(pattern)) != nullptr) {
		ScopedFile f;
		const char* savePath = va("%s/%s", relSavePath, filename);
		FS_OpenFile(savePath, &f, FILE_READ);
		if (!f) {
			Com_Printf("Warning: Could not open '%s'\n", filename);
			continue;
		}
		teamSaveFileHeader_t header;
		const int clen = sizeof(header);
		if (FS_Read(&header, clen, &f) != clen) {
			Com_Printf("Warning: Could not read %i bytes from savefile\n", clen);
			continue;
		}
		if (LittleLong(header.version) != TEAM_SAVE_FILE_VERSION) {
			Com_Printf("Warning: Version mismatch in '%s'\n", filename);
			continue;
		}

		char absSavePath[MAX_OSPATH];
		GAME_GetAbsoluteSavePath(absSavePath, sizeof(absSavePath));
		const bool uploadable = FS_FileExists("%s/%s", absSavePath, filename);
		UI_ExecuteConfunc("teamsaveslotadd %i \"%s\" \"%s\" %i %i", i++, filename, header.name, LittleLong(header.soldiercount), uploadable ? 1 : 0);
	}
	FS_NextFileFromFileList(nullptr);
}
/**
 * @brief Update the equipment weight for the selected actor.
 */
static void INV_UpdateActorLoad_f (void)
{
	if (Cmd_Argc() < 2) {
		Com_Printf("Usage: %s <callback>\n", Cmd_Argv(0));
		return;
	}

	const character_t* chr = GAME_GetSelectedChr();
	if (chr == nullptr)
		return;

	const float invWeight = chr->inv.getWeight();
	const int maxWeight = GAME_GetChrMaxLoad(chr);
	const float penalty = GET_ENCUMBRANCE_PENALTY(invWeight, maxWeight);
	const int normalTU = GET_TU(chr->score.skills[ABILITY_SPEED], 1.0f - WEIGHT_NORMAL_PENALTY);
	const int tus = GET_TU(chr->score.skills[ABILITY_SPEED], penalty);
	const int tuPenalty = tus - normalTU;
	int count = 0;

	const Container* cont = nullptr;
	while ((cont = chr->inv.getNextCont(cont))) {
		if (cont->def()->temp)
			continue;
		for (Item* invList = cont->_invList, *next; invList; invList = next) {
			next = invList->getNext();
			const fireDef_t* fireDef = invList->getFiredefs();
			if (fireDef == nullptr)
				continue;
			for (int i = 0; i < MAX_FIREDEFS_PER_WEAPON; i++) {
				if (fireDef[i].time <= 0)
					continue;
				if (fireDef[i].time <= tus)
					continue;
				if (count <= 0)
					Com_sprintf(popupText, sizeof(popupText), _("This soldier no longer has enough TUs to use the following items:\n\n"));
				Q_strcat(popupText, sizeof(popupText), "%s: %s (%i)\n", _(invList->def()->name), _(fireDef[i].name), fireDef[i].time);
				++count;
			}
		}
	}

	if ((Cmd_Argc() < 3 || atoi(Cmd_Argv(2)) == 0) && count > 0)
		UI_Popup(_("Warning"), popupText);

	char label[MAX_VAR];
	char tooltip[MAX_VAR];
	Com_sprintf(label, sizeof(label), "%g/%i %s %s", invWeight / WEIGHT_FACTOR, maxWeight, _("Kg"),
			(count > 0 ? _("Warning!") : ""));
	Com_sprintf(tooltip, sizeof(tooltip), "%s %i (%+i)", _("TU:"), tus, tuPenalty);
	UI_ExecuteConfunc("%s \"%s\" \"%s\" %f %i", Cmd_Argv(1), label, tooltip, WEIGHT_NORMAL_PENALTY - (1.0f - penalty), count);
}
Exemple #17
0
/**
 * @brief Performs end-of-turn processing.
 * @param[in] self Pointer to the event structure that is currently executed
 * @param[in] msg The netchannel message
 * @sa CL_EndRoundAnnounce
 */
void CL_DoEndRound (const eventRegister_t* self, dbuffer* msg)
{
	/* hud changes */
	if (cls.isOurRound())
		UI_ExecuteConfunc("endround");

	refdef.rendererFlags &= ~RDF_IRGOGGLES;

	/* change active player */
	Com_Printf("Team %i ended round\n", cl.actTeam);
	cl.actTeam = NET_ReadByte(msg);
	Com_Printf("Team %i's round started!\n", cl.actTeam);

	/* hud changes */
	if (cls.isOurRound()) {
		/* check whether a particle has to go */
		CL_ParticleCheckRounds();
		UI_ExecuteConfunc("startround");
		HUD_DisplayMessage(_("Your round started!"));
		S_StartLocalSample("misc/roundstart", SND_VOLUME_DEFAULT);
		CL_ActorConditionalMoveCalc(selActor);
	}
}
/**
 * @brief Network event function for reaction fire target handling. Responsible for updating
 * the HUD with the information that were received from the server
 * @param self The event pointer
 * @param msg The network message to parse the event data from
 */
void CL_ActorReactionFireRemoveTarget (const eventRegister_t* self, dbuffer* msg)
{
	int shooterEntNum;
	int targetEntNum;
	int unused;

	NET_ReadFormat(msg, self->formatString, &shooterEntNum, &targetEntNum, &unused);

	const le_t* target = LE_Get(targetEntNum);
	if (!target)
		LE_NotFoundError(targetEntNum);

	UI_ExecuteConfunc("reactionfire_removetarget %i %i", shooterEntNum, target->entnum);
}
Exemple #19
0
static void CL_BattlescapeRadarGenPreview_f (void)
{
	int x, y, width, height;
	/* map to screen */
	CL_BattlescapeRadarMapInFrameBuffer(&x, &y, &width, &height);

	/* from screen to virtual screen */
	x /= viddef.rx;
	width /= viddef.rx;
	y /= viddef.ry;
	height /= viddef.ry;
	y = viddef.virtualHeight - y - height;

	UI_ExecuteConfunc("mn_radarhud_setmapborder %d %d %d %d", x, y, width, height);
}
Exemple #20
0
/**
 * @brief Adds UI Keybindings to the list for the Keylist UI
 */
static inline int CLMN_AddUIBindings (keyBindSpace_t scope)
{
	int cnt = 0;
	const int num = UI_GetKeyBindingCount();
	for (int i = 0; i < num; i++) {
		const uiKeyBinding_t* binding = UI_GetKeyBindingByIndex(i);
		if (binding == nullptr)
			continue;
		if (binding->inherited)
			continue;
		if (!Q_strvalid(binding->description))
			continue;

		UI_ExecuteConfunc("keybinding_add %i %i \"%s\" \"%s\"", cnt++, scope, Key_KeynumToString(binding->key), _(binding->description));
	}
	return cnt;
}
/**
 * @brief Sell one item of a given type.
 * @sa BS_BuyItem_f
 * @sa BS_SellAircraft_f
 * @sa BS_BuyAircraft_f
 */
static void BS_SellItem_f (void)
{
	int num;
	base_t *base = B_GetCurrentSelectedBase();

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

	if (!base)
		return;

	if (buyCat == FILTER_AIRCRAFT) {
		Com_DPrintf(DEBUG_CLIENT, "BS_SellItem_f: Redirects to BS_SellAircraft_f\n");
		BS_SellAircraft_f();
		return;
	}

	num = atoi(Cmd_Argv(1));
	if (num < 0 || num >= buyList.length)
		return;

	UI_ExecuteConfunc("buy_selectitem %i", num + buyList.scroll);
	{
		const objDef_t *item = BS_GetObjectDefition(&buyList.l[num + buyList.scroll]);
		/* don't sell more items than we have */
		const int numItems = min(B_ItemInBase(item, base), BS_GetBuySellFactor());
		/* Normal item (or equipment for UGVs/Robots if buyCategory==BUY_HEAVY) */
		assert(item);
		currentSelectedMenuEntry = item;
		INV_ItemDescription(item);

		/* don't sell more items than we have */
		if (numItems) {
			/* reinit the menu */
			B_UpdateStorageAndCapacity(base, item, -numItems, qfalse);
			BS_AddItemToMarket(item, numItems);
			BS_BuyType(base);
			CP_UpdateCredits(ccs.credits + BS_GetItemSellingPrice(item) * numItems);
			BS_UpdateItem(base, num);
		}
	}
}
/**
 * @brief Network event function for reaction fire mode changes. Responsible for updating
 * the HUD with the information that were received from the server
 * @param self The event pointer
 * @param msg The network message to parse the event data from
 * @sa HUD_UpdateReactionFiremodes
 */
void CL_ActorReactionFireChange (const eventRegister_t* self, dbuffer* msg)
{
	actorHands_t hand;
	int entnum, fmIdx, odIdx;

	NET_ReadFormat(msg, self->formatString, &entnum, &fmIdx, &hand, &odIdx);

	const le_t* le = LE_Get(entnum);
	if (!le)
		LE_NotFoundError(entnum);

	character_t* chr = CL_ActorGetChr(le);
	if (!chr)
		return;

	const objDef_t* od = INVSH_GetItemByIDX(odIdx);
	chr->RFmode.set(hand, fmIdx, od);

	UI_ExecuteConfunc("reactionfire_updated");
}
/**
 * @brief Network event function for reaction fire target handling. Responsible for updating
 * the HUD with the information that were received from the server
 * @param self The event pointer
 * @param msg The network message to parse the event data from
 */
void CL_ActorReactionFireTargetUpdate (const eventRegister_t* self, dbuffer* msg)
{
	int shooterEntNum;
	int targetEntNum;
	// if these TUs have arrived at 0, the reaction fire can be triggered
	int tusUntilTriggered;
	int unused;

	NET_ReadFormat(msg, self->formatString, &shooterEntNum, &targetEntNum, &tusUntilTriggered, &unused);

	const le_t* shooter = LE_Get(shooterEntNum);
	if (!shooter)
		LE_NotFoundError(shooterEntNum);

	const le_t* target = LE_Get(targetEntNum);
	if (!target)
		LE_NotFoundError(targetEntNum);

	const bool outOfRange = CL_ActorIsReactionFireOutOfRange(shooter, target);
	UI_ExecuteConfunc("reactionfire_updatetarget %i %i %i %i", shooterEntNum, target->entnum, tusUntilTriggered, outOfRange);
}
/**
 * @brief Select one entry on the list.
 * @sa BS_MarketScroll_f
 * @sa BS_AddToList
 */
static void BS_MarketClick_f (void)
{
	int num;

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

	num = atoi(Cmd_Argv(1));
	if (num >= buyList.length || num < 0)
		return;

	Cvar_Set("mn_item", "");

	switch (buyCat) {
	case FILTER_AIRCRAFT:
		assert(buyList.l[num].aircraft);
		BS_MarketAircraftDescription(buyList.l[num].aircraft->tpl);
		break;
	case FILTER_CRAFTITEM:
		UP_AircraftItemDescription(buyList.l[num].item);
		Cvar_Set("mn_aircraftname", "");
		break;
	case MAX_FILTERTYPES:
		break;
	default:
		if (buyList.l[num].item->craftitem.type != MAX_ACITEMS)
			UP_AircraftItemDescription(buyList.l[num].item);
		else
			INV_ItemDescription(buyList.l[num].item);
		currentSelectedMenuEntry = buyList.l[num].item;
		break;
	}

	/* update selected element */
	UI_ExecuteConfunc("buy_selectitem %i", num);
}
/**
 * @brief Buy one item of a given type.
 * @sa BS_SellItem_f
 * @sa BS_SellAircraft_f
 * @sa BS_BuyAircraft_f
 */
static void BS_BuyItem_f (void)
{
	int num;
	base_t *base = B_GetCurrentSelectedBase();

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

	if (!base)
		return;

	if (buyCat == FILTER_AIRCRAFT) {
		Com_DPrintf(DEBUG_CLIENT, "BS_BuyItem_f: Redirects to BS_BuyAircraft_f\n");
		BS_BuyAircraft_f();
		return;
	}

	num = atoi(Cmd_Argv(1));
	if (num < 0 || num >= buyList.length)
		return;

	UI_ExecuteConfunc("buy_selectitem %i", num + buyList.scroll);

	{
		/* Normal item (or equipment for UGVs/Robots if buyCategory==BUY_HEAVY) */
		const objDef_t *item = BS_GetObjectDefition(&buyList.l[num + buyList.scroll]);
		assert(item);
		currentSelectedMenuEntry = item;
		INV_ItemDescription(item);
		Com_DPrintf(DEBUG_CLIENT, "BS_BuyItem_f: item %s\n", item->id);
		BS_CheckAndDoBuyItem(base, item, BS_GetBuySellFactor());
		/* reinit the menu */
		BS_BuyType(base);
		BS_UpdateItem(base, num);
	}
}
Exemple #26
0
/**
 * @brief Init menu cvar for one savegame slot given by actual index.
 * @param[in] idx the savegame slot to retrieve gamecomment for
 * @sa SAV_GameReadGameComments_f
 */
static void SAV_GameReadGameComment (const int idx)
{
	saveFileHeader_t header;
	qFILE f;

	FS_OpenFile(va("save/slot%i.%s", idx, SAVEGAME_EXTENSION), &f, FILE_READ);
	if (f.f || f.z) {
		if (FS_Read(&header, sizeof(header), &f) != sizeof(header))
			Com_Printf("Warning: Savefile header may be corrupted\n");

		header.compressed = LittleLong(header.compressed);
		header.version = LittleLong(header.version);
		header.xmlSize = LittleLong(header.xmlSize);
		header.subsystems = LittleLong(header.subsystems);

		if (!SAV_VerifyHeader(&header))
			Com_Printf("Savegame header for slot%d is corrupted!\n", idx);
		else
			UI_ExecuteConfunc("update_save_game_info %i \"%s\" \"%s\" \"%s\"", idx, header.name, header.gameDate, header.realDate);

		FS_CloseFile(&f);
	}
}
/**
 * @brief Reads the entity number for client interaction
 * @sa EV_CLIENT_ACTION
 * @sa Touch_DoorTrigger
 * @sa CL_ActorUse
 * @todo Hud should have a button that should be activated now
 */
void CL_ActorClientAction (const eventRegister_t *self, dbuffer *msg)
{
	le_t* le;
	int number, actionEntityNumber;

	/* read data */
	NET_ReadFormat(msg, self->formatString, &number, &actionEntityNumber);

	/* get actor le */
	le = LE_Get(number);
	if (!le)
		LE_NotFoundError(number);

	/* set client action entity */
	le->clientAction = LE_Get(actionEntityNumber);
	if (!le->clientAction)
		LE_NotFoundError(actionEntityNumber);

	UI_ExecuteConfunc("enable_clientaction");

	Com_DPrintf(DEBUG_CLIENT, "CL_ActorClientAction: Set entity number: %i (for actor with entnum %i)\n",
			actionEntityNumber, number);
}
/**
 * @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;");
    }
}
Exemple #29
0
static void UI_CvarChangeListener (const char *cvarName, const char *oldValue, const char *newValue, void *data)
{
	linkedList_t *list = static_cast<linkedList_t*>(data);
	LIST_Foreach(list, char const, confunc) {
		UI_ExecuteConfunc("%s %s %s", confunc, oldValue, newValue);
	}
/**
 * @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);
}