Add [automaticmode] Load File button to console lobby
options.ini [automaticmode] section: automaticmode=1 automaticfile=c:\path\to\config.ini Right-click was considered then dropped in favor of a dedicated button at 467,510 (below Pick Cond., left of Reprint). C++ (MW4Shell.cpp): - SAutoFileSlot struct + g_aAutoSlots[16], g_bAutomaticMode, g_szAutomaticFile globals - [automaticmode] ini read at StartUp - CTCL_LoadAutoFile: checks file exists, reads [mission] page into existing g_nRookieXxx globals + [slot0]..[slot15] pages into g_aAutoSlots[]; returns 1 if loaded - CTCL_GetAutoSlotName(out_str, k): pilot name for slot k - CTCL_GetAutoSlotMech(out_str, k): mech display name for slot k - CTCL_GetAutoSlotInt(k, field): Type/Team/Skin/Decal for slot k (fields 0-3) - Register/unregister all 4 callbacks in StartUp/ShutDown Script (ConLobby.script): - o_load_file button at 467, 510 - Handler: CTCL_LoadAutoFile -> if loaded, sends MAIL_SET_ROOKIE_MISSION to ConLobbyMission (game options), clears all slots, then applies per-slot data in a loop (pilot names, mech by display-name lookup in allowed_mechs[], team, skin, decal). USE_ALLOWED_MECHS/non-ALLOWED_MECHS both handled via #if. File not consumed (stays on disk); external app overwrites for next load. Rebuild required: MW4.exe (Release + Profile).
This commit is contained in:
@@ -132,6 +132,10 @@ extern SCRIPTCALLBACK(CTCL_GetMissionState);
|
||||
extern SCRIPTCALLBACK(CTCL_DoBreak);
|
||||
extern SCRIPTCALLBACK(CTCL_IsGameLoaded);
|
||||
extern SCRIPTCALLBACK(CTCL_DoReprint);
|
||||
extern SCRIPTCALLBACK(CTCL_LoadAutoFile);
|
||||
extern SCRIPTCALLBACK(CTCL_GetAutoSlotName);
|
||||
extern SCRIPTCALLBACK(CTCL_GetAutoSlotMech);
|
||||
extern SCRIPTCALLBACK(CTCL_GetAutoSlotInt);
|
||||
extern SCRIPTCALLBACK(CTCL_CheckPlayMovie);
|
||||
extern SCRIPTCALLBACK(CTCL_CheckCoinCounts);
|
||||
extern SCRIPTCALLBACK(CTCL_CheckUseJPD);
|
||||
@@ -174,6 +178,19 @@ int g_nRookieUnlimitedAmmo = 1; // 1=on (be cautious)
|
||||
int g_nRookieWeaponJam = 0;
|
||||
int g_nRookieAdvanceMode = 0;
|
||||
int g_nRookieArmorMode = 0;
|
||||
// [automaticmode] options.ini ? Load File button
|
||||
struct SAutoFileSlot {
|
||||
char szName[64]; // pilot name
|
||||
char szMech[64]; // mech display name (matched against mech[] array)
|
||||
int nType; // 0=empty, 1=player, 2-9=bot difficulty level
|
||||
int nTeam;
|
||||
int nSkin;
|
||||
int nDecal;
|
||||
};
|
||||
static SAutoFileSlot g_aAutoSlots[16];
|
||||
static int g_nAutoSlotsCount = 0;
|
||||
static int g_bAutomaticMode = 0;
|
||||
static char g_szAutomaticFile[MAX_PATH] = "";
|
||||
// MSL 5.06
|
||||
int g_nMechVariant = 0;
|
||||
int g_nMechLabOp = 0;
|
||||
@@ -758,6 +775,21 @@ void MW4Shell::StartUp()
|
||||
gosScript_RegisterVariable("g_nRookieWeaponJam", &g_nRookieWeaponJam, GOSVAR_INT, 0, NULL);
|
||||
gosScript_RegisterVariable("g_nRookieAdvanceMode", &g_nRookieAdvanceMode, GOSVAR_INT, 0, NULL);
|
||||
gosScript_RegisterVariable("g_nRookieArmorMode", &g_nRookieArmorMode, GOSVAR_INT, 0, NULL);
|
||||
// [automaticmode] callbacks
|
||||
gosScript_RegisterCallback("CTCL_LoadAutoFile", &CTCL_LoadAutoFile, GOSVAR_INT, 0, NULL);
|
||||
gosScript_RegisterCallback("CTCL_GetAutoSlotName", &CTCL_GetAutoSlotName, GOSVAR_INT, 0, NULL);
|
||||
gosScript_RegisterCallback("CTCL_GetAutoSlotMech", &CTCL_GetAutoSlotMech, GOSVAR_INT, 0, NULL);
|
||||
gosScript_RegisterCallback("CTCL_GetAutoSlotInt", &CTCL_GetAutoSlotInt, GOSVAR_INT, 0, NULL);
|
||||
{
|
||||
NotationFile opts("options.ini", NotationFile::Standard, true);
|
||||
Page *pAuto = opts.FindPage("automaticmode");
|
||||
if (pAuto) {
|
||||
pAuto->GetEntry("automaticmode", &g_bAutomaticMode);
|
||||
const char *sz = NULL;
|
||||
if (pAuto->GetEntry("automaticfile", &sz) && sz)
|
||||
strncpy(g_szAutomaticFile, sz, sizeof(g_szAutomaticFile)-1);
|
||||
}
|
||||
}
|
||||
// MSL 5.06
|
||||
gosScript_RegisterVariable("g_nMechVariant", &g_nMechVariant, GOSVAR_INT, 0, NULL);
|
||||
gosScript_RegisterVariable("g_nMechLabOp", &g_nMechLabOp, GOSVAR_INT, 0, NULL);
|
||||
@@ -1154,6 +1186,11 @@ void MW4Shell::ShutDown()
|
||||
gosScript_UnregisterVariable("g_nRookieWeaponJam");
|
||||
gosScript_UnregisterVariable("g_nRookieAdvanceMode");
|
||||
gosScript_UnregisterVariable("g_nRookieArmorMode");
|
||||
// [automaticmode] callbacks
|
||||
gosScript_UnregisterCallback("CTCL_GetAutoSlotInt");
|
||||
gosScript_UnregisterCallback("CTCL_GetAutoSlotMech");
|
||||
gosScript_UnregisterCallback("CTCL_GetAutoSlotName");
|
||||
gosScript_UnregisterCallback("CTCL_LoadAutoFile");
|
||||
// MSL 5.06
|
||||
gosScript_UnregisterVariable("g_nBlackMech");
|
||||
gosScript_UnregisterVariable("g_nMechVariant");
|
||||
@@ -12809,6 +12846,104 @@ int __stdcall CTCL_SetCDSP(void* instance, int args, void* data[])
|
||||
return 0;
|
||||
}
|
||||
|
||||
// [automaticmode] Load File button ? reads automatic file into Rookie Mission globals + per-slot data.
|
||||
// Returns 1 if the file was found and loaded, 0 otherwise. File is NOT consumed (stays on disk).
|
||||
int __stdcall CTCL_LoadAutoFile(void* instance, int args, void* data[])
|
||||
{
|
||||
if (!g_bAutomaticMode || !g_szAutomaticFile[0])
|
||||
return 0;
|
||||
if (GetFileAttributes(g_szAutomaticFile) == 0xFFFFFFFF)
|
||||
return 0;
|
||||
|
||||
NotationFile autofile(g_szAutomaticFile, NotationFile::Standard, true);
|
||||
|
||||
// Game options ? overwrite Rookie Mission globals so the existing
|
||||
// MAIL_SET_ROOKIE_MISSION script flow picks them up automatically.
|
||||
Page *pMission = autofile.FindPage("mission");
|
||||
if (pMission) {
|
||||
const char *sz = NULL;
|
||||
if (pMission->GetEntry("MissionName", &sz) && sz) {
|
||||
strncpy(g_szRookieMission, sz, sizeof(g_szRookieMission)-1);
|
||||
g_szRookieMission[sizeof(g_szRookieMission)-1] = '\0';
|
||||
}
|
||||
pMission->GetEntry("GameType", &g_nRookieGameType);
|
||||
pMission->GetEntry("Visibility", &g_nRookieVisibility);
|
||||
pMission->GetEntry("Weather", &g_nRookieWeather);
|
||||
pMission->GetEntry("TimeOfDay", &g_nRookieTimeOfDay);
|
||||
pMission->GetEntry("TimeLimit", &g_nRookieTimeLimit);
|
||||
pMission->GetEntry("Radar", &g_nRookieRadar);
|
||||
pMission->GetEntry("HeatOn", &g_nRookieHeat);
|
||||
pMission->GetEntry("FriendlyFire", &g_nRookieFriendlyFire);
|
||||
pMission->GetEntry("SplashDamage", &g_nRookieSplash);
|
||||
pMission->GetEntry("UnlimitedAmmo", &g_nRookieUnlimitedAmmo);
|
||||
pMission->GetEntry("WeaponJam", &g_nRookieWeaponJam);
|
||||
pMission->GetEntry("AdvanceMode", &g_nRookieAdvanceMode);
|
||||
pMission->GetEntry("ArmorMode", &g_nRookieArmorMode);
|
||||
}
|
||||
|
||||
// Per-slot data (up to 16 slots via [slot0]..[slot15] pages)
|
||||
g_nAutoSlotsCount = 0;
|
||||
memset(g_aAutoSlots, 0, sizeof(g_aAutoSlots));
|
||||
char szPageName[16];
|
||||
for (int i = 0; i < 16; i++) {
|
||||
sprintf(szPageName, "slot%d", i);
|
||||
Page *pSlot = autofile.FindPage(szPageName);
|
||||
if (!pSlot) break;
|
||||
g_nAutoSlotsCount = i + 1;
|
||||
const char *sz = NULL;
|
||||
if (pSlot->GetEntry("PilotName", &sz) && sz)
|
||||
strncpy(g_aAutoSlots[i].szName, sz, sizeof(g_aAutoSlots[i].szName)-1);
|
||||
sz = NULL;
|
||||
if (pSlot->GetEntry("Mech", &sz) && sz)
|
||||
strncpy(g_aAutoSlots[i].szMech, sz, sizeof(g_aAutoSlots[i].szMech)-1);
|
||||
pSlot->GetEntry("Type", &g_aAutoSlots[i].nType);
|
||||
pSlot->GetEntry("Team", &g_aAutoSlots[i].nTeam);
|
||||
pSlot->GetEntry("Skin", &g_aAutoSlots[i].nSkin);
|
||||
pSlot->GetEntry("Decal", &g_aAutoSlots[i].nDecal);
|
||||
}
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
// Returns pilot name string for slot k ? data[0]=string output buffer, data[1]=int k
|
||||
int __stdcall CTCL_GetAutoSlotName(void* instance, int args, void* data[])
|
||||
{
|
||||
int k = INTPARM(1);
|
||||
const char *sz = (k >= 0 && k < 16) ? g_aAutoSlots[k].szName : "";
|
||||
if (STRPARM(0)) gos_Free(STRPARM(0));
|
||||
STRPARM(0) = (char *)gos_Malloc(64);
|
||||
strncpy(STRPARM(0), sz, 63);
|
||||
STRPARM(0)[63] = '\0';
|
||||
return 1;
|
||||
}
|
||||
|
||||
// Returns mech display name for slot k ? data[0]=string output buffer, data[1]=int k
|
||||
int __stdcall CTCL_GetAutoSlotMech(void* instance, int args, void* data[])
|
||||
{
|
||||
int k = INTPARM(1);
|
||||
const char *sz = (k >= 0 && k < 16) ? g_aAutoSlots[k].szMech : "";
|
||||
if (STRPARM(0)) gos_Free(STRPARM(0));
|
||||
STRPARM(0) = (char *)gos_Malloc(64);
|
||||
strncpy(STRPARM(0), sz, 63);
|
||||
STRPARM(0)[63] = '\0';
|
||||
return 1;
|
||||
}
|
||||
|
||||
// Returns int field for slot k ? data[0]=int k, data[1]=int field (0=Type 1=Team 2=Skin 3=Decal)
|
||||
int __stdcall CTCL_GetAutoSlotInt(void* instance, int args, void* data[])
|
||||
{
|
||||
int k = INTPARM(0);
|
||||
int field = INTPARM(1);
|
||||
if (k < 0 || k >= 16) return 0;
|
||||
switch (field) {
|
||||
case 0: return g_aAutoSlots[k].nType;
|
||||
case 1: return g_aAutoSlots[k].nTeam;
|
||||
case 2: return g_aAutoSlots[k].nSkin;
|
||||
case 3: return g_aAutoSlots[k].nDecal;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
void CTCL_API CTCL_InitMechDatas()
|
||||
{
|
||||
//CTCL_ClearMechDatas();
|
||||
|
||||
@@ -1229,6 +1229,16 @@ main
|
||||
o_all_random_mech.state = 0 // initially enabled
|
||||
initialize(o_all_random_mech)
|
||||
|
||||
// [automaticmode] Load File button -- below Pick Cond., left of Reprint
|
||||
object o_load_file = s_multistatepane
|
||||
o_load_file.total_states = 3
|
||||
o_load_file.textsize = 1
|
||||
o_load_file.text = "Load File"
|
||||
o_load_file.file = WPATH "button_reg_138x23m_3state.tga"
|
||||
o_load_file.location = 467, 510, o_frame.location.z + 1
|
||||
o_load_file.state = 0 // initially enabled
|
||||
initialize(o_load_file)
|
||||
|
||||
// MSL Added default settings button
|
||||
object o_default = s_multistatepane
|
||||
o_default.total_states = 3
|
||||
@@ -1664,6 +1674,94 @@ main
|
||||
mail(MAIL_RESET_AFTER_LAUNCH, this) // reset
|
||||
return
|
||||
}
|
||||
// [automaticmode] Load File button handler
|
||||
if (sender == o_load_file)
|
||||
{
|
||||
play press, 1
|
||||
if callback($$CTCL_LoadAutoFile$$)
|
||||
{
|
||||
// Apply mission + game options via existing Rookie Mission flow
|
||||
mail(MAIL_SET_ROOKIE_MISSION, @ConLobbyMission@)
|
||||
// Clear all slots
|
||||
o_cam_list.nselected = 0
|
||||
for (k = 0; k < nRosterCount; k++)
|
||||
{
|
||||
if (1 <= o_BotList[k].nselected)
|
||||
{
|
||||
if (o_BotList[k].nselected == 1) && (k < MAXTESLA_P)
|
||||
{
|
||||
o_Editbox[k].boxValue = ""
|
||||
initialize(o_Editbox[k])
|
||||
deactivate(o_Editbox[k])
|
||||
}
|
||||
o_BotList[k].nselected = 0
|
||||
m_naLastSelected[k] = 0
|
||||
if (ROSTER_top_of_list <= k) && (k < ROSTER_top_of_list + ROSTER_DISPLAY_COUNT)
|
||||
mail(MAIL_PLAYER_TYPE_CHANGED, k, this)
|
||||
}
|
||||
}
|
||||
// Apply per-slot data from file
|
||||
string szAutoName
|
||||
string szAutoMech
|
||||
int nAutoType
|
||||
int j
|
||||
for (k = 0; k < nRosterCount; k++)
|
||||
{
|
||||
nAutoType = callback($$CTCL_GetAutoSlotInt$$, k, 0)
|
||||
if nAutoType > 0
|
||||
{
|
||||
o_BotList[k].nselected = nAutoType
|
||||
m_naLastSelected[k] = nAutoType
|
||||
if (o_BotList[k].nselected > 0)
|
||||
activate(o_BotList[k])
|
||||
if (nAutoType == 1) && (k < MAXTESLA_P)
|
||||
{
|
||||
callback($$CTCL_GetAutoSlotName$$, szAutoName, k)
|
||||
o_Editbox[k].boxValue = szAutoName
|
||||
initialize(o_Editbox[k])
|
||||
activate(o_Editbox[k])
|
||||
}
|
||||
callback($$CTCL_GetAutoSlotMech$$, szAutoMech, k)
|
||||
if (!equal$(szAutoMech, ""))
|
||||
{
|
||||
#if USE_ALLOWED_MECHS
|
||||
for (j = 0; j < MAX_ALLOWED_MECHS; j++)
|
||||
{
|
||||
if equal$(mech[allowed_mechs[j]], szAutoMech)
|
||||
{
|
||||
o_mech_variant[k].nselected = j
|
||||
break
|
||||
}
|
||||
}
|
||||
#else
|
||||
for (j = 0; j < $$m_mechCount$$; j++)
|
||||
{
|
||||
if equal$(mech[j], szAutoMech)
|
||||
{
|
||||
o_mech_variant[k].nselected = j
|
||||
break
|
||||
}
|
||||
}
|
||||
#endif
|
||||
}
|
||||
if cur_team_val > 0
|
||||
o_team[k].nselected = callback($$CTCL_GetAutoSlotInt$$, k, 1)
|
||||
else
|
||||
o_skins[k].nselected = callback($$CTCL_GetAutoSlotInt$$, k, 2)
|
||||
o_decal[k].nselected = callback($$CTCL_GetAutoSlotInt$$, k, 3)
|
||||
initialize(o_mech_variant[k])
|
||||
if (ROSTER_top_of_list <= k) && (k < ROSTER_top_of_list + ROSTER_DISPLAY_COUNT)
|
||||
{
|
||||
activate(o_mech_variant[k])
|
||||
mail(MAIL_PLAYER_TYPE_CHANGED, k, this)
|
||||
}
|
||||
else
|
||||
deactivate(o_mech_variant[k])
|
||||
}
|
||||
}
|
||||
}
|
||||
return
|
||||
}
|
||||
if (sender == o_reprint)
|
||||
{
|
||||
play press,1
|
||||
|
||||
Reference in New Issue
Block a user