[Research] Scripted heroes in instant action playlists

In this forum you will find and post information regarding the modding of Star Wars Battlefront 2. DO NOT POST MOD IDEAS/REQUESTS.

Moderator: Moderators

Post Reply
Sporadia
Corporal
Corporal
Posts: 151
Joined: Thu Jan 24, 2019 11:02 pm
Projects :: No Mod project currently
Games I'm Playing :: None
xbox live or psn: No gamertag set

[Research] Scripted heroes in instant action playlists

Post by Sporadia »

I've gotten side tracked from the issue I had in this thread here. I've started to think that instant action playlists aren't designed to handle missions which contain the lua command EnableSPScriptedHeroes(). And potentially there are other bits of lua from campaign scripts which also aren't supposed to be used in instant action. I don't want this topic to take over my first thread (which is supposed to be about getting a user script to work) so now I'm making a new one just to cover how lua affects instant action playlists.

So here's what I'm talking about: When you play a mission in instant action which contains the lua EnableSPScriptedHeroes(), every other mission you play after that, in the same playlist, will also act as if you've enabled scripted heroes. (Or at least, something similar is happening). So for most conquest or capture the flag missions, they'll suddenly lose the prompt for players to play as heroes because those missions aren't supposed to have scripted heroes; they're supposed to unlock heroes with the instant action settings. But this only occurs after you play a mission which uses scripted heroes in the same playlist. I've seen this happening a few times but now I've done an actual test.

Test 1: A stock mission with EnableSPHeroRules() added to ScriptPostLoad()
To test the effects of EnableSPScriptedHeroes(), the first thing I did was make a new mod (called SPE). For the whole test, Zerted's patch and SPE were the only mods on my game. After making SPE, I added a copy of Death Star conquest in GCW era. Then I added the line EnableSPScriptedHeroes() to the ScriptPostLoad() function of this mission's lua. So this is the mission lua I ran:
Hidden/Spoiler:
[code]
--
-- Copyright (c) 2005 Pandemic Studios, LLC. All rights reserved.
--

-- load the gametype script
ScriptCB_DoFile("ObjectiveConquest")
ScriptCB_DoFile("setup_teams")
---------------------------------------------------------------------------
-- FUNCTION: ScriptInit
-- PURPOSE: This function is only run once
-- INPUT:
-- OUTPUT:
-- NOTES: The name, 'ScriptInit' is a chosen convention, and each
-- mission script must contain a version of this function, as
-- it is called from C to start the mission.
---------------------------------------------------------------------------


function ScriptPostLoad()
EnableSPScriptedHeroes()

TrashStuff();
PlayAnimExtend();
PlayAnimTakExtend();

BlockPlanningGraphArcs("compactor")
OnObjectKillName(CompactorConnectionOn, "grate01")

DisableBarriers("start_room_barrier")
DisableBarriers("dr_left")
DisableBarriers("circle_bar1")
DisableBarriers("circle_bar2")

-- handle reinforcment loss and defeat condition
OnCharacterDeathTeam(function(character, killer) AddReinforcements(1, -1) end, 1)
OnTicketCountChange(function(team, count) if count == 0 then MissionDefeat(team) end end)

OnObjectRespawnName(PlayAnimExtend, "Panel-Chasm");
OnObjectKillName(PlayAnimRetract, "Panel-Chasm");

OnObjectRespawnName(PlayAnimTakExtend, "Panel-Tak");
OnObjectKillName(PlayAnimTakRetract, "Panel-Tak");

EnableSPHeroRules()
KillObject("CP6")
cp1 = CommandPost:New{name = "CP1"}
cp2 = CommandPost:New{name = "CP2"}
cp3 = CommandPost:New{name = "CP3"}
cp4 = CommandPost:New{name = "CP4"}
cp5 = CommandPost:New{name = "CP5"}
--cp6 = CommandPost:New{name = "CP6"}
cp7 = CommandPost:New{name = "CP7"}

--This sets up the actual objective. This needs to happen after cp's are defined
conquest = ObjectiveConquest:New{teamATT = ATT, teamDEF = DEF, textATT = "game.modes.con", textDEF = "game.modes.con2", multiplayerRules = true}

--This adds the CPs to the objective. This needs to happen after the objective is set up
conquest:AddCommandPost(cp1)
conquest:AddCommandPost(cp2)
conquest:AddCommandPost(cp3)
conquest:AddCommandPost(cp4)
conquest:AddCommandPost(cp5)
--conquest:AddCommandPost(cp6)
conquest:AddCommandPost(cp7)

conquest:Start()

AddDeathRegion("DeathRegion01")
AddDeathRegion("DeathRegion02")
AddDeathRegion("DeathRegion03")
AddDeathRegion("DeathRegion04")
AddDeathRegion("DeathRegion05")

end

function CompactorConnectionOn()
UnblockPlanningGraphArcs ("compactor")
end
--START BRIDGEWORK!

-- OPEN
function PlayAnimExtend()
PauseAnimation("bridgeclose");
RewindAnimation("bridgeopen");
PlayAnimation("bridgeopen");

-- allow the AI to run across it
UnblockPlanningGraphArcs("Connection122");
DisableBarriers("BridgeBarrier");

end
-- CLOSE
function PlayAnimRetract()
PauseAnimation("bridgeopen");
RewindAnimation("bridgeclose");
PlayAnimation("bridgeclose");

-- prevent the AI from running across it
BlockPlanningGraphArcs("Connection122");
EnableBarriers("BridgeBarrier");

end

--START BRIDGEWORK TAK!!!

-- OPEN
function PlayAnimTakExtend()
PauseAnimation("TakBridgeOpen");
RewindAnimation("TakBridgeClose");
PlayAnimation("TakBridgeClose");

-- allow the AI to run across it
UnblockPlanningGraphArcs("Connection128");
DisableBarriers("Barrier222");

end
-- CLOSE
function PlayAnimTakRetract()
PauseAnimation("TakBridgeClose");
RewindAnimation("TakBridgeOpen");
PlayAnimation("TakBridgeOpen");

-- prevent the AI from running across it
BlockPlanningGraphArcs("Connection128");
EnableBarriers("Barrier222");

end

function TrashStuff()

trash_open = 1
trash_closed = 0

trash_timer = CreateTimer("trash_timer")
SetTimerValue(trash_timer, 7)
StartTimer(trash_timer)
trash_death = OnTimerElapse(
function(timer)
if trash_open == 1 then
AddDeathRegion("deathregion")
SetTimerValue(trash_timer, 5)
StartTimer(trash_timer)
trash_closed = 1
trash_open = 0
print("death region added")

elseif trash_closed == 1 then
RemoveRegion("deathregion")
SetTimerValue(trash_timer, 15)
StartTimer(trash_timer)
print("death region removed")
trash_closed = 0
trash_open = 1
end
end,
trash_timer
)
end




function ScriptInit()
-- Designers, these two lines *MUST* be first.
SetPS2ModelMemory(4000000)
ReadDataFile("ingame.lvl")

-- Empire Attacking (attacker is always #1)
local ALL = 1
local IMP = 2
-- These variables do not change
local ATT = 1
local DEF = 2

ReadDataFile("sound\\dea.lvl;dea1gcw")


SetMaxFlyHeight(72)
SetMaxPlayerFlyHeight (72)
AISnipeSuitabilityDist(30)

ReadDataFile("SIDE\\all.lvl",
"all_inf_rifleman_fleet",
"all_inf_rocketeer_fleet",
"all_inf_engineer_fleet",
"all_inf_sniper_fleet",
"all_inf_officer",
"all_hero_luke_jedi",
"all_inf_wookiee")
ReadDataFile("SIDE\\imp.lvl",
"imp_inf_rifleman",
"imp_inf_rocketeer",
"imp_inf_engineer",
"imp_inf_sniper",
"imp_inf_officer",
"imp_inf_dark_trooper")

ReadDataFile("SIDE\\imp.lvl",
"imp_hero_emperor")

SetupTeams{

all={
team = ALL,
units = 32,
reinforcements = 150,
soldier = {"all_inf_rifleman_fleet",7, 25},
assault = {"all_inf_rocketeer_fleet",1, 4},
engineer = {"all_inf_engineer_fleet",1, 4},
sniper = {"all_inf_sniper_fleet",1, 4},
officer = {"all_inf_officer",1, 4},
special = {"all_inf_wookiee",1, 4},

},

imp={
team = IMP,
units = 32,
reinforcements = 150,
soldier = {"imp_inf_rifleman",7, 25},
assault = {"imp_inf_rocketeer",1, 4},
engineer = {"imp_inf_engineer",1, 4},
sniper = {"imp_inf_sniper",1, 4},
officer = {"imp_inf_officer",1, 4},
special = {"imp_inf_dark_trooper",1, 4},


}
}

SetHeroClass(ALL, "all_hero_luke_jedi")
SetHeroClass(IMP, "imp_hero_emperor")

-- Level Stats
ClearWalkers()
-- AddWalkerType(0, 0) -- 8 droidekas (special case: 0 leg pairs)
-- AddWalkerType(1, 0) -- 8 droidekas (special case: 0 leg pairs)
-- AddWalkerType(2, 0) -- 2 spider walkers with 2 leg pairs each
-- AddWalkerType(3, 0) -- 2 attes with 3 leg pairs each
local weaponCnt = 200
SetMemoryPoolSize ("Aimer", 0)
SetMemoryPoolSize ("AmmoCounter", weaponCnt)
SetMemoryPoolSize ("BaseHint", 300)
SetMemoryPoolSize ("EnergyBar", weaponCnt)
SetMemoryPoolSize ("EntityCloth", 18)
SetMemoryPoolSize ("EntityLight", 100)
SetMemoryPoolSize ("EntitySoundStatic", 30)
SetMemoryPoolSize ("SoundSpaceRegion", 50)
SetMemoryPoolSize ("MountedTurret", 0)
SetMemoryPoolSize ("Navigator", 50)
SetMemoryPoolSize ("Obstacle", 260)
SetMemoryPoolSize ("PathFollower", 50)
SetMemoryPoolSize ("PathNode", 512)
SetMemoryPoolSize ("RedOmniLight", 130)
SetMemoryPoolSize ("ShieldEffect", 0)
SetMemoryPoolSize ("TreeGridStack", 200)
SetMemoryPoolSize ("UnitAgent", 50)
SetMemoryPoolSize ("UnitController", 50)
SetMemoryPoolSize ("Weapon", weaponCnt)
SetMemoryPoolSize ("EntityFlyer", 6)

-- Local Stats
--SetTeamName (3, "locals")
--AddUnitClass (3, "ewk_inf_trooper", 4)
--AddUnitClass (3, "ewk_inf_repair", 6)
--SetUnitCount (3, 14)
--SetTeamAsFriend(3,ATT)
--SetTeamAsEnemy(3,DEF)


SetSpawnDelay(10.0, 0.25)
ReadDataFile("dea\\dea1.lvl", "dea1_Conquest")
SetDenseEnvironment("true")

--SetStayInTurrets(1)


-- Movies
-- SetVictoryMovie(ALL, "all_end_victory")
-- SetDefeatMovie(ALL, "imp_end_victory")
-- SetVictoryMovie(IMP, "imp_end_victory")
-- SetDefeatMovie(IMP, "all_end_victory")

-- Sound

voiceSlow = OpenAudioStream("sound\\global.lvl", "all_unit_vo_slow")
AudioStreamAppendSegments("sound\\global.lvl", "imp_unit_vo_slow", voiceSlow)
AudioStreamAppendSegments("sound\\global.lvl", "global_vo_slow", voiceSlow)

voiceQuick = OpenAudioStream("sound\\global.lvl", "all_unit_vo_quick")
AudioStreamAppendSegments("sound\\global.lvl", "imp_unit_vo_quick", voiceQuick)

OpenAudioStream("sound\\global.lvl", "gcw_music")
-- OpenAudioStream("sound\\global.lvl", "global_vo_quick")
-- OpenAudioStream("sound\\global.lvl", "global_vo_slow")
OpenAudioStream("sound\\dea.lvl", "dea1")
OpenAudioStream("sound\\dea.lvl", "dea1")
-- OpenAudioStream("sound\\cor.lvl", "dea1gcw_emt")

SetBleedingVoiceOver(ALL, ALL, "all_off_com_report_us_overwhelmed", 1)
SetBleedingVoiceOver(ALL, IMP, "all_off_com_report_enemy_losing", 1)
SetBleedingVoiceOver(IMP, ALL, "imp_off_com_report_enemy_losing", 1)
SetBleedingVoiceOver(IMP, IMP, "imp_off_com_report_us_overwhelmed", 1)

SetLowReinforcementsVoiceOver(ALL, ALL, "all_off_defeat_im", .1, 1)
SetLowReinforcementsVoiceOver(ALL, IMP, "all_off_victory_im", .1, 1)
SetLowReinforcementsVoiceOver(IMP, IMP, "imp_off_defeat_im", .1, 1)
SetLowReinforcementsVoiceOver(IMP, ALL, "imp_off_victory_im", .1, 1)

SetOutOfBoundsVoiceOver(1, "allleaving")
SetOutOfBoundsVoiceOver(2, "impleaving")

SetAmbientMusic(ALL, 1.0, "all_dea_amb_start", 0,1)
SetAmbientMusic(ALL, 0.8, "all_dea_amb_middle", 1,1)
SetAmbientMusic(ALL, 0.2,"all_dea_amb_end", 2,1)
SetAmbientMusic(IMP, 1.0, "imp_dea_amb_start", 0,1)
SetAmbientMusic(IMP, 0.8, "imp_dea_amb_middle", 1,1)
SetAmbientMusic(IMP, 0.2,"imp_dea_amb_end", 2,1)

SetVictoryMusic(ALL, "all_dea_amb_victory")
SetDefeatMusic (ALL, "all_dea_amb_defeat")
SetVictoryMusic(IMP, "imp_dea_amb_victory")
SetDefeatMusic (IMP, "imp_dea_amb_defeat")

SetSoundEffect("ScopeDisplayZoomIn", "binocularzoomin")
SetSoundEffect("ScopeDisplayZoomOut", "binocularzoomout")
-- SetSoundEffect("BirdScatter", "birdsFlySeq1")
SetSoundEffect("SpawnDisplayUnitChange", "shell_select_unit")
SetSoundEffect("SpawnDisplayUnitAccept", "shell_menu_enter")
SetSoundEffect("SpawnDisplaySpawnPointChange", "shell_select_change")
SetSoundEffect("SpawnDisplaySpawnPointAccept", "shell_menu_enter")
SetSoundEffect("SpawnDisplayBack", "shell_menu_exit")


SetAttackingTeam(ATT)



AddCameraShot(-0.404895, 0.000992, -0.514360, -0.002240, -121.539894, 62.536297, -257.699493)
--Homestead
AddCameraShot(0.040922, -0.004049, -0.994299, -0.098381, -103.729523, 55.546598, -225.360893)
--Sarlac Pit
AddCameraShot(-1.0, 0.0, -0.514360, 0.0, -55.381485, 50.450953, -96.514324)
end
[/code]
For the sake of sharing everything, here is also the addme and mission.req which I used to apply this mission. No other changes were made to SPE:
Addme
Hidden/Spoiler:
[code]
-- first two functions by gametoast user [RDH]Zerted
-- recursively merges the second given table into the first given table
function MergeTables( mission, newFlags )
-- for each table entry,
local array = type({})
for key,value in pairs(newFlags) do
-- check for nested tables
if type(value) == array then
-- mission must have this key as a table too
if type(mission[key]) ~= array then
mission[key] = {}
end
-- merge these two tables recursively
MergeTables(mission[key], value)
else
-- the key is a simple variable, so simply store it
mission[key] = value
end
end
end

-- Search through the missionlist to find a map that matches mapName,
-- then insert the new flags into said entry.
-- Use this when you know the map already exists, but this content patch is just
-- adding new gamemodes (otherwise you should just add whole new entries to the missionlist)
function AddNewGameModes(missionList, mapName, newFlags)
for i, mission in missionList do
if mission.mapluafile == mapName then
MergeTables(mission, newFlags)
end
end
end




-- insert totally new maps here:
local sp_n = 0
local mp_n = 0
sp_n = table.getn(sp_missionselect_listbox_contents)

-- sp_missionselect_listbox_contents[sp_n+1] = { isModLevel = 1, mapluafile = "SPE%s_%s", era_g = 1, era_c = 1, mode_con_g = 1, mode_con_c = 1,}
-- mp_n = table.getn(mp_missionselect_listbox_contents)
-- mp_missionselect_listbox_contents[mp_n+1] = sp_missionselect_listbox_contents[sp_n+1]

-- add gamemodes here
AddNewGameModes(sp_missionselect_listbox_contents, "dea1%s_%s", {era_g = 1, mode_con_g = 1})

-- associate this mission name with the current downloadable content directory
-- (this tells the engine which maps are downloaded, so you need to include all new mission lua's here)
-- first arg: mapluafile from above
-- second arg: mission script name
-- third arg: level memory modifier. the arg to LuaScript.cpp: DEFAULT_MODEL_MEMORY_PLUS(x)

AddDownloadableContent("dea1", "dea1g_con", 4)
AddDownloadableContent("SPE","SPEg_con",4)
AddDownloadableContent("SPE","SPEc_con",4)

-- all done
newEntry = nil
n = nil

-- Now load our core.lvl into the shell to add our localize keys
ReadDataFile("..\\..\\addon\\SPE\\data\\_LVL_PC\\core.lvl")
[/code]
mission.req
Hidden/Spoiler:
[code]
ucft
{
REQN
{
"config"
"ingame_movies"
}

REQN
{
"script"
"setup_teams"
"gametype_conquest"
"gametype_capture"
"Objective"
"MultiObjectiveContainer"
"ObjectiveCTF"
"ObjectiveAssault"
"ObjectiveSpaceAssault"
"ObjectiveConquest"
"ObjectiveTDM"
"ObjectiveOneFlagCTF"
"SoundEvent_ctf"
"ObjectiveGoto"
"LinkedShields"
"LinkedDestroyables"
"LinkedTurrets"
"Ambush"
"PlayMovieWithTransition"
}

REQN
{
"lvl"
"dea1g_con"
}
}
[/code]
The next thing I did after that was a play test. I put the following playlist into instant action (using the actual game not the debug version):
  1. Mygeeto GCW Conquest
  2. Polis Massa GCW Conquest
  3. Death Star GCW Conquest (modified, with EnableSPScriptedHeroes() added)
  4. Tantive IV GCW Conquest
  5. Polis Massa GCW Conquest
  6. Dagobah GCW Conquest
I played through every single one to see what happened to the hero unlock prompt. I let the playlist cycle around to the Mygeeto mission again to see if it would reset or not. It might not have been necessary but I only played as the rebels each time, and only played as either a rebel soldier or the hero. The hero settings were kept as default. I added a 5 minute timer to conquest to try and get through it faster. This is what happened:
Hidden/Spoiler:
[list=1][*]Mygeeto: Heroes are unlockable
[*]Polis Massa: Heroes are unlockable
[*]Death Star: No prompt to play as heroes (correct behaviour of EnableSPScriptedHeroes())
[*]Tantive IV: No prompt to play as heroes
[*]Polis Massa: No prompt to play as heroes
[*]Dagobah: No prompt to play as heroes[/list]
[list=1][*]Mygeeto: No prompt to play as heroes[/list]

The number is each mission's position in the playlist.
This lines up with what I was expecting to see (and have experienced in the past) where the heroes stop working after the mission containing EnableSPScriptedHeroes(). It also shows that playlists don't reset when they cycle back around to the beginning again. I've used the same Polis Massa mission twice to show that it can go from working to non-working in a single run. I tried to mix the heroes up so if Luke was broken then Mygeeto would break first (not the Death Star), the two mission's either side of the Death Star both use Leia so she goes from working to non-working in a single run, and Dagobah's at the end because it has a unique hero and I wanted an indication for if they're all broken.

Test 2) The control test
In order to test this properly, I did second test run with no EnableSPScriptedHeroes() added to the Death Star conquest. I commented out the line, but kept the mission in SPE. This is the mission lua used for the control test:
Hidden/Spoiler:
[code]
--
-- Copyright (c) 2005 Pandemic Studios, LLC. All rights reserved.
--

-- load the gametype script
ScriptCB_DoFile("ObjectiveConquest")
ScriptCB_DoFile("setup_teams")
---------------------------------------------------------------------------
-- FUNCTION: ScriptInit
-- PURPOSE: This function is only run once
-- INPUT:
-- OUTPUT:
-- NOTES: The name, 'ScriptInit' is a chosen convention, and each
-- mission script must contain a version of this function, as
-- it is called from C to start the mission.
---------------------------------------------------------------------------


function ScriptPostLoad()
-- EnableSPScriptedHeroes()

TrashStuff();
PlayAnimExtend();
PlayAnimTakExtend();

BlockPlanningGraphArcs("compactor")
OnObjectKillName(CompactorConnectionOn, "grate01")

DisableBarriers("start_room_barrier")
DisableBarriers("dr_left")
DisableBarriers("circle_bar1")
DisableBarriers("circle_bar2")

-- handle reinforcment loss and defeat condition
OnCharacterDeathTeam(function(character, killer) AddReinforcements(1, -1) end, 1)
OnTicketCountChange(function(team, count) if count == 0 then MissionDefeat(team) end end)

OnObjectRespawnName(PlayAnimExtend, "Panel-Chasm");
OnObjectKillName(PlayAnimRetract, "Panel-Chasm");

OnObjectRespawnName(PlayAnimTakExtend, "Panel-Tak");
OnObjectKillName(PlayAnimTakRetract, "Panel-Tak");

EnableSPHeroRules()
KillObject("CP6")
cp1 = CommandPost:New{name = "CP1"}
cp2 = CommandPost:New{name = "CP2"}
cp3 = CommandPost:New{name = "CP3"}
cp4 = CommandPost:New{name = "CP4"}
cp5 = CommandPost:New{name = "CP5"}
--cp6 = CommandPost:New{name = "CP6"}
cp7 = CommandPost:New{name = "CP7"}

--This sets up the actual objective. This needs to happen after cp's are defined
conquest = ObjectiveConquest:New{teamATT = ATT, teamDEF = DEF, textATT = "game.modes.con", textDEF = "game.modes.con2", multiplayerRules = true}

--This adds the CPs to the objective. This needs to happen after the objective is set up
conquest:AddCommandPost(cp1)
conquest:AddCommandPost(cp2)
conquest:AddCommandPost(cp3)
conquest:AddCommandPost(cp4)
conquest:AddCommandPost(cp5)
--conquest:AddCommandPost(cp6)
conquest:AddCommandPost(cp7)

conquest:Start()

AddDeathRegion("DeathRegion01")
AddDeathRegion("DeathRegion02")
AddDeathRegion("DeathRegion03")
AddDeathRegion("DeathRegion04")
AddDeathRegion("DeathRegion05")

end

function CompactorConnectionOn()
UnblockPlanningGraphArcs ("compactor")
end
--START BRIDGEWORK!

-- OPEN
function PlayAnimExtend()
PauseAnimation("bridgeclose");
RewindAnimation("bridgeopen");
PlayAnimation("bridgeopen");

-- allow the AI to run across it
UnblockPlanningGraphArcs("Connection122");
DisableBarriers("BridgeBarrier");

end
-- CLOSE
function PlayAnimRetract()
PauseAnimation("bridgeopen");
RewindAnimation("bridgeclose");
PlayAnimation("bridgeclose");

-- prevent the AI from running across it
BlockPlanningGraphArcs("Connection122");
EnableBarriers("BridgeBarrier");

end

--START BRIDGEWORK TAK!!!

-- OPEN
function PlayAnimTakExtend()
PauseAnimation("TakBridgeOpen");
RewindAnimation("TakBridgeClose");
PlayAnimation("TakBridgeClose");

-- allow the AI to run across it
UnblockPlanningGraphArcs("Connection128");
DisableBarriers("Barrier222");

end
-- CLOSE
function PlayAnimTakRetract()
PauseAnimation("TakBridgeClose");
RewindAnimation("TakBridgeOpen");
PlayAnimation("TakBridgeOpen");

-- prevent the AI from running across it
BlockPlanningGraphArcs("Connection128");
EnableBarriers("Barrier222");

end

function TrashStuff()

trash_open = 1
trash_closed = 0

trash_timer = CreateTimer("trash_timer")
SetTimerValue(trash_timer, 7)
StartTimer(trash_timer)
trash_death = OnTimerElapse(
function(timer)
if trash_open == 1 then
AddDeathRegion("deathregion")
SetTimerValue(trash_timer, 5)
StartTimer(trash_timer)
trash_closed = 1
trash_open = 0
print("death region added")

elseif trash_closed == 1 then
RemoveRegion("deathregion")
SetTimerValue(trash_timer, 15)
StartTimer(trash_timer)
print("death region removed")
trash_closed = 0
trash_open = 1
end
end,
trash_timer
)
end




function ScriptInit()
-- Designers, these two lines *MUST* be first.
SetPS2ModelMemory(4000000)
ReadDataFile("ingame.lvl")

-- Empire Attacking (attacker is always #1)
local ALL = 1
local IMP = 2
-- These variables do not change
local ATT = 1
local DEF = 2

ReadDataFile("sound\\dea.lvl;dea1gcw")


SetMaxFlyHeight(72)
SetMaxPlayerFlyHeight (72)
AISnipeSuitabilityDist(30)

ReadDataFile("SIDE\\all.lvl",
"all_inf_rifleman_fleet",
"all_inf_rocketeer_fleet",
"all_inf_engineer_fleet",
"all_inf_sniper_fleet",
"all_inf_officer",
"all_hero_luke_jedi",
"all_inf_wookiee")
ReadDataFile("SIDE\\imp.lvl",
"imp_inf_rifleman",
"imp_inf_rocketeer",
"imp_inf_engineer",
"imp_inf_sniper",
"imp_inf_officer",
"imp_inf_dark_trooper")

ReadDataFile("SIDE\\imp.lvl",
"imp_hero_emperor")

SetupTeams{

all={
team = ALL,
units = 32,
reinforcements = 150,
soldier = {"all_inf_rifleman_fleet",7, 25},
assault = {"all_inf_rocketeer_fleet",1, 4},
engineer = {"all_inf_engineer_fleet",1, 4},
sniper = {"all_inf_sniper_fleet",1, 4},
officer = {"all_inf_officer",1, 4},
special = {"all_inf_wookiee",1, 4},

},

imp={
team = IMP,
units = 32,
reinforcements = 150,
soldier = {"imp_inf_rifleman",7, 25},
assault = {"imp_inf_rocketeer",1, 4},
engineer = {"imp_inf_engineer",1, 4},
sniper = {"imp_inf_sniper",1, 4},
officer = {"imp_inf_officer",1, 4},
special = {"imp_inf_dark_trooper",1, 4},


}
}

SetHeroClass(ALL, "all_hero_luke_jedi")
SetHeroClass(IMP, "imp_hero_emperor")

-- Level Stats
ClearWalkers()
-- AddWalkerType(0, 0) -- 8 droidekas (special case: 0 leg pairs)
-- AddWalkerType(1, 0) -- 8 droidekas (special case: 0 leg pairs)
-- AddWalkerType(2, 0) -- 2 spider walkers with 2 leg pairs each
-- AddWalkerType(3, 0) -- 2 attes with 3 leg pairs each
local weaponCnt = 200
SetMemoryPoolSize ("Aimer", 0)
SetMemoryPoolSize ("AmmoCounter", weaponCnt)
SetMemoryPoolSize ("BaseHint", 300)
SetMemoryPoolSize ("EnergyBar", weaponCnt)
SetMemoryPoolSize ("EntityCloth", 18)
SetMemoryPoolSize ("EntityLight", 100)
SetMemoryPoolSize ("EntitySoundStatic", 30)
SetMemoryPoolSize ("SoundSpaceRegion", 50)
SetMemoryPoolSize ("MountedTurret", 0)
SetMemoryPoolSize ("Navigator", 50)
SetMemoryPoolSize ("Obstacle", 260)
SetMemoryPoolSize ("PathFollower", 50)
SetMemoryPoolSize ("PathNode", 512)
SetMemoryPoolSize ("RedOmniLight", 130)
SetMemoryPoolSize ("ShieldEffect", 0)
SetMemoryPoolSize ("TreeGridStack", 200)
SetMemoryPoolSize ("UnitAgent", 50)
SetMemoryPoolSize ("UnitController", 50)
SetMemoryPoolSize ("Weapon", weaponCnt)
SetMemoryPoolSize ("EntityFlyer", 6)

-- Local Stats
--SetTeamName (3, "locals")
--AddUnitClass (3, "ewk_inf_trooper", 4)
--AddUnitClass (3, "ewk_inf_repair", 6)
--SetUnitCount (3, 14)
--SetTeamAsFriend(3,ATT)
--SetTeamAsEnemy(3,DEF)


SetSpawnDelay(10.0, 0.25)
ReadDataFile("dea\\dea1.lvl", "dea1_Conquest")
SetDenseEnvironment("true")

--SetStayInTurrets(1)


-- Movies
-- SetVictoryMovie(ALL, "all_end_victory")
-- SetDefeatMovie(ALL, "imp_end_victory")
-- SetVictoryMovie(IMP, "imp_end_victory")
-- SetDefeatMovie(IMP, "all_end_victory")

-- Sound

voiceSlow = OpenAudioStream("sound\\global.lvl", "all_unit_vo_slow")
AudioStreamAppendSegments("sound\\global.lvl", "imp_unit_vo_slow", voiceSlow)
AudioStreamAppendSegments("sound\\global.lvl", "global_vo_slow", voiceSlow)

voiceQuick = OpenAudioStream("sound\\global.lvl", "all_unit_vo_quick")
AudioStreamAppendSegments("sound\\global.lvl", "imp_unit_vo_quick", voiceQuick)

OpenAudioStream("sound\\global.lvl", "gcw_music")
-- OpenAudioStream("sound\\global.lvl", "global_vo_quick")
-- OpenAudioStream("sound\\global.lvl", "global_vo_slow")
OpenAudioStream("sound\\dea.lvl", "dea1")
OpenAudioStream("sound\\dea.lvl", "dea1")
-- OpenAudioStream("sound\\cor.lvl", "dea1gcw_emt")

SetBleedingVoiceOver(ALL, ALL, "all_off_com_report_us_overwhelmed", 1)
SetBleedingVoiceOver(ALL, IMP, "all_off_com_report_enemy_losing", 1)
SetBleedingVoiceOver(IMP, ALL, "imp_off_com_report_enemy_losing", 1)
SetBleedingVoiceOver(IMP, IMP, "imp_off_com_report_us_overwhelmed", 1)

SetLowReinforcementsVoiceOver(ALL, ALL, "all_off_defeat_im", .1, 1)
SetLowReinforcementsVoiceOver(ALL, IMP, "all_off_victory_im", .1, 1)
SetLowReinforcementsVoiceOver(IMP, IMP, "imp_off_defeat_im", .1, 1)
SetLowReinforcementsVoiceOver(IMP, ALL, "imp_off_victory_im", .1, 1)

SetOutOfBoundsVoiceOver(1, "allleaving")
SetOutOfBoundsVoiceOver(2, "impleaving")

SetAmbientMusic(ALL, 1.0, "all_dea_amb_start", 0,1)
SetAmbientMusic(ALL, 0.8, "all_dea_amb_middle", 1,1)
SetAmbientMusic(ALL, 0.2,"all_dea_amb_end", 2,1)
SetAmbientMusic(IMP, 1.0, "imp_dea_amb_start", 0,1)
SetAmbientMusic(IMP, 0.8, "imp_dea_amb_middle", 1,1)
SetAmbientMusic(IMP, 0.2,"imp_dea_amb_end", 2,1)

SetVictoryMusic(ALL, "all_dea_amb_victory")
SetDefeatMusic (ALL, "all_dea_amb_defeat")
SetVictoryMusic(IMP, "imp_dea_amb_victory")
SetDefeatMusic (IMP, "imp_dea_amb_defeat")

SetSoundEffect("ScopeDisplayZoomIn", "binocularzoomin")
SetSoundEffect("ScopeDisplayZoomOut", "binocularzoomout")
-- SetSoundEffect("BirdScatter", "birdsFlySeq1")
SetSoundEffect("SpawnDisplayUnitChange", "shell_select_unit")
SetSoundEffect("SpawnDisplayUnitAccept", "shell_menu_enter")
SetSoundEffect("SpawnDisplaySpawnPointChange", "shell_select_change")
SetSoundEffect("SpawnDisplaySpawnPointAccept", "shell_menu_enter")
SetSoundEffect("SpawnDisplayBack", "shell_menu_exit")


SetAttackingTeam(ATT)



AddCameraShot(-0.404895, 0.000992, -0.514360, -0.002240, -121.539894, 62.536297, -257.699493)
--Homestead
AddCameraShot(0.040922, -0.004049, -0.994299, -0.098381, -103.729523, 55.546598, -225.360893)
--Sarlac Pit
AddCameraShot(-1.0, 0.0, -0.514360, 0.0, -55.381485, 50.450953, -96.514324)
end
[/code]
For this test I did the exact same playlist as test 1:
Hidden/Spoiler:
[list=1][*]Mygeeto GCW Conquest
[*]Polis Massa GCW Conquest
[*]Death Star GCW Conquest (modified, same as the asset)
[*]Tantive IV GCW Conquest
[*]Polis Massa GCW Conquest
[*]Dagobah GCW Conquest[/list]
I also stuck to the same settings and rules. This is what happened:
Hidden/Spoiler:
[list=1][*]Mygeeto: Heroes are unlockable
[*]Polis Massa: Heroes are unlockable
[*]Death Star: Heroes are unlockable
[*]Tantive IV: Heroes are unlockable
[*]Polis Massa: Heroes are unlockable
[*]Dagobah: Heroes are unlockable[/list]
[list=1][*]Mygeeto: Heroes are unlockable[/list]
This rules out the possibility that something else in the Death Star mission lua was causing the change.

Test 3) A vanilla campaign mission
Before I did any of these tests, I'd tried playlists with vanilla campaign missions and had the same thing happen (most of which contain EnableSPScriptedHeroes()) so I wanted to test them too. I kept the mod SPE installed, with no changes made since the control test. But I didn't put the Death Star mission into the playlist. This is the playlist I used:
  1. Mygeeto GCW Conquest
  2. Polis Massa GCW Conquest
  3. Utapau CW Campaign
  4. Tantive IV GCW Conquest
  5. Polis Massa GCW Conquest
  6. Dagobah GCW Conquest
In this case, I didn't bother sticking to the soldier only rule for the campaign mission. I did stick to "rebel soldier & hero" for every other mission. I also went through more of the playlist's second cycle, because the campaign mission has scripted heroes set up and I wanted to know if they would be broken the second time. This is what happened:
Hidden/Spoiler:
[list=1][*]Mygeeto: Heroes are unlockable
[*]Polis Massa: Heroes are unlockable
[*]Utapau CW: Campaign heroes function correctly
[*]Tantive IV: No prompt to play as heroes
[*]Polis Massa: No prompt to play as heroes
[*]Dagobah: No prompt to play as heroes[/list]
[list=1][*]Mygeeto: No prompt to play as heroes
[*]Polis Massa: No prompt to play as heroes
[*]Utapau CW: Campaign heroes function correctly[/list]
I have an extra note to make about this. I had a 5 minute timer applied to the conquest missions in the instant action settings. None of the conquest missions had that timer after the Utapau mission. The first two games in this test were the ones where the 5 minute timer applied; they didn't get the timer back in the second cycle; it completely disappeared after Utapau. I did not have this problem in test 1, which is making me think there might be other lua commands with negative effects on whole instant action playlists. After the test, I looked at the instant action settings (without closing the game) and it still said that there was a 5 minute timer on conquest. Weird. But the test itself, in the context of what I was testing for, shows hero unlocks breaking after the mission with EnableSPScriptedHeroes() again. It also shows the heroes were still working, because the second cycle of Utapau (which had the scripted hero unlocks set up) functioned just as well as the first. I suppose this problem never comes up in vanilla, since campaign missions are normally hidden from instant action anyway. But it's worth people knowing that using EnableSPScriptedHeroes() in a mission will have a negative affect on the heroes in all of the missions after it. And, if anyone else wants to try it out, hopefully this is repeatable.
Post Reply