PDA

View Full Version : Auto Hyper space bypassed.


Rags707
25th Jun 04, 5:14 AM
Yes!!! I have an ear to ear grin on right now despite the lack of sleep.

My first thought was to make a Sob_Group out of all the players resourcers and have the mission wait till they were all docked before hypering, but that didn’t work out so good. Probably because I’m still new to this SCAR/LUA thingermabobber. Well that and the NIS, but we’ll discuss that later.

While browsing through the mission 1 lua to find out how they made the resource Sob work I found an interesting method used to invoke a cheat in the mission. I haven’t tried their cheat yet but I found the implementation really useful.

Basically I have modified mission 3 so that once all the objectives are completed, the player has to type:
J U M P
In order to trigger the final letterbox scene and auto hyper.

Now that I have a much better understanding of how the mission scripts work I intend to go through all of them and implement this method. Well not all the missions, some like mission one are ‘emergency’ hyperspaces and should probably be let alone. I’m just using a letterbox and text message which leads me to a question. Is there anyone who knows the # of the audio file where fleet command says something like “jump at your discretion”? I know I’ve heard that before, I’d really to play that clip along with the message.

I’ll post up somewhere for everyone to use the finished modified missions once they are complete, however if your interested in how it was done, I started by using the m03_staging.lua from Evillejedi's Awesome Data Files.



Step 1) Repair Broken Lua.
Apparently LuaDC makes these things go out of order a bit. I had to copy all the functions and place them above the Events in the file. OnInit() should be the very first function after the globals. File structure like so:
---------------------------------------------
globals
OnInit()
all other functions
Events = {}
event scripts
---------------------------------------------


Step 2) Add global variables. I add these 4 to track the key presses:


-- Added to allow players to type jump when ready to Hyperspace out of the mission
g_jpressed = 0
g_upressed = 0
g_mpressed = 0
g_ppressed = 0


Step 3) Modify function Rule_NISCompleted(). Comment out 1 and then add the following lines as shown. You can leave out the print, I just used a boat load of prints together with the –luatrace option to help me figure out what was going on. Many thanks to ZaTcH for telling me about that.

-- Event_Start("MissionWon")
print("========================== CALLING hyper bypass event MissionWonWait")
EventPlaying = 1
Event_Start("MissionWonWait")
Rule_AddInterval("Rule_PlayMissionWonWait", 1)


Step 4) Add new function rule. The lines below as shown:

function Rule_PlayMissionWonWait()
if Event_IsDone("MissionWonWait")==1 then
print("========================== Hyperspace now activated")
Rule_Add("Rule_HyperspaceActivate")
UI_BindKeyEvent(JKEY, "Rags_HyperJ")
UI_BindKeyEvent(UKEY, "Rags_HyperU")
UI_BindKeyEvent(MKEY, "Rags_HyperM")
UI_BindKeyEvent(PKEY, "Rags_HyperP")
Rule_Remove("Rule_PlayMissionWonWait")
end

end


I originally had these bind key commands in Rule_Init() as they are in mission 1, but it didn’t always work. Something to do with loading saves I think. I tried writing an OnStartOrLoad() function but that broke most everything else! I will investigate further and see what I can figure out.



Step 5) Add new functions. These are all related so I’ll list them in one block. All they do is increment or reset the global variables, and the last 3 are nearly a straight cut and paste.

function Rags_HyperJ()
if g_jpressed>1 then
g_jpressed = 0
g_upressed = 0
g_mpressed = 0
g_ppressed = 0
else
g_jpressed = ( g_jpressed + 1 )
end

end

function Rags_HyperU()
if g_jpressed==1 then
g_upressed = 1
end

end

function Rags_HyperM()
if g_jpressed==1 then
g_mpressed = 1
end

end

function Rags_HyperP()
if g_jpressed==1 then
g_ppressed = 1
end

end


Someone can probably tell me a better method for these, but the other ways I tried made it really difficult to get it to recognize that you had typed ‘jump’.


Step 6) Add new function Rule. This is the guy that does most of the work:

function Rule_HyperspaceActivate()
if g_jpressed==1 then
print("========================== J passed")
if g_upressed==1 then
print("========================== U passed")
if g_mpressed==1 then
print("========================== M passed")
if g_ppressed==1 then
print("========================== JUMP detected")
EventPlaying = 1
Event_Start("MissionWon")
Rule_Remove("Rule_HyperspaceActivate")

end

end

end

end

end


again feel free to leave out the prints, they were just for debugging.


Step 7) Finally the actual event where we tell the player about the new command. This event syntax is a real pain in my @$$. Took me a long time and many crashes to desktop to figure it out. I left the commented lines in because I think I’ll probably need them in other missions. They weren’t needed here because the Bentusi NIS event that plays right before this one doesn’t shut down letterbox or re-enable sound and stuff when it finishes. It wouldn’t surprise me if I’d had the code correct for some time before figuring out The previous event was messing it up:

Events.MissionWonWait =
{
{
{ "Sound_EnableAllSpeech(1)", "" },
-- { "Sound_EnterIntelEvent()", "" },
-- { "Universe_EnableSkip(1)", "" },
},
-- {
-- HW2_Letterbox(1),
-- HW2_Wait(2),
-- },
{
HW2_SubTitleEvent(Actor_FleetCommand, "De-select all ships and type { j u m p } to hyperspace", 5),
},
{
HW2_Wait(2),
},
{
HW2_Letterbox(0),
HW2_Wait(2),
{ "Universe_EnableSkip(0)", "" },
{ "Sound_ExitIntelEvent()", "" },
{ "EventPlaying = 0", "", },
},
}


Step 8) Go play the mission and enjoy freedom of hyperspace choice!

Again there is something not right with the save games. I’m almost positive if you wait until after the jump message then save, that when you reload that game you’ll be stuck in the mission for all eternity. Other than that it works pretty good.

The biggest hurdles I had doing this were lack of knowledge/experience with the SCAR when setting up the event, and the other mission events causing my event to fail. The functions stuff is pretty straight forward to me. I’m guessing that integrating these changes with the existing mission events will probably be the most challenging part.

Well that’s it. I hope you found this informative or at least somewhat amusing. Thank you for spending your time to read it.

Rags

P.S. I’m still looking for a working de-compiled scar_util.lua if anyone is willing to share. And the message number for the hyperspace fleet command audio.

evillejedi
25th Jun 04, 6:25 AM
very interesting, very interesting indeed, I believe my decompiled data.zip (on zatch's FTP and linked on the wiki) has the scar _util

though I think the problem you are running into has to do with the crappy way relics lua parser handles tables (I had to do some weird hacks to get mine working) basically it has trouble determining the enumeration of a table entry, so stuff like "foreach" indexes through the array numerically, but the function gets a nil because the array is considered a non-enumerated literal string

I dunno I'm really tired right now so some of that may not make sense or be right....

Rags707
25th Jun 04, 2:37 PM
I did try the one from your data from somewhere and got a bunch of nil table errors. That does make sense, i know a good bit of c/c++. But what I don't know is the proper syntax or format to fix those errors.

I have downloaded the LUA manual/docs but haven't really delved into them yet. Just read the RDN kit SCAR doc. What I'd like to get is a syntax definition for Visual C++ or .Net so I can do my coding with visual assist :) . I downloaded a copy of Scite but haven't installed it yet, its my understanding scite does syntax highlights. Perhaps when i get through with the Lua reference doc I can work on porting the definition over or something like that.

Do you remember any of the hacks you used, or could you send the file to me or even post code snipets up here for the functions of mine that are broken?

Any help would be greatly appreciated, right now It feels a lot like banging my head against a brick wall when trying to debug that file.

Oh another thing.

While this method above works fine I'd much rather use a single key, but all the keys are already bound to other stuff. At least the keys that I know that work. Is there anywhere I might be able to find the definitions for the key constants to try and find one that is currently unbound? Like maybe F12 to hyper, much easier to detect and easier on the player too.

Anyway thanks for the reply.

Rags

evillejedi
25th Jun 04, 3:04 PM
one of the problems with relics lua implementation is that it really doesn't like stuff across multiple files (table in one file, function in another)

annoying thing #1 always declare tables before they are used

annoying thing #2 allways include dofiles before their contents are used

hack #1 copy and paste either the function or table into the current file (messy)

hack #2 make a new lua file and include it as a dofile, in the lua, make a table that just sets the values equal to themselves

IE
conversion_table=
{
{VARIABLEX=variablex},
}

hack #3 declare all of your tables fully with members
table =
{
{name=variablex},
}


access with
table.name

the best solution for the scar_util problem seems to be copying the function into you file.

Rags707
25th Jun 04, 3:21 PM
Now were talking damint!!! I hadn't considered that. It could make things quite a bit easier.

What happens if i create ( or cut and paste then mod ) a function in one of my files that is the same as one in the scar_util ? Will my local copy over-ride/over-write the other one or will I get a CTD? I'll have to try that.

Or are you saying to take out the "dofile scar_util" command thing and just cut and paste over the functions that the particular file, in this case mission 3 need?

Interesting, I could at least move the functions over maybe and debug 'em there then move them back or something once they're working properly.

And thanks a bunch for the code snipets, You've given me a lot to chew on here.

Ahhhhhh!!! You know what I'll bet its a matter of order. Prolly the LuaDC has put table declarations before there first use and stuff. hrmmmmmmm, man I really wish I could do this scar with visual assist. That app has made me so lazy!!

This is great info evil!!, awesome man. I gotta go play with this stuff now and see what happens. BBL.

Rags

Rags707
26th Jun 04, 7:19 PM
Well I didn't get to do much last night but read the Lua ref, storm knocked the power out here for several hours. However here is what I've found out.

You can bind any letter or number key, and the function keys F1 - F10. You cannot bind F11 or F12. We do know that other keys work, but I have not yet discovered how to bind them in the script.

When you save a game the value of all global variables in the missions is saved, along with the I guess you'd call it the contents of the active rules list. So on load all globals get thier previous values, and whatever rules that were running will resume.

Using this new knowledge I have greatly simplified the auto Hyper bypass. I'm now using a Rule_AddInterval call to bind the only unused key I could find, F9, at the appropriate time to the final sequence. So, now a single keypress activates the hyperspace, and it works perfectly when resuming a saved game!

Now all I need is that audio.....

Rags

Rags707
27th Jun 04, 2:15 PM
I despise mission 2 with a passion now! well not really but it is causing me headaches.

So the straight LuaDC of it didn't work, as expected. Moved the functions to where they should be. Still no good, fix the syntax errors, ahhh its working. Or so I thought. Tried to play through the mission so I could figure out where to put the break in for the auto hyper bypass. Right after the carrier gets destroyed Kabboom!!! Total system lock. Reload try again, same thing. No hint of any problems in the log. So I'm trying to figure out which rules and or events might be suspect for causing the crash. Well, let me say that the events and function rules in mision 2 follow some rather twisted and convulted logic. More as a way of how it has to work for the script, but hard to follow just by reading the code. So rather then spend a lot of time trying to figure out where to look for the problem, I wrote some helper stuff which I added to scar_util.lua.

Anyway I've included the code here from some functions I wrote to track all the rules and print them to the log so you can see whats going on. I tried to actually remove the inactive rules from the list, but that didn't work. The list kept getting corrupted and stuff.

I've also included here a global abilities list I made to fix problems in the mission with a missing abilitiesList table. Then I use the AllabilitiesList along with SobGroup_CanDoAbility to find the actual ones to shut down or whatever the case may be.

Many thanks to Thought and whoever else is maintaining the Wiki over at Karos Graveyard, its proving an invaluable resource for me.

Right then here is the code. It's not pretty or perfect but it at least helps give you an idea of whats happenning in the script during a mission.



AllabilityList = {
AB_None,
AB_Move,
AB_Attack,
AB_Guard,
AB_Repair,
AB_Cloak,
AB_Harvest,
AB_Mine,
AB_Capture,
AB_Dock,
AB_AcceptDocking,
AB_Builder,
AB_Stop,
AB_Hyperspace,
AB_Parade,
AB_FormHyperspaceGate,
AB_HyperspaceViaGate,
AB_SensorPing,
AB_SpecialAttack,
AB_Retire,
AB_DefenseField,
AB_DefenseFieldShield,
AB_HyperspaceInhibitor,
AB_Salvage,
AB_Steering,
AB_Targeting,
AB_Sensors,
AB_Lights,
AB_Scuttle,
AB_UseSpecialWeaponsInNormalAttack,
}
AllabilityStrList = {
"AB_None",
"AB_Move",
"AB_Attack",
"AB_Guard",
"AB_Repair",
"AB_Cloak",
"AB_Harvest",
"AB_Mine",
"AB_Capture",
"AB_Dock",
"AB_AcceptDocking",
"AB_Builder",
"AB_Stop",
"AB_Hyperspace",
"AB_Parade",
"AB_FormHyperspaceGate",
"AB_HyperspaceViaGate",
"AB_SensorPing",
"AB_SpecialAttack",
"AB_Retire",
"AB_DefenseField",
"AB_DefenseFieldShield",
"AB_HyperspaceInhibitor",
"AB_Salvage",
"AB_Steering",
"AB_Targeting",
"AB_Sensors",
"AB_Lights",
"AB_Scuttle",
"AB_UseSpecialWeaponsInNormalAttack",
}

ActiveRules = {} -- Tracks the rule names
ActiveRulesInt = {} -- Tracks the interval of the rule, 0 means Rule_Add()
ActiveRulesStat = {} -- Tracks the rules status "" means active

-- ----------------------------------------------------------------------------
-- this function intercepts calls to add rule to store them in a set of global
-- rules lists.
-- ----------------------------------------------------------------------------
function Rule_Add_Debug(strRule)
-- find out how many rules there are now
local nIdx = getn(ActiveRules)

-- append the new rule to the lists
ActiveRules[(nIdx + 1)] = strRule
ActiveRulesInt[(nIdx + 1)] = 0
ActiveRulesStat[(nIdx + 1)] = ""

-- tell me any time there is a change
PrintActiveRules()

-- now add the rule
Rule_Add(strRule)

end

-- ----------------------------------------------------------------------------
-- Same as above but it takes another argument for the interval
-- ----------------------------------------------------------------------------
function Rule_AddInterval_Debug(strRule, nInterval)
-- find out how many rules there are now
local nIdx = getn(ActiveRules)

-- append the new rule to the lists
ActiveRules[(nIdx + 1)] = strRule
ActiveRulesInt[(nIdx + 1)] = nInterval
ActiveRulesStat[(nIdx + 1)] = ""

-- tell me any time there is a change
PrintActiveRules()

-- now add the rule
Rule_AddInterval(strRule, nInterval)

end

-- ----------------------------------------------------------------------------
-- Intercepts calls to remove rule so they can be set to 'Removed' in the
-- global active rules lists.
-- ----------------------------------------------------------------------------
function Rule_Remove_Debug(strRule)

-- step thru the list and find the rule to be removed once we
-- find the rule to remove we just set the status
-- table for that rule to 'Removed :'
for i = 1,getn(ActiveRules),1 do

-- if the lengths are different this cannot be the one
-- we are looking for
if strlen(ActiveRules[i])==strlen(strRule) then

-- this may be it, do the string search to be sure
if strfind(ActiveRules[i], strRule)==1 then

-- this is it, set the status
ActiveRulesStat[i] = " Removed :"
end

end

end

-- finally remove the rule
Rule_Remove(strRule)

-- tell me what's going on
print("Rule Removed: "..strRule)

end

-- ----------------------------------------------------------------------------
-- Prints the list of rules, thier status, and call intervals to the log
-- ----------------------------------------------------------------------------
function PrintActiveRules()
print(" ")
print("============================================= Current Rule Set ==")
for i = 1,getn(ActiveRules),1 do
print(ActiveRulesStat[i]..ActiveRules[i]..", "..ActiveRulesInt[i])

end

print("=================================================================")
-- added these to insert some newlines and make the log easier to read
print(" ")
print(" ")
end



Here is some sample output

============================================= Current Rule Set ==
Rule_Init, 0
Rule_DisableSpeech, 0
Rule_watchForNISDoneFromTimer, 41
Rule_watchForNISDone, 0
=================================================================


Rule Removed: Rule_Init
Rule Removed: Rule_DisableSpeech
*** StatusCriticallyDamaged: Sp_Tanker
build available
generic build available
REACTIVE FLEET: Creating "VGR_INTERCEPTOR", player 1 "C", sobgroup "Convoy3Interceptors2", slot at (38767, 0,-35055)
REACTIVE FLEET: Creating "VGR_INTERCEPTOR", player 1 "C", sobgroup "Convoy6Interceptors2", slot at (-15508, 0,-52958)

============================================= Current Rule Set ==
Removed :Rule_Init, 0
Removed :Rule_DisableSpeech, 0
Rule_watchForNISDoneFromTimer, 41
Rule_watchForNISDone, 0
Rule_spawnEscorts, 1
=================================================================



============================================= Current Rule Set ==
Removed :Rule_Init, 0
Removed :Rule_DisableSpeech, 0
Rule_watchForNISDoneFromTimer, 41
Rule_watchForNISDone, 0
Rule_spawnEscorts, 1
Rule_Init2, 10
=================================================================


Rule Removed: Rule_watchForNISDone

============================================= Current Rule Set ==
Removed :Rule_Init, 0
Removed :Rule_DisableSpeech, 0
Rule_watchForNISDoneFromTimer, 41
Removed :Rule_watchForNISDone, 0
Rule_spawnEscorts, 1
Rule_Init2, 10
EscortSetup, 1
=================================================================


Rule Removed: Rule_spawnEscorts
Doing Escort setup on 2 Interceptor squadrons!!
Doing Escort setup on 1 Bomber squadron!!
Rule Removed: EscortSetup
starting Init2 !!!!! !!!!!!!! !!!!!!!! !!!!!!!! !!!!!!!
Convoy3Interceptors2 are alive!!!!!
Convoy6Interceptors2 are alive!!!!!

============================================= Current Rule Set ==
Removed :Rule_Init, 0
Removed :Rule_DisableSpeech, 0
Rule_watchForNISDoneFromTimer, 41
Removed :Rule_watchForNISDone, 0
Removed :Rule_spawnEscorts, 1
Rule_Init2, 10
Removed :EscortSetup, 1
Rule_convoySetup, 5
=================================================================



If this doesn't help me find the problem I'll end up adding something similar for the Events I guess. Enjoy.

Rags