mirror of
https://github.com/scp-fs2open/fs2open.github.com.git
synced 2026-11-09 04:49:39 -10:00
1514 lines
42 KiB
C++
1514 lines
42 KiB
C++
//
|
|
//
|
|
#include "ui.h"
|
|
|
|
#include "freespace.h"
|
|
|
|
#include "globalincs/alphacolors.h"
|
|
|
|
#include "cmdline/cmdline.h"
|
|
#include "cutscene/cutscenes.h"
|
|
#include "gamesnd/eventmusic.h"
|
|
#include "gamesequence/gamesequence.h"
|
|
#include "menuui/barracks.h"
|
|
#include "menuui/credits.h"
|
|
#include "menuui/mainhallmenu.h"
|
|
#include "menuui/optionsmenu.h"
|
|
#include "menuui/playermenu.h"
|
|
#include "menuui/readyroom.h"
|
|
#include "mission/missionmessage.h"
|
|
#include "mission/missiongoals.h"
|
|
#include "mission/missionbriefcommon.h"
|
|
#include "mission/missionparse.h"
|
|
#include "missionui/fictionviewer.h"
|
|
#include "missionui/missionbrief.h"
|
|
#include "mission/missioncampaign.h"
|
|
#include "missionui/missionscreencommon.h"
|
|
#include "missionui/missiondebrief.h"
|
|
#include "mission/missiongoals.h"
|
|
#include "mission/missioncampaign.h"
|
|
#include "missionui/redalert.h"
|
|
#include "network/multi.h"
|
|
#include "network/multiteamselect.h"
|
|
#include "playerman/managepilot.h"
|
|
#include "radar/radarsetup.h"
|
|
#include "ship/ship.h"
|
|
#include "weapon/weapon.h"
|
|
#include "scpui/SoundPlugin.h"
|
|
#include "scpui/rocket_ui.h"
|
|
#include "scripting/api/objs/techroom.h"
|
|
#include "scripting/api/objs/loop_brief.h"
|
|
#include "scripting/api/objs/redalert.h"
|
|
#include "scripting/api/objs/fictionviewer.h"
|
|
#include "scripting/api/objs/cmd_brief.h"
|
|
#include "scripting/api/objs/briefing.h"
|
|
#include "scripting/api/objs/debriefing.h"
|
|
#include "scripting/api/objs/shipwepselect.h"
|
|
#include "scripting/api/objs/color.h"
|
|
#include "scripting/api/objs/enums.h"
|
|
#include "scripting/api/objs/player.h"
|
|
#include "scripting/lua/LuaTable.h"
|
|
#include "stats/medals.h"
|
|
#include "stats/stats.h"
|
|
|
|
// Our Assert conflicts with the definitions inside libRocket
|
|
#pragma push_macro("Assert")
|
|
#undef Assert
|
|
|
|
#include <Rocket/Core/Lua/LuaType.h>
|
|
|
|
#pragma pop_macro("Assert")
|
|
|
|
namespace scripting {
|
|
namespace api {
|
|
|
|
//*************************Testing stuff*************************
|
|
// This section is for stuff that's considered experimental.
|
|
ADE_LIB(l_UserInterface, "UserInterface", "ui", "Functions for managing the \"scpui\" user interface system.");
|
|
|
|
ADE_FUNC(setOffset, l_UserInterface, "number x, number y",
|
|
"Sets the offset from the top left corner at which <b>all</b> rocket contexts will be rendered", "boolean",
|
|
"true if the operation was successful, false otherwise")
|
|
{
|
|
float x;
|
|
float y;
|
|
|
|
if (!ade_get_args(L, "ff", &x, &y)) {
|
|
return ADE_RETURN_FALSE;
|
|
}
|
|
|
|
scpui::setOffset(x, y);
|
|
|
|
return ADE_RETURN_TRUE;
|
|
}
|
|
|
|
ADE_FUNC(enableInput,
|
|
l_UserInterface,
|
|
"any context /* A libRocket Context value */",
|
|
"Enables input for the specified libRocket context",
|
|
"boolean",
|
|
"true if successfull")
|
|
{
|
|
using namespace Rocket::Core;
|
|
|
|
// Check parameter number
|
|
if (!ade_get_args(L, "*")) {
|
|
return ADE_RETURN_FALSE;
|
|
}
|
|
|
|
auto ctx = Lua::LuaType<Context>::check(L, 1);
|
|
|
|
if (ctx == nullptr) {
|
|
LuaError(L, "Parameter 1 is not a valid context handle!");
|
|
return ADE_RETURN_FALSE;
|
|
}
|
|
|
|
scpui::enableInput(ctx);
|
|
|
|
return ADE_RETURN_TRUE;
|
|
}
|
|
|
|
ADE_FUNC(disableInput, l_UserInterface, "", "Disables UI input", "boolean", "true if successfull")
|
|
{
|
|
scpui::disableInput();
|
|
|
|
return ADE_RETURN_TRUE;
|
|
}
|
|
|
|
ADE_VIRTVAR(ColorTags,
|
|
l_UserInterface,
|
|
nullptr,
|
|
"The available tagged colors",
|
|
"{ string => color ... }",
|
|
"A mapping from tag string to color value")
|
|
{
|
|
using namespace luacpp;
|
|
|
|
LuaTable mapping = LuaTable::create(L);
|
|
|
|
for (const auto& tagged : Tagged_Colors) {
|
|
SCP_string tag;
|
|
tag.resize(1, tagged.first);
|
|
|
|
mapping.addValue(tag, l_Color.Set(*tagged.second));
|
|
}
|
|
|
|
return ade_set_args(L, "t", mapping);
|
|
}
|
|
|
|
ADE_FUNC(DefaultTextColorTag,
|
|
l_UserInterface,
|
|
"number UiScreen",
|
|
"Gets the default color tag string for the specified state. 1 for Briefing, 2 for CBriefing, 3 for Debriefing, "
|
|
"4 for Fiction Viewer, 5 for Red Alert, 6 for Loop Briefing, 7 for Recommendation text. Defaults to 1. Index into ColorTags.",
|
|
"string",
|
|
"The default color tag")
|
|
{
|
|
int UiScreen;
|
|
|
|
if (!ade_get_args(L, "i", &UiScreen)) {
|
|
UiScreen = 1;
|
|
}
|
|
|
|
SCP_string tagStr;
|
|
char defaultColor = default_briefing_color;
|
|
|
|
switch (UiScreen) {
|
|
case 1:
|
|
defaultColor = default_briefing_color;
|
|
break;
|
|
case 2:
|
|
defaultColor = default_command_briefing_color;
|
|
break;
|
|
case 3:
|
|
defaultColor = default_debriefing_color;
|
|
break;
|
|
case 4:
|
|
defaultColor = default_fiction_viewer_color;
|
|
break;
|
|
case 5:
|
|
defaultColor = default_redalert_briefing_color;
|
|
break;
|
|
case 6:
|
|
defaultColor = default_loop_briefing_color;
|
|
break;
|
|
case 7:
|
|
defaultColor = default_recommendation_color;
|
|
break;
|
|
}
|
|
|
|
if (defaultColor == '\0' || !brief_verify_color_tag(defaultColor)) {
|
|
defaultColor = Color_Tags[0];
|
|
}
|
|
tagStr.resize(1, defaultColor);
|
|
|
|
return ade_set_args(L, "s", tagStr);
|
|
}
|
|
|
|
ADE_FUNC(playElementSound,
|
|
l_UserInterface,
|
|
"any element /* A libRocket element */, string event, string state = \"\"",
|
|
"Plays an element specific sound with an optional state for differentiating different UI states.",
|
|
"boolean",
|
|
"true if a sound was played, false otherwise")
|
|
{
|
|
using namespace Rocket::Core;
|
|
const char* event;
|
|
const char* state = "";
|
|
if (!ade_get_args(L, "*s|s", &event, &state)) {
|
|
return ADE_RETURN_FALSE;
|
|
}
|
|
|
|
auto el = Lua::LuaType<Element>::check(L, 1);
|
|
|
|
if (el == nullptr) {
|
|
return ADE_RETURN_FALSE;
|
|
}
|
|
|
|
return ade_set_args(L, "b", scpui::SoundPlugin::instance()->PlayElementSound(el, event, state));
|
|
}
|
|
|
|
ADE_FUNC(maybePlayCutscene, l_UserInterface, "enumeration MovieType, boolean RestartMusic, number ScoreIndex", "Plays a cutscene, if one exists, for the appropriate state transition. If RestartMusic is true, then the music score at ScoreIndex will be started after the cutscene plays.", nullptr, "Returns nothing")
|
|
{
|
|
enum_h movie_type;
|
|
bool restart_music = false;
|
|
int score_index = 0;
|
|
|
|
if (!ade_get_args(L, "obi", l_Enum.Get(&movie_type), &restart_music, &score_index))
|
|
return ADE_RETURN_NIL;
|
|
|
|
if (!movie_type.IsValid() || movie_type.index < LE_MOVIE_PRE_FICTION || movie_type.index > LE_MOVIE_END_CAMPAIGN)
|
|
{
|
|
Warning(LOCATION, "Invalid movie type index %d", movie_type.index);
|
|
return ADE_RETURN_NIL;
|
|
}
|
|
|
|
common_maybe_play_cutscene(movie_type.index - LE_MOVIE_PRE_FICTION, restart_music, score_index);
|
|
return ADE_RETURN_NIL;
|
|
}
|
|
|
|
ADE_FUNC(playCutscene, l_UserInterface, "string Filename, boolean RestartMusic, number ScoreIndex", "Plays a cutscene. If RestartMusic is true, then the music score at ScoreIndex will be started after the cutscene plays.", nullptr, "Returns nothing")
|
|
{
|
|
const char* filename;
|
|
bool restart_music = false;
|
|
int score_index = 0;
|
|
|
|
if (!ade_get_args(L, "sbi", &filename, &restart_music, &score_index))
|
|
return ADE_RETURN_NIL;
|
|
|
|
common_play_cutscene(filename, restart_music, score_index);
|
|
return ADE_RETURN_NIL;
|
|
}
|
|
|
|
//**********SUBLIBRARY: UserInterface/PilotSelect
|
|
ADE_LIB_DERIV(l_UserInterface_PilotSelect, "PilotSelect", nullptr,
|
|
"API for accessing values specific to the pilot select screen.<br><b>Warning:</b> This is an internal "
|
|
"API for the new UI system. This should not be used by other code and may be removed in the future!",
|
|
l_UserInterface);
|
|
|
|
ADE_VIRTVAR(MAX_PILOTS, l_UserInterface_PilotSelect, nullptr, "Gets the maximum number of possible pilots.", "number",
|
|
"The maximum number of pilots")
|
|
{
|
|
return ade_set_args(L, "i", MAX_PILOTS);
|
|
}
|
|
ADE_VIRTVAR(WarningCount, l_UserInterface_PilotSelect, nullptr, "The amount of warnings caused by the mod while loading.", "number",
|
|
"The maximum number of pilots")
|
|
{
|
|
return ade_set_args(L, "i", Global_warning_count);
|
|
}
|
|
ADE_VIRTVAR(ErrorCount, l_UserInterface_PilotSelect, nullptr, "The amount of errors caused by the mod while loading.", "number",
|
|
"The maximum number of pilots")
|
|
{
|
|
return ade_set_args(L, "i", Global_error_count);
|
|
}
|
|
|
|
ADE_FUNC(enumeratePilots, l_UserInterface_PilotSelect, nullptr,
|
|
"Lists all pilots available for the pilot selection<br>", "string[]",
|
|
"A table containing the pilots (without a file extension) or nil on error")
|
|
{
|
|
using namespace luacpp;
|
|
|
|
auto table = LuaTable::create(L);
|
|
|
|
auto pilots = player_select_enumerate_pilots();
|
|
for (size_t i = 0; i < pilots.size(); ++i) {
|
|
table.addValue(i + 1, pilots[i]);
|
|
}
|
|
|
|
return ade_set_args(L, "t", &table);
|
|
}
|
|
|
|
ADE_FUNC(getLastPilot, l_UserInterface_PilotSelect, nullptr,
|
|
"Reads the last active pilot from the config file and returns some information about it. callsign is the name "
|
|
"of the player and is_multi indicates whether the pilot was last active as a multiplayer pilot.",
|
|
"string", "The pilot name or nil if there was no last pilot")
|
|
{
|
|
using namespace luacpp;
|
|
|
|
auto callsign = player_get_last_player();
|
|
if (callsign.empty()) {
|
|
return ADE_RETURN_NIL;
|
|
}
|
|
|
|
return ade_set_args(L, "s", callsign.c_str());
|
|
}
|
|
|
|
ADE_FUNC(checkPilotLanguage, l_UserInterface_PilotSelect, "string callsign",
|
|
"Checks if the pilot with the specified callsign has the right language.", "boolean",
|
|
"true if pilot is valid, false otherwise")
|
|
{
|
|
const char* callsign;
|
|
if (!ade_get_args(L, "s", &callsign)) {
|
|
return ADE_RETURN_FALSE;
|
|
}
|
|
|
|
return ade_set_args(L, "b", valid_pilot(callsign, true));
|
|
}
|
|
|
|
ADE_FUNC(selectPilot, l_UserInterface_PilotSelect, "string callsign, boolean is_multi",
|
|
"Selects the pilot with the specified callsign and advances the game to the main menu.", nullptr, "nothing")
|
|
{
|
|
const char* callsign;
|
|
bool is_multi;
|
|
if (!ade_get_args(L, "sb", &callsign, &is_multi)) {
|
|
return ADE_RETURN_NIL;
|
|
}
|
|
|
|
player_finish_select(callsign, is_multi);
|
|
|
|
return ADE_RETURN_NIL;
|
|
}
|
|
|
|
ADE_FUNC(deletePilot, l_UserInterface_PilotSelect, "string callsign",
|
|
"Deletes the pilot with the specified callsign. This is not reversible!", "boolean",
|
|
"true on success, false otherwise")
|
|
{
|
|
const char* callsign;
|
|
if (!ade_get_args(L, "s", &callsign)) {
|
|
return ADE_RETURN_NIL;
|
|
}
|
|
|
|
return ade_set_args(L, "b", delete_pilot_file(callsign));
|
|
}
|
|
|
|
ADE_FUNC(
|
|
createPilot, l_UserInterface_PilotSelect, "string callsign, boolean is_multi, [string copy_from]",
|
|
"Creates a new pilot in either single or multiplayer mode and optionally copies settings from an existing pilot.",
|
|
"boolean", "true on success, false otherwise")
|
|
{
|
|
const char* callsign;
|
|
bool is_multi;
|
|
const char* copy_from = nullptr;
|
|
if (!ade_get_args(L, "sb|s", &callsign, &is_multi, ©_from)) {
|
|
return ADE_RETURN_NIL;
|
|
}
|
|
|
|
return ade_set_args(L, "b", player_create_new_pilot(callsign, is_multi, copy_from));
|
|
}
|
|
|
|
ADE_FUNC(isAutoselect, l_UserInterface_PilotSelect, nullptr,
|
|
"Determines if the pilot selection screen should automatically select the default user.", "boolean",
|
|
"true if autoselect is enabled, false otherwise")
|
|
{
|
|
return ade_set_args(L, "b", Cmdline_benchmark_mode || Cmdline_pilot);
|
|
}
|
|
|
|
ADE_VIRTVAR(CmdlinePilot, l_UserInterface_PilotSelect, nullptr,
|
|
"The pilot chosen from commandline, if any.", "string",
|
|
"The name if specified, nil otherwise")
|
|
{
|
|
if (Cmdline_pilot)
|
|
return ade_set_args(L, "s", Cmdline_pilot);
|
|
else
|
|
return ADE_RETURN_NIL;
|
|
}
|
|
|
|
//**********SUBLIBRARY: UserInterface/MainHall
|
|
ADE_LIB_DERIV(l_UserInterface_MainHall, "MainHall", nullptr,
|
|
"API for accessing values specific to the main hall screen.<br><b>Warning:</b> This is an internal "
|
|
"API for the new UI system. This should not be used by other code and may be removed in the future!",
|
|
l_UserInterface);
|
|
|
|
ADE_FUNC(startAmbientSound, l_UserInterface_MainHall, nullptr, "Starts the ambient mainhall sound.", nullptr, "nothing")
|
|
{
|
|
SCP_UNUSED(L);
|
|
main_hall_start_ambient();
|
|
return ADE_RETURN_NIL;
|
|
}
|
|
|
|
ADE_FUNC(stopAmbientSound, l_UserInterface_MainHall, nullptr, "Stops the ambient mainhall sound.", nullptr, "nothing")
|
|
{
|
|
SCP_UNUSED(L);
|
|
main_hall_stop_ambient();
|
|
return ADE_RETURN_NIL;
|
|
}
|
|
|
|
ADE_FUNC(startMusic, l_UserInterface_MainHall, nullptr, "Starts the mainhall music.", nullptr, "nothing")
|
|
{
|
|
SCP_UNUSED(L);
|
|
main_hall_start_music();
|
|
return ADE_RETURN_NIL;
|
|
}
|
|
|
|
//**********SUBLIBRARY: UserInterface/Barracks
|
|
ADE_LIB_DERIV(l_UserInterface_Barracks, "Barracks", nullptr,
|
|
"API for accessing values specific to the barracks screen.<br><b>Warning:</b> This is an internal "
|
|
"API for the new UI system. This should not be used by other code and may be removed in the future!",
|
|
l_UserInterface);
|
|
|
|
ADE_FUNC(listPilotImages, l_UserInterface_Barracks, nullptr, "Lists the names of the available pilot images.",
|
|
"string[]", "The list of pilot filenames or nil on error")
|
|
{
|
|
pilot_load_pic_list();
|
|
|
|
using namespace luacpp;
|
|
|
|
LuaTable out = LuaTable::create(L);
|
|
for (auto i = 0; i < Num_pilot_images; ++i) {
|
|
out.addValue(i + 1, Pilot_image_names[i]);
|
|
}
|
|
return ade_set_args(L, "t", &out);
|
|
}
|
|
|
|
ADE_FUNC(listSquadImages, l_UserInterface_Barracks, nullptr, "Lists the names of the available squad images.",
|
|
"string[]", "The list of squad filenames or nil on error")
|
|
{
|
|
pilot_load_squad_pic_list();
|
|
|
|
using namespace luacpp;
|
|
|
|
LuaTable out = LuaTable::create(L);
|
|
for (auto i = 0; i < Num_pilot_squad_images; ++i) {
|
|
out.addValue(i + 1, Pilot_squad_image_names[i]);
|
|
}
|
|
return ade_set_args(L, "t", &out);
|
|
}
|
|
|
|
ADE_FUNC(acceptPilot, l_UserInterface_Barracks, "player selection", "Accept the given player as the current player",
|
|
"boolean", "true on sucess, false otherwise")
|
|
{
|
|
player_h* plh;
|
|
if (!ade_get_args(L, "o", l_Player.GetPtr(&plh))) {
|
|
return ADE_RETURN_FALSE;
|
|
}
|
|
|
|
barracks_accept_pilot(plh->get());
|
|
return ADE_RETURN_TRUE;
|
|
}
|
|
|
|
//**********SUBLIBRARY: UserInterface/OptionsMenu
|
|
// This needs a slightly different name since there is already a type called "Options"
|
|
ADE_LIB_DERIV(l_UserInterface_Options,
|
|
"OptionsMenu",
|
|
nullptr,
|
|
"API for accessing values specific to the options screen.<br><b>Warning:</b> This is an internal "
|
|
"API for the new UI system. This should not be used by other code and may be removed in the future!",
|
|
l_UserInterface);
|
|
|
|
ADE_FUNC(playVoiceClip,
|
|
l_UserInterface_Options,
|
|
nullptr,
|
|
"Plays the example voice clip used for checking the voice volume",
|
|
"boolean",
|
|
"true on sucess, false otherwise")
|
|
{
|
|
options_play_voice_clip();
|
|
return ADE_RETURN_TRUE;
|
|
}
|
|
|
|
//**********SUBLIBRARY: UserInterface/CampaignMenu
|
|
ADE_LIB_DERIV(l_UserInterface_Campaign,
|
|
"CampaignMenu",
|
|
nullptr,
|
|
"API for accessing data related to the campaign UI.<br><b>Warning:</b> This is an internal "
|
|
"API for the new UI system. This should not be used by other code and may be removed in the future!",
|
|
l_UserInterface);
|
|
|
|
ADE_FUNC(loadCampaignList,
|
|
l_UserInterface_Campaign,
|
|
nullptr,
|
|
"Loads the list of available campaigns",
|
|
"boolean",
|
|
// ade_type_info({ade_type_array("string"), ade_type_array("string")}),
|
|
"false if something failed while loading the list, true otherwise")
|
|
{
|
|
return ade_set_args(L, "b", !campaign_build_campaign_list());
|
|
}
|
|
|
|
ADE_FUNC(getCampaignList,
|
|
l_UserInterface_Campaign,
|
|
nullptr,
|
|
"Get the campaign name and description lists",
|
|
"string[], string[], string[]",
|
|
"Three tables with the names, file names, and descriptions of the campaigns")
|
|
{
|
|
luacpp::LuaTable nameTable = luacpp::LuaTable::create(L);
|
|
luacpp::LuaTable fileNameTable = luacpp::LuaTable::create(L);
|
|
luacpp::LuaTable descriptionTable = luacpp::LuaTable::create(L);
|
|
|
|
for (int i = 0; i < Num_campaigns; ++i) {
|
|
nameTable.addValue(i + 1, Campaign_names[i]);
|
|
fileNameTable.addValue(i + 1, Campaign_file_names[i]);
|
|
|
|
auto description = Campaign_descs[i];
|
|
descriptionTable.addValue(i + 1, description ? description : "");
|
|
}
|
|
|
|
// We actually do not need this anymore now so free it immediately
|
|
mission_campaign_free_list();
|
|
|
|
return ade_set_args(L, "ttt", nameTable, fileNameTable, descriptionTable);
|
|
}
|
|
|
|
ADE_FUNC(selectCampaign,
|
|
l_UserInterface_Campaign,
|
|
"string campaign_file",
|
|
"Selects the specified campaign file name",
|
|
"boolean",
|
|
"true if successful, false otherwise")
|
|
{
|
|
const char* filename = nullptr;
|
|
if (!ade_get_args(L, "s", &filename)) {
|
|
return ADE_RETURN_FALSE;
|
|
}
|
|
|
|
campaign_select_campaign(filename);
|
|
|
|
return ADE_RETURN_TRUE;
|
|
}
|
|
|
|
ADE_FUNC(resetCampaign,
|
|
l_UserInterface_Campaign,
|
|
"string campaign_file",
|
|
"Resets the campaign with the specified file name",
|
|
"boolean",
|
|
"true if successful, false otherwise")
|
|
{
|
|
const char* filename = nullptr;
|
|
if (!ade_get_args(L, "s", &filename)) {
|
|
return ADE_RETURN_FALSE;
|
|
}
|
|
|
|
campaign_reset(filename);
|
|
|
|
return ADE_RETURN_TRUE;
|
|
}
|
|
|
|
//**********SUBLIBRARY: UserInterface/Briefing
|
|
ADE_LIB_DERIV(l_UserInterface_Brief,
|
|
"Briefing",
|
|
nullptr,
|
|
"API for accessing data related to the briefing UI.<br><b>Warning:</b> This is an internal "
|
|
"API for the new UI system. This should not be used by other code and may be removed in the future!",
|
|
l_UserInterface);
|
|
|
|
ADE_FUNC(getBriefingMusicName,
|
|
l_UserInterface_Brief,
|
|
nullptr,
|
|
"Gets the file name of the music file to play for the briefing.",
|
|
"string",
|
|
"The file name or empty if no music")
|
|
{
|
|
return ade_set_args(L, "s", common_music_get_filename(SCORE_BRIEFING).c_str());
|
|
}
|
|
|
|
ADE_FUNC(runBriefingStageHook,
|
|
l_UserInterface_Brief,
|
|
"number oldStage, number newStage",
|
|
"Run $On Briefing Stage: hooks.",
|
|
nullptr,
|
|
nullptr)
|
|
{
|
|
int oldStage = -1, newStage = -1;
|
|
if (ade_get_args(L, "ii", &oldStage, &newStage) == 2) {
|
|
// Subtract 1 to convert from Lua conventions to C conventions
|
|
common_fire_stage_script_hook(oldStage - 1, newStage - 1);
|
|
} else {
|
|
LuaError(L, "Bad arguments given to ui.runBriefingStageHook!");
|
|
}
|
|
return ADE_RETURN_NIL;
|
|
}
|
|
|
|
ADE_FUNC(initBriefing,
|
|
l_UserInterface_Brief,
|
|
nullptr,
|
|
"Initializes the briefing and prepares the map for drawing. Also handles various non-UI housekeeping tasks "
|
|
"and compacts the stages to remove those that should not be shown.",
|
|
nullptr,
|
|
nullptr)
|
|
{
|
|
SCP_UNUSED(L);
|
|
|
|
brief_api_init();
|
|
|
|
return ADE_RETURN_NIL;
|
|
}
|
|
|
|
ADE_FUNC(closeBriefing,
|
|
l_UserInterface_Brief,
|
|
nullptr,
|
|
"Closes the briefing and pauses the map. Required after using the briefing API!",
|
|
nullptr,
|
|
nullptr)
|
|
{
|
|
SCP_UNUSED(L);
|
|
brief_api_close();
|
|
return ADE_RETURN_NIL;
|
|
}
|
|
|
|
ADE_FUNC(getBriefing,
|
|
l_UserInterface_Brief,
|
|
nullptr,
|
|
"Get the briefing",
|
|
"briefing",
|
|
"The briefing data")
|
|
{
|
|
// get a pointer to the appropriate briefing structure
|
|
if (MULTI_TEAM) {
|
|
return ade_set_args(L, "o", l_Brief.Set(Net_player->p_info.team));
|
|
} else {
|
|
return ade_set_args(L, "o", l_Brief.Set(0));
|
|
}
|
|
|
|
}
|
|
|
|
ADE_FUNC(exitLoop,
|
|
l_UserInterface_Brief,
|
|
nullptr,
|
|
"Skips the current mission, exits the campaign loop, and loads the next non-loop mission in a campaign. Returns to the main hall if the player is not in a campaign.",
|
|
nullptr,
|
|
nullptr)
|
|
{
|
|
SCP_UNUSED(L);
|
|
|
|
if (!(Game_mode & GM_CAMPAIGN_MODE)) {
|
|
gameseq_post_event(GS_EVENT_MAIN_MENU);
|
|
}
|
|
|
|
mission_campaign_exit_loop();
|
|
|
|
return ADE_RETURN_NIL;
|
|
}
|
|
|
|
ADE_FUNC(skipMission,
|
|
l_UserInterface_Brief,
|
|
nullptr,
|
|
"Skips the current mission, and loads the next mission in a campaign. Returns to the main hall if the player is not in a campaign.",
|
|
nullptr,
|
|
nullptr)
|
|
{
|
|
SCP_UNUSED(L);
|
|
|
|
if (!(Game_mode & GM_CAMPAIGN_MODE)) {
|
|
gameseq_post_event(GS_EVENT_MAIN_MENU);
|
|
}
|
|
|
|
mission_campaign_skip_to_next();
|
|
|
|
return ADE_RETURN_NIL;
|
|
}
|
|
|
|
ADE_FUNC(skipTraining,
|
|
l_UserInterface_Brief,
|
|
nullptr,
|
|
"Skips the current training mission, and loads the next mission in a campaign. Returns to the main hall if the player is not in a campaign.",
|
|
nullptr,
|
|
nullptr)
|
|
{
|
|
SCP_UNUSED(L);
|
|
|
|
if (!(Game_mode & GM_CAMPAIGN_MODE)) {
|
|
gameseq_post_event(GS_EVENT_MAIN_MENU);
|
|
}
|
|
|
|
// tricky part. Need to move to the next mission in the campaign.
|
|
mission_goal_mark_objectives_complete();
|
|
mission_goal_fail_incomplete();
|
|
mission_campaign_store_goals_and_events_and_variables();
|
|
|
|
mission_campaign_eval_next_mission();
|
|
mission_campaign_mission_over();
|
|
|
|
if (Campaign.next_mission == -1 || (The_mission.flags[Mission::Mission_Flags::End_to_mainhall])) {
|
|
gameseq_post_event(GS_EVENT_MAIN_MENU);
|
|
} else {
|
|
gameseq_post_event(GS_EVENT_START_GAME);
|
|
}
|
|
|
|
return ADE_RETURN_NIL;
|
|
}
|
|
|
|
// For now any loadout error checking needs to happen in the script to prevent FSO from
|
|
// generating a popup that will not be interactible from Librocket. A later update to this
|
|
// method will introduce return values instead of generating popups and those return values
|
|
// can be used to handle loadout popups on the script side
|
|
ADE_FUNC(commitToMission,
|
|
l_UserInterface_Brief,
|
|
nullptr,
|
|
"Commits to the current mission with current loadout data, and starts the mission. Returns an integer to represent "
|
|
"built-in errors or 0 if successful. 1 = general error, 2 = a player ship has no weapons, 3 = the required weapon was not found "
|
|
"loaded on a ship, 4 = 2 or more required weapons were not found loaded on a ship, 5 = a gap in a ship's weapon banks was discovered "
|
|
"and all empty banks must be at the bottom of the list, 6 = a player has no ship selected",
|
|
"number error",
|
|
"the error value")
|
|
{
|
|
return ade_set_args(L, "i", static_cast<int>(commit_pressed(true)));
|
|
}
|
|
|
|
ADE_FUNC(drawBriefingMap,
|
|
l_UserInterface_Brief,
|
|
"number x, number y, [number width = 888, number height = 371]",
|
|
"Draws the briefing map for the current mission at the specified coordinates. Note that the "
|
|
"width and height must be a specific aspect ratio to match retail. If changed then some icons "
|
|
"may be clipped from view unexpectedly. Must be called On Frame.",
|
|
nullptr,
|
|
nullptr)
|
|
{
|
|
|
|
int x1;
|
|
int y1;
|
|
int x2 = 888;
|
|
int y2 = 371;
|
|
|
|
if (!ade_get_args(L, "ii|ii", &x1, &y1, &x2, &y2)) {
|
|
LuaError(L, "X and Y coordinates not provided!");
|
|
return ADE_RETURN_NIL;
|
|
}
|
|
|
|
// Saving retail coords here for posterity
|
|
// GR_640 - 19, 147, 555, 232
|
|
// GR_1024 - 30, 235, 888, 371
|
|
|
|
bscreen.map_x1 = x1;
|
|
bscreen.map_x2 = x1 + x2;
|
|
bscreen.map_y1 = y1;
|
|
bscreen.map_y2 = y1 + y2;
|
|
bscreen.resize = GR_RESIZE_NONE;
|
|
|
|
brief_api_do_frame(flRealframetime);
|
|
|
|
return ADE_RETURN_NIL;
|
|
}
|
|
|
|
ADE_FUNC(callNextMapStage,
|
|
l_UserInterface_Brief,
|
|
nullptr,
|
|
"Sends the briefing map to the next stage.",
|
|
nullptr,
|
|
nullptr)
|
|
{
|
|
SCP_UNUSED(L);
|
|
brief_do_next_pressed(0);
|
|
return ADE_RETURN_NIL;
|
|
}
|
|
|
|
ADE_FUNC(callPrevMapStage,
|
|
l_UserInterface_Brief,
|
|
nullptr,
|
|
"Sends the briefing map to the previous stage.",
|
|
nullptr,
|
|
nullptr)
|
|
{
|
|
SCP_UNUSED(L);
|
|
brief_do_prev_pressed();
|
|
return ADE_RETURN_NIL;
|
|
}
|
|
|
|
ADE_FUNC(callFirstMapStage,
|
|
l_UserInterface_Brief,
|
|
nullptr,
|
|
"Sends the briefing map to the first stage.",
|
|
nullptr,
|
|
nullptr)
|
|
{
|
|
SCP_UNUSED(L);
|
|
brief_do_start_pressed();
|
|
return ADE_RETURN_NIL;
|
|
}
|
|
|
|
ADE_FUNC(callLastMapStage,
|
|
l_UserInterface_Brief,
|
|
nullptr,
|
|
"Sends the briefing map to the last stage.",
|
|
nullptr,
|
|
nullptr)
|
|
{
|
|
SCP_UNUSED(L);
|
|
brief_do_end_pressed();
|
|
return ADE_RETURN_NIL;
|
|
}
|
|
|
|
ADE_LIB_DERIV(l_Briefing_Goals, "Objectives", nullptr, nullptr, l_UserInterface_Brief);
|
|
ADE_INDEXER(l_Briefing_Goals,
|
|
"number Index",
|
|
"Array of goals",
|
|
"mission_goal",
|
|
"goal handle, or invalid handle if index is invalid")
|
|
{
|
|
int idx;
|
|
if (!ade_get_args(L, "*i", &idx))
|
|
return ade_set_error(L, "s", "");
|
|
|
|
return ade_set_args(L, "o", l_Goals.Set(idx));
|
|
}
|
|
|
|
ADE_FUNC(__len, l_Briefing_Goals, nullptr, "The number of goals in the mission", "number", "The number of goals.")
|
|
{
|
|
return ade_set_args(L, "i", Num_goals);
|
|
}
|
|
|
|
//**********SUBLIBRARY: UserInterface/CommandBriefing
|
|
ADE_LIB_DERIV(l_UserInterface_CmdBrief,
|
|
"CommandBriefing",
|
|
nullptr,
|
|
"API for accessing data related to the command briefing UI.<br><b>Warning:</b> This is an internal "
|
|
"API for the new UI system. This should not be used by other code and may be removed in the future!",
|
|
l_UserInterface);
|
|
|
|
ADE_FUNC(getCmdBriefing,
|
|
l_UserInterface_CmdBrief,
|
|
nullptr,
|
|
"Get the command briefing.",
|
|
"cmd_briefing",
|
|
"The briefing data")
|
|
{
|
|
// The cmd briefing code has support for specifying the team but only sets the index to 0
|
|
return ade_set_args(L, "o", l_CmdBrief.Set(0));
|
|
}
|
|
|
|
//**********SUBLIBRARY: UserInterface/Debriefing
|
|
ADE_LIB_DERIV(l_UserInterface_Debrief,
|
|
"Debriefing",
|
|
nullptr,
|
|
"API for accessing data related to the debriefing UI.<br><b>Warning:</b> This is an internal "
|
|
"API for the new UI system. This should not be used by other code and may be removed in the future!",
|
|
l_UserInterface);
|
|
|
|
ADE_FUNC(initDebriefing,
|
|
l_UserInterface_Debrief,
|
|
nullptr,
|
|
"Builds the debriefing, the stats, sets the next campaign mission, and makes all relevant data accessible",
|
|
"number",
|
|
"Returns true when completed")
|
|
{
|
|
//This is used to skip some UI preloading in debrief init
|
|
API_Access = true;
|
|
|
|
// stop all looping mission sounds
|
|
game_stop_looped_sounds();
|
|
|
|
// fail all incomplete goals before entering debriefing
|
|
mission_goal_fail_incomplete();
|
|
hud_config_as_player();
|
|
debrief_init();
|
|
|
|
API_Access = false;
|
|
|
|
return ade_set_args(L, "b", true);
|
|
}
|
|
|
|
ADE_FUNC(getDebriefingMusicName,
|
|
l_UserInterface_Debrief,
|
|
nullptr,
|
|
"Gets the file name of the music file to play for the debriefing.",
|
|
"string",
|
|
"The file name or empty if no music")
|
|
{
|
|
return ade_set_args(L, "s", common_music_get_filename(debrief_select_music()).c_str());
|
|
}
|
|
|
|
ADE_FUNC(getDebriefing, l_UserInterface_Debrief, nullptr, "Get the debriefing", "debriefing", "The debriefing data")
|
|
{
|
|
// get a pointer to the appropriate debriefing structure
|
|
if (MULTI_TEAM) {
|
|
return ade_set_args(L, "o", l_Debrief.Set(Net_player->p_info.team));
|
|
} else {
|
|
return ade_set_args(L, "o", l_Debrief.Set(0));
|
|
}
|
|
}
|
|
|
|
ADE_FUNC(getEarnedMedal,
|
|
l_UserInterface_Debrief,
|
|
nullptr,
|
|
"Get the earned medal name and bitmap",
|
|
"string, string",
|
|
"The name and bitmap or NIL if not earned")
|
|
{
|
|
char filename[80];
|
|
SCP_string displayname;
|
|
|
|
if (Player->stats.m_medal_earned != -1) {
|
|
debrief_choose_medal_variant(filename,
|
|
Player->stats.m_medal_earned,
|
|
Player->stats.medal_counts[Player->stats.m_medal_earned] - 1);
|
|
displayname = Medals[Player->stats.m_medal_earned].get_display_name();
|
|
|
|
return ade_set_args(L, "ss", displayname, filename);
|
|
} else {
|
|
return ADE_RETURN_NIL;
|
|
}
|
|
}
|
|
|
|
ADE_FUNC(getEarnedPromotion,
|
|
l_UserInterface_Debrief,
|
|
nullptr,
|
|
"Get the earned promotion stage, name, and bitmap",
|
|
"debriefing_stage, string, string",
|
|
"The promotion stage, name and bitmap or NIL if not earned")
|
|
{
|
|
char filename[80];
|
|
SCP_string displayname;
|
|
|
|
if (Player->stats.m_promotion_earned != -1) {
|
|
Promoted = Player->stats.m_promotion_earned;
|
|
debrief_choose_medal_variant(filename, Rank_medal_index, Promoted);
|
|
displayname = Ranks[Promoted].name;
|
|
|
|
return ade_set_args(L, "oss", l_DebriefStage.Set(debrief_stage_h(&Promotion_stage)), displayname, filename);
|
|
} else {
|
|
return ADE_RETURN_NIL;
|
|
}
|
|
}
|
|
|
|
ADE_FUNC(getEarnedBadge,
|
|
l_UserInterface_Debrief,
|
|
nullptr,
|
|
"Get the earned badge stage, name, and bitmap",
|
|
"debriefing_stage, string, string",
|
|
"The badge stage, name and bitmap or NIL if not earned")
|
|
{
|
|
char filename[80];
|
|
SCP_string displayname;
|
|
|
|
if (Player->stats.m_badge_earned.size()) {
|
|
debrief_choose_medal_variant(filename,
|
|
Player->stats.m_badge_earned.back(),
|
|
Player->stats.medal_counts[Player->stats.m_badge_earned.back()] - 1);
|
|
displayname = Ranks[Promoted].name;
|
|
|
|
return ade_set_args(L, "oss", l_DebriefStage.Set(debrief_stage_h(&Badge_stage)), displayname, filename);
|
|
} else {
|
|
return ADE_RETURN_NIL;
|
|
}
|
|
}
|
|
|
|
ADE_FUNC(clearMissionStats,
|
|
l_UserInterface_Debrief,
|
|
nullptr,
|
|
"Clears out the player's mission stats.",
|
|
nullptr,
|
|
nullptr)
|
|
{
|
|
SCP_UNUSED(L); // unused parameter
|
|
Player->flags &= ~PLAYER_FLAGS_PROMOTED;
|
|
scoring_level_init(&Player->stats);
|
|
return ADE_RETURN_NIL;
|
|
}
|
|
|
|
ADE_FUNC(getTraitor,
|
|
l_UserInterface_Debrief,
|
|
nullptr,
|
|
"Get the traitor stage",
|
|
"debriefing_stage",
|
|
"The traitor stage or nil if the player is not traitor. Should be coupled with clearMissionStats if true")
|
|
{
|
|
if (Turned_traitor) {
|
|
return ade_set_args(L, "o", l_DebriefStage.Set(debrief_stage_h(&Traitor_debriefing.stages[0])));
|
|
} else {
|
|
return ADE_RETURN_NIL;
|
|
}
|
|
}
|
|
|
|
ADE_FUNC(mustReplay,
|
|
l_UserInterface_Debrief,
|
|
nullptr,
|
|
"Gets whether or not the player must replay the mission. Should be coupled with clearMissionStats if true",
|
|
"boolean",
|
|
"true if must replay, false otherwise")
|
|
{
|
|
|
|
if (Must_replay_mission) {
|
|
return ade_set_args(L, "b", true);
|
|
} else {
|
|
return ade_set_args(L, "b", false);
|
|
}
|
|
}
|
|
|
|
ADE_FUNC(canSkip,
|
|
l_UserInterface_Debrief,
|
|
nullptr,
|
|
"Gets whether or not the player has failed enough times to trigger a skip dialog",
|
|
"boolean",
|
|
"true if can skip, false otherwise")
|
|
{
|
|
|
|
if (Player->failures_this_session >= PLAYER_MISSION_FAILURE_LIMIT) {
|
|
return ade_set_args(L, "b", true);
|
|
} else {
|
|
return ade_set_args(L, "b", false);
|
|
}
|
|
}
|
|
|
|
ADE_FUNC(replayMission,
|
|
l_UserInterface_Debrief,
|
|
"[boolean restart = true]",
|
|
"Resets the mission outcome, and optionally restarts the mission at the briefing; "
|
|
"true to restart the mission, false to stay at current UI. Defaults to true.",
|
|
nullptr,
|
|
nullptr)
|
|
{
|
|
|
|
bool restart = true;
|
|
|
|
ade_get_args(L, "|b", &restart);
|
|
|
|
// This is used to skip some UI preloading in debrief init
|
|
API_Access = true;
|
|
|
|
debrief_close();
|
|
|
|
if (restart) {
|
|
gameseq_post_event(GS_EVENT_START_GAME);
|
|
}
|
|
|
|
API_Access = false;
|
|
|
|
return ADE_RETURN_NIL;
|
|
}
|
|
|
|
ADE_FUNC(acceptMission,
|
|
l_UserInterface_Debrief,
|
|
"[boolean start = true]",
|
|
"Accepts the mission outcome, saves the stats, and optionally begins the next mission if in campaign; "
|
|
"true to start the next mission, false to stay at current UI. Defaults to true.",
|
|
nullptr,
|
|
nullptr)
|
|
{
|
|
bool start = true;
|
|
|
|
ade_get_args(L, "|b", &start);
|
|
|
|
// This is used to skip some UI preloading in debrief init
|
|
API_Access = true;
|
|
|
|
if (start) {
|
|
debrief_accept(1);
|
|
} else {
|
|
debrief_accept(0);
|
|
};
|
|
|
|
debrief_close();
|
|
|
|
API_Access = false;
|
|
|
|
return ADE_RETURN_NIL;
|
|
}
|
|
|
|
//**********SUBLIBRARY: UserInterface/LoopBrief
|
|
ADE_LIB_DERIV(l_UserInterface_LoopBrief,
|
|
"LoopBrief",
|
|
nullptr,
|
|
"API for accessing data related to the loop brief UI.<br><b>Warning:</b> This is an internal "
|
|
"API for the new UI system. This should not be used by other code and may be removed in the future!",
|
|
l_UserInterface);
|
|
|
|
ADE_FUNC(getLoopBrief,
|
|
l_UserInterface_LoopBrief,
|
|
nullptr,
|
|
"Get the loop brief.",
|
|
"loop_brief_stage",
|
|
"The loop brief data")
|
|
{
|
|
return ade_set_args(L, "o", l_LoopBriefStage.Set(cmission_h(Campaign.current_mission)));
|
|
}
|
|
|
|
ADE_FUNC(setLoopChoice, l_UserInterface_LoopBrief, "boolean", "Accepts mission outcome and then True to go to loop, False to skip", nullptr, nullptr)
|
|
{
|
|
bool choice = false;
|
|
ade_get_args(L, "|b", &choice);
|
|
|
|
if (choice) {
|
|
// select the loop mission
|
|
Campaign.loop_enabled = 1;
|
|
Campaign.loop_reentry = Campaign.next_mission; // save reentry pt, so we can break out of loop
|
|
Campaign.next_mission = Campaign.loop_mission;
|
|
|
|
mission_campaign_mission_over();
|
|
} else {
|
|
mission_campaign_mission_over();
|
|
}
|
|
|
|
return ADE_RETURN_NIL;
|
|
}
|
|
|
|
//**********SUBLIBRARY: UserInterface/RedAlert
|
|
ADE_LIB_DERIV(l_UserInterface_RedAlert,
|
|
"RedAlert",
|
|
nullptr,
|
|
"API for accessing data related to the Red Alert UI.<br><b>Warning:</b> This is an internal "
|
|
"API for the new UI system. This should not be used by other code and may be removed in the future!",
|
|
l_UserInterface);
|
|
|
|
ADE_FUNC(getRedAlert,
|
|
l_UserInterface_RedAlert,
|
|
nullptr,
|
|
"Get the red alert brief.",
|
|
"red_alert_stage",
|
|
"The red-alert data")
|
|
{
|
|
if (Briefings[0].num_stages) {
|
|
return ade_set_args(L, "o", l_RedAlertStage.Set(redalert_stage_h(0,0)));
|
|
} else {
|
|
return ADE_RETURN_NIL;
|
|
}
|
|
}
|
|
|
|
ADE_FUNC(replayPreviousMission,
|
|
l_UserInterface_RedAlert,
|
|
nullptr,
|
|
"Loads the previous mission of the campaign, does nothing if not in campaign",
|
|
"boolean",
|
|
"Returns true if the operation was successful, false otherwise")
|
|
{
|
|
if (!mission_campaign_previous_mission()) {
|
|
return ADE_RETURN_FALSE;
|
|
} else {
|
|
return ADE_RETURN_TRUE;
|
|
}
|
|
}
|
|
|
|
//**********SUBLIBRARY: UserInterface/FictionViewer
|
|
ADE_LIB_DERIV(l_UserInterface_FictionViewer,
|
|
"FictionViewer",
|
|
nullptr,
|
|
"API for accessing data related to the fiction viewer UI.<br><b>Warning:</b> This is an internal "
|
|
"API for the new UI system. This should not be used by other code and may be removed in the future!",
|
|
l_UserInterface);
|
|
|
|
ADE_FUNC(getFiction, l_UserInterface_FictionViewer, nullptr, "Get the fiction.", "fiction_viewer_stage", "The fiction data")
|
|
{
|
|
if (Fiction_viewer_active_stage >= 0) {
|
|
return ade_set_args(L, "o", l_FictionViewerStage.Set(fiction_viewer_stage_h(Fiction_viewer_active_stage)));
|
|
} else {
|
|
return ADE_RETURN_NIL;
|
|
}
|
|
}
|
|
|
|
ADE_FUNC(getFictionMusicName, l_UserInterface_FictionViewer, nullptr,
|
|
"Gets the file name of the music file to play for the fiction viewer.",
|
|
"string",
|
|
"The file name or empty if no music")
|
|
{
|
|
return ade_set_args(L, "s", common_music_get_filename(SCORE_FICTION_VIEWER).c_str());
|
|
}
|
|
|
|
//**********SUBLIBRARY: UserInterface/ShipWepSelect
|
|
ADE_LIB_DERIV(l_UserInterface_ShipWepSelect,
|
|
"ShipWepSelect",
|
|
nullptr,
|
|
"API for accessing data related to the ship and weapon select UIs.<br><b>Warning:</b> This is an internal "
|
|
"API for the new UI system. This should not be used by other code and may be removed in the future!",
|
|
l_UserInterface);
|
|
|
|
ADE_FUNC(initSelect,
|
|
l_UserInterface_ShipWepSelect,
|
|
nullptr,
|
|
"Initializes selection data including wing slots, ship and weapon pool, and loadout information",
|
|
nullptr,
|
|
nullptr)
|
|
{
|
|
//Note this does all the things from common_select_init() in missionscreencommon.cpp except load UI
|
|
//elements into memory - Mjn
|
|
|
|
SCP_UNUSED(L); // unused parameter
|
|
|
|
Common_team = 0;
|
|
|
|
if ((Game_mode & GM_MULTIPLAYER) && IS_MISSION_MULTI_TEAMS)
|
|
Common_team = Net_player->p_info.team;
|
|
|
|
common_set_team_pointers(Common_team);
|
|
|
|
ship_select_common_init();
|
|
weapon_select_common_init();
|
|
|
|
if ( Game_mode & GM_MULTIPLAYER ) {
|
|
multi_ts_common_init();
|
|
}
|
|
|
|
// restore loadout from Player_loadout if this is the same mission as the one previously played
|
|
if ( !(Game_mode & GM_MULTIPLAYER) ) {
|
|
if ( !stricmp(Player_loadout.filename, Game_current_mission_filename) ) {
|
|
wss_maybe_restore_loadout();
|
|
ss_synch_interface();
|
|
wl_synch_interface();
|
|
}
|
|
}
|
|
|
|
return ADE_RETURN_NIL;
|
|
}
|
|
|
|
ADE_FUNC(saveLoadout,
|
|
l_UserInterface_ShipWepSelect,
|
|
nullptr,
|
|
"Saves the current loadout to the player file. Only should be used when a mission is loaded but has not been started.",
|
|
nullptr,
|
|
nullptr)
|
|
{
|
|
SCP_UNUSED(L); // unused parameter
|
|
|
|
// This could be requested before Common_team has been initialized, so let's check.
|
|
// Freespace.cpp will clear Common_select_inited if the player ever leaves a valid
|
|
// "briefing" game state, so this should be a pretty safe check to avoid the assert
|
|
// contained within. - Mjn
|
|
if (Common_select_inited) {
|
|
wss_save_loadout();
|
|
} else {
|
|
return ADE_RETURN_NIL;
|
|
}
|
|
|
|
return ADE_RETURN_NIL;
|
|
}
|
|
|
|
ADE_LIB_DERIV(l_Ship_Pool, "Ship_Pool", nullptr, nullptr, l_UserInterface_ShipWepSelect);
|
|
ADE_INDEXER(l_Ship_Pool,
|
|
"number Index, number amount",
|
|
"Array of ship amounts available in the pool for selection in the current mission. Index is index into Ship Classes.",
|
|
"number",
|
|
"Amount of the ship that's available")
|
|
{
|
|
int idx;
|
|
int amount;
|
|
if (!ade_get_args(L, "*i|i", &idx, &amount))
|
|
return ADE_RETURN_NIL;
|
|
|
|
if (idx < 0 || idx > ship_info_size()) {
|
|
return ADE_RETURN_NIL;
|
|
};
|
|
|
|
idx--; // Convert to Lua's 1 based index system
|
|
|
|
if (ADE_SETTING_VAR) {
|
|
if (amount < 0) {
|
|
Ss_pool[idx] = 0;
|
|
} else {
|
|
Ss_pool[idx] = amount;
|
|
}
|
|
}
|
|
|
|
return ade_set_args(L, "i", Ss_pool[idx]);
|
|
}
|
|
|
|
ADE_FUNC(__len, l_Ship_Pool, nullptr, "The number of ship classes in the pool", "number", "The number of ship classes.")
|
|
{
|
|
return ade_set_args(L, "i", ship_info_size());
|
|
}
|
|
|
|
ADE_LIB_DERIV(l_Weapon_Pool, "Weapon_Pool", nullptr, nullptr, l_UserInterface_ShipWepSelect);
|
|
ADE_INDEXER(l_Weapon_Pool,
|
|
"number Index, number amount",
|
|
"Array of weapon amounts available in the pool for selection in the current mission. Index is index into Weapon Classes.",
|
|
"number",
|
|
"Amount of the weapon that's available")
|
|
{
|
|
int idx;
|
|
int amount;
|
|
if (!ade_get_args(L, "*i|i", &idx, &amount))
|
|
return ADE_RETURN_NIL;
|
|
|
|
if (idx < 0 || idx > weapon_info_size()) {
|
|
return ADE_RETURN_NIL;
|
|
};
|
|
|
|
idx--; // Convert to Lua's 1 based index system
|
|
|
|
if (ADE_SETTING_VAR) {
|
|
if (amount < 0) {
|
|
Wl_pool[idx] = 0;
|
|
} else {
|
|
Wl_pool[idx] = amount;
|
|
}
|
|
}
|
|
|
|
return ade_set_args(L, "i", Wl_pool[idx]);
|
|
}
|
|
|
|
ADE_FUNC(__len,
|
|
l_Weapon_Pool, nullptr, "The number of weapon classes in the pool", "number", "The number of weapon classes.")
|
|
{
|
|
return ade_set_args(L, "i", weapon_info_size());
|
|
}
|
|
|
|
ADE_FUNC(resetSelect,
|
|
l_UserInterface_ShipWepSelect,
|
|
nullptr,
|
|
"Resets selection data to mission defaults including wing slots, ship and weapon pool, and loadout information",
|
|
nullptr,
|
|
nullptr)
|
|
{
|
|
// Note this does all the things from ss_reset_to_default() in missionshipchoice.cpp except
|
|
// resetting UI elements - Mjn
|
|
|
|
SCP_UNUSED(L); // unused parameter
|
|
|
|
ss_init_pool(&Team_data[Common_team]);
|
|
ss_init_units();
|
|
|
|
if (!(Game_mode & GM_MULTIPLAYER)) {
|
|
wl_fill_slots();
|
|
}
|
|
|
|
return ADE_RETURN_NIL;
|
|
}
|
|
|
|
ADE_LIB_DERIV(l_Loadout_Wings, "Loadout_Wings", nullptr, nullptr, l_UserInterface_ShipWepSelect);
|
|
ADE_INDEXER(l_Loadout_Wings,
|
|
"number Index",
|
|
"Array of loadout wing data",
|
|
"loadout_wing",
|
|
"loadout handle, or invalid handle if index is invalid")
|
|
{
|
|
int idx;
|
|
if (!ade_get_args(L, "*i", &idx))
|
|
return ade_set_error(L, "o", l_Loadout_Wing.Set(ss_wing_info_h()));
|
|
idx--; //Convert to Lua's 1 based index system
|
|
return ade_set_args(L, "o", l_Loadout_Wing.Set(ss_wing_info_h(idx)));
|
|
}
|
|
|
|
ADE_FUNC(__len, l_Loadout_Wings, nullptr, "The number of loadout wings", "number", "The number of loadout wings.")
|
|
{
|
|
int count = 0;
|
|
|
|
for (int i = 0; i < MAX_STARTING_WINGS; i++) {
|
|
if (Ss_wings[i].ss_slots[0].in_mission)
|
|
count++;
|
|
};
|
|
|
|
return ade_set_args(L, "i", count);
|
|
}
|
|
|
|
ADE_LIB_DERIV(l_Loadout_Ships, "Loadout_Ships", nullptr, nullptr, l_UserInterface_ShipWepSelect);
|
|
ADE_INDEXER(l_Loadout_Ships,
|
|
"number Index",
|
|
"Array of loadout ship data. Slots are 1-12 where 1-4 is wing 1, 5-8 is wing 2, 9-12 is wing 3. "
|
|
"This is the array that is used to actually build the mission loadout on Commit.",
|
|
"loadout_ship",
|
|
"loadout handle, or nil if index is invalid")
|
|
{
|
|
int idx;
|
|
if (!ade_get_args(L, "*i", &idx))
|
|
return ADE_RETURN_NIL;
|
|
idx--; // Convert to Lua's 1 based index system
|
|
return ade_set_args(L, "o", l_Loadout_Ship.Set(idx));
|
|
}
|
|
|
|
ADE_FUNC(__len, l_Loadout_Ships, nullptr, "The number of loadout ships", "number", "The number of loadout ships.")
|
|
{
|
|
return ade_set_args(L, "i", MAX_WING_BLOCKS*MAX_WING_SLOTS);
|
|
}
|
|
|
|
//**********SUBLIBRARY: UserInterface/TechRoom
|
|
ADE_LIB_DERIV(l_UserInterface_TechRoom,
|
|
"TechRoom",
|
|
nullptr,
|
|
"API for accessing data related to the tech room UI.<br><b>Warning:</b> This is an internal "
|
|
"API for the new UI system. This should not be used by other code and may be removed in the future!",
|
|
l_UserInterface);
|
|
|
|
ADE_FUNC(buildMissionList,
|
|
l_UserInterface_TechRoom,
|
|
nullptr,
|
|
"Builds the mission list for display. Must be called before the sim_mission handle will have data",
|
|
"number",
|
|
"Returns 1 when completed")
|
|
{
|
|
Sim_Missions.clear();
|
|
Sim_CMissions.clear();
|
|
|
|
api_sim_room_build_mission_list(true);
|
|
|
|
mprintf(("Building mission lists for scripting API is complete!\n"));
|
|
|
|
return ade_set_args(L, "i", 1);
|
|
}
|
|
|
|
ADE_FUNC(buildCredits,
|
|
l_UserInterface_TechRoom,
|
|
nullptr,
|
|
"Builds the credits for display. Must be called before the credits_info handle will have data",
|
|
"number",
|
|
"Returns 1 when completed")
|
|
{
|
|
credits_parse();
|
|
credits_scp_position();
|
|
|
|
size_t count = Credit_text_parts.size();
|
|
|
|
for (size_t i = 0; i < count; i++) {
|
|
credits_complete.append(Credit_text_parts[i]);
|
|
}
|
|
|
|
//Make sure we clean up after ourselves
|
|
Credit_text_parts.clear();
|
|
|
|
mprintf(("Building credits for scripting API is complete!\n"));
|
|
|
|
return ade_set_args(L, "i", 1);
|
|
}
|
|
|
|
ADE_LIB_DERIV(l_UserInterface_SingleMissions, "SingleMissions", nullptr, nullptr, l_UserInterface_TechRoom);
|
|
ADE_INDEXER(l_UserInterface_SingleMissions, "number Index", "Array of simulator missions", "sim_mission", "Mission handle, or invalid handle if index is invalid")
|
|
{
|
|
int idx;
|
|
if (!ade_get_args(L, "*i", &idx))
|
|
return ade_set_error(L, "s", "");
|
|
|
|
return ade_set_args(L, "o", l_TechRoomMission.Set(sim_mission_h(idx, false)));
|
|
}
|
|
|
|
ADE_FUNC(__len, l_UserInterface_SingleMissions, nullptr, "The number of single missions", "number", "The number of single missions")
|
|
{
|
|
return ade_set_args(L, "i", Sim_Missions.size());
|
|
}
|
|
|
|
ADE_LIB_DERIV(l_UserInterface_CampaignMissions, "CampaignMissions", nullptr, nullptr, l_UserInterface_TechRoom);
|
|
ADE_INDEXER(l_UserInterface_CampaignMissions, "number Index", "Array of campaign missions", "sim_mission", "Mission handle, or invalid handle if index is invalid")
|
|
{
|
|
int idx;
|
|
if (!ade_get_args(L, "*i", &idx))
|
|
return ade_set_error(L, "s", "");
|
|
|
|
return ade_set_args(L, "o", l_TechRoomMission.Set(sim_mission_h(idx, true)));
|
|
}
|
|
|
|
ADE_FUNC(__len, l_UserInterface_CampaignMissions, nullptr, "The number of campaign missions", "number", "The number of campaign missions")
|
|
{
|
|
return ade_set_args(L, "i", Sim_CMissions.size());
|
|
}
|
|
|
|
ADE_LIB_DERIV(l_UserInterface_Cutscenes, "Cutscenes", nullptr, nullptr, l_UserInterface_TechRoom);
|
|
ADE_INDEXER(l_UserInterface_Cutscenes,
|
|
"number Index",
|
|
"Array of cutscenes",
|
|
"custscene_info",
|
|
"Cutscene handle, or invalid handle if index is invalid")
|
|
{
|
|
int idx;
|
|
if (!ade_get_args(L, "*i", &idx))
|
|
return ade_set_error(L, "s", "");
|
|
|
|
return ade_set_args(L, "o", l_TechRoomCutscene.Set(cutscene_info_h(idx)));
|
|
}
|
|
|
|
ADE_FUNC(__len, l_UserInterface_Cutscenes, nullptr, "The number of cutscenes", "number", "The number of cutscenes")
|
|
{
|
|
return ade_set_args(L, "i", Cutscenes.size());
|
|
}
|
|
|
|
ADE_LIB_DERIV(l_UserInterface_Credits, "Credits", nullptr, nullptr, l_UserInterface_TechRoom);
|
|
ADE_VIRTVAR(Music, l_UserInterface_Credits, nullptr, "The credits music filename", "string", "The music filename")
|
|
{
|
|
if (ADE_SETTING_VAR) {
|
|
LuaError(L, "This property is read only.");
|
|
}
|
|
|
|
return ade_set_args(L, "s", credits_get_music_filename(Credits_music_name));
|
|
}
|
|
|
|
ADE_VIRTVAR(NumImages, l_UserInterface_Credits, nullptr, "The total number of credits images", "number", "The number of images")
|
|
{
|
|
if (ADE_SETTING_VAR) {
|
|
LuaError(L, "This property is read only.");
|
|
}
|
|
|
|
return ade_set_args(L, "i", Credits_num_images);
|
|
}
|
|
|
|
ADE_VIRTVAR(StartIndex, l_UserInterface_Credits, nullptr, "The image index to begin with", "number", "The index")
|
|
{
|
|
if (ADE_SETTING_VAR) {
|
|
LuaError(L, "This property is read only.");
|
|
}
|
|
|
|
return ade_set_args(L, "i", Credits_artwork_index);
|
|
}
|
|
|
|
ADE_VIRTVAR(DisplayTime, l_UserInterface_Credits, nullptr, "The display time for each image", "number", "The display time")
|
|
{
|
|
if (ADE_SETTING_VAR) {
|
|
LuaError(L, "This property is read only.");
|
|
}
|
|
|
|
return ade_set_args(L, "f", Credits_artwork_display_time);
|
|
}
|
|
|
|
ADE_VIRTVAR(FadeTime, l_UserInterface_Credits, nullptr, "The crossfade time for each image", "number", "The fade time")
|
|
{
|
|
if (ADE_SETTING_VAR) {
|
|
LuaError(L, "This property is read only.");
|
|
}
|
|
|
|
return ade_set_args(L, "f", Credits_artwork_fade_time);
|
|
}
|
|
|
|
ADE_VIRTVAR(ScrollRate, l_UserInterface_Credits, nullptr, "The scroll rate of the text", "number", "The scroll rate")
|
|
{
|
|
if (ADE_SETTING_VAR) {
|
|
LuaError(L, "This property is read only.");
|
|
}
|
|
|
|
return ade_set_args(L, "f", Credits_scroll_rate);
|
|
}
|
|
|
|
ADE_VIRTVAR(Complete, l_UserInterface_Credits, nullptr, "The complete credits string", "string", "The credits")
|
|
{
|
|
if (ADE_SETTING_VAR) {
|
|
LuaError(L, "This property is read only.");
|
|
}
|
|
|
|
return ade_set_args(L, "s", credits_complete);
|
|
}
|
|
|
|
} // namespace api
|
|
} // namespace scripting
|