THUG PC questions

Tony Hawk's Underground modding is discussed here.
Ksk
Posts: 7
Joined: Sun Apr 15, 2012 1:11 am
Contact:

THUG PC questions

Postby Ksk » Sun Apr 15, 2012 1:24 am

Hi everyone, I'm working on a little mod and I'm wondering a couple things. Information about the games is pretty scattered and not well-documented, so I figured I should ask everyone in here - if you're still around :)

1. Is there any known way to enable fog on THUG PC? I discovered a scripting error in /engine/menu/timeofday.qb which prevented the fog settings from being enabled, but patching this still doesn't change anything, so it's probably not a scripting issue.
2. Has anyone found a way to change the key binding for spine transfers/acid drops to a single button? I'm pretty sure that it can't be changed through scripting.

The reason I'm asking is because I'm writing a time-of-day transition feature (similar to THUG2 and onward) along with random weather effects that would benefit greatly from being able to turn fog on!
WhoElseButMe
Posts: 419
Joined: Tue Aug 04, 2009 12:50 am
Location: FL - USA
Contact:

Re: THUG PC questions

Postby WhoElseButMe » Sun Apr 15, 2012 11:49 am

Not sure about this but if THUG time of day is anything like the newer games its disabled online and the only way around this is to either figure out that specific games method of blocking it and bypass the code or setup a temp_tod. Also, my memory is kind of foggy (pun intended), wasn't fog an on/off option in chads thug mod?
As for the spine keys, I don't think this has been done and without a decompressed exe I don't see this being possible. That is, of course, if its not possible through scripting.
Image
WhoElseButMe on Nov 26, 2009 wrote:It's that lack of respect amongst their peers and ignorance towards modding etiquette that keeps us who know this stuff well from spreading it like wild fire. We do still enjoy playing the game and if you need to cheat to play a game PLAY SOMETHING ELSE YOU DON'T SUCK AT.
tiki
Posts: 3
Joined: Wed Apr 18, 2012 9:56 am
Contact:

Re: THUG PC questions

Postby tiki » Wed Apr 18, 2012 10:15 am

some of us have been using a workaround for spine transfers with an app called xpadder.. it just allows you to remap your controller to keyboard keys instead of the default thug mapping.

in xpadder you can also create custom macros like any typical gaming mouse/keyboard software, so you can assign 1 button on your controller to mimic 2 keypresses on your keyboard

i have numpad 7&9 assigned to R2 and this button covers drop downs, acids and spines

there are some downsides, you need to navigate menus with start/select and not a/b like you're used to... the only real thing missing is l1+r1 cavemans, but i find a 1 button caveman seems to be a lot better anyway.

http://dl.dropbox.com/u/21932190/xpadder.jpg


also, anteara posted about thug1 bindings in a thread on phun

Doublepost, eh, I think we may need to take a different approach to this. PS2 Controls are assigned in the exe, which I believe means that we can make a new launcher (or a dll) that assigns our controller buttons to the assignments in exe, however I don't have the exe source, nor do I know how to make a dll, so I can't do this. WhoElseButMe might be able to provide insight. P.S. don't quote me on the above it's just a brainstorm.

Another Idea I had was that since we can change the bindings in the menus, we could either a)
Look at how the function is made (Stored in the exe, raises the same problem we can't access it)
or b) try and trick the game in to believing we're in a menu so that the menu controls are loader.

anyway hopefully whoelsebutme or morten can come up with some ideas.
Ksk
Posts: 7
Joined: Sun Apr 15, 2012 1:11 am
Contact:

Re: THUG PC questions

Postby Ksk » Thu Apr 19, 2012 12:26 am

Ah, thanks for that. I've been modding PS2-style controls into the game, and I can get everything converted but spine transfer/acid drop. This unfortunately means that it has the same key binding as walk, however I've mitigated the issue by increasing the sensitivity of the walk keys. That is to say, you have to press them concurrently, so if you are going up to a QP holding one spin key (typically the case), you can press the other and you will only trigger the spine transfer/acid drop.

THUG2 seems to have introduced some sort of 'TOD Manager', which is absent in THUG, so enabling time-of-day online is as simple as removing a condition on NetGame in /engine/menu/timeofday.qb. This allows the night-time lighting effects and such, though it only happens on the client side of course.


One thing I'm also wondering about is the ability to save and reload custom data. I did a search on here and found the way to add simple custom settings to a CAS file's net/split screen options, which can store either a string or checksum name. However, I've not seen any information on how to store more complex pieces of data, such as an array.

For instance, I am trying to test out the ability to save and reload a node array, but am unsure how to go about it in a way that allows both reading and writing. You can use the net/split screen options to store it but there is no apparent way to retrieve it. I'm thinking that there may be a way to hook onto a goal editor save file, since it stores nodes, but I'm not sure how it could be done.
WhoElseButMe
Posts: 419
Joined: Tue Aug 04, 2009 12:50 am
Location: FL - USA
Contact:

Re: THUG PC questions

Postby WhoElseButMe » Thu Apr 19, 2012 1:40 am

Preference options have in place functions for retrieving a string, checksum or a numerical value only.
You could write your own function for parsing the preference structure to first check if an element exist. If the element exist perform parsing using your method.
That should allow you to add a StructureStructure with any number of valid structure items e.g. a StructureArray.
Keep in mind the size of your skater file mustn't exceed the max allowed size for the game, else you'll crash.

Also, with using the method I suggested above you could store a structure of an array of checksums who's ID would never change (so you can easily check if it exist). The checksum values would ultimately be ID's of other structure items you have created within the preference structure (ID's for a node array for a specific level or whatever). The checksums you add to this structure could then be parsed and used, first for checking existence within the preference structure and then for handling the data you parse.
Image
WhoElseButMe on Nov 26, 2009 wrote:It's that lack of respect amongst their peers and ignorance towards modding etiquette that keeps us who know this stuff well from spreading it like wild fire. We do still enjoy playing the game and if you need to cheat to play a game PLAY SOMETHING ELSE YOU DON'T SUCK AT.
Ksk
Posts: 7
Joined: Sun Apr 15, 2012 1:11 am
Contact:

Re: THUG PC questions

Postby Ksk » Thu Apr 19, 2012 1:52 am

That sounds cool, I just don't know how to access the preference structure in order to parse it. I only know of the three GetPreference methods which return only a desired string/checksum. If you could let me know how to get at the entire thing, that would be great, as I could easily write the method to search for it.
WhoElseButMe
Posts: 419
Joined: Tue Aug 04, 2009 12:50 am
Location: FL - USA
Contact:

Re: THUG PC questions

Postby WhoElseButMe » Thu Apr 19, 2012 2:53 am

Since we know the preference structure ID already you could easily do something like below to get the structure and check if an element exist. Then if exist you would check for parameters within the structure item that you found exists.

Code: Select all

:i $TempArray$ = :a{:a}
:i if call $StructureContains$ arguments
      $structure$ = $default_network_preferences$ $My_Struct_Item$
   :i if call $StructureContains$ arguments
         $structure$ = $My_Struct_Item$ $My_Array_Item_To_Parse$
      :i %GLOBAL%$TempArray$ = $My_Struct_Item$->$My_Array_Item_To_Parse$
      :i $GetArraySize$%GLOBAL%$TempArray$
      #/ you could then, either pass the TempArray to another function for parsing or jump into a while loop here and parse the array,
      #/ looping %GLOBAL%$Array_Size$ (the id for the array size returned by GetArraySize)
      :i $index$ = 0
      :i while
         #/ TODO: perform parsing actions on each element within the array
         :i %GLOBAL%$index$ =  (%GLOBAL%$index$ + %i(1,00000001))
      :i loop_to %GLOBAL%$Array_Size$
   :i endif
:i endif

To clearify "StructureContains" a little bit
"structure" is the ID of the structure to iterate through looking for the second parameter which is the ID of the item within the "structure" we wish to find.
Image
WhoElseButMe on Nov 26, 2009 wrote:It's that lack of respect amongst their peers and ignorance towards modding etiquette that keeps us who know this stuff well from spreading it like wild fire. We do still enjoy playing the game and if you need to cheat to play a game PLAY SOMETHING ELSE YOU DON'T SUCK AT.
Ksk
Posts: 7
Joined: Sun Apr 15, 2012 1:11 am
Contact:

Re: THUG PC questions

Postby Ksk » Thu Apr 19, 2012 3:51 am

That seems to be more or less the code - however, are you referencing the default preference structures? I'm hoping to be able to read the array as it exists in my save file - when I tried it out I got an empty array (which is the default).
WhoElseButMe
Posts: 419
Joined: Tue Aug 04, 2009 12:50 am
Location: FL - USA
Contact:

Re: THUG PC questions

Postby WhoElseButMe » Thu Apr 19, 2012 4:17 am

Yes, it looks within the default_network_preferences
The GetPrefference* functions are within the exe

I suppose another way you could approach this would be to utilize the checksum and the string values to hold different information
Say for example you want to store information about a ped placed in a level. You could set the checksum to something like MyPed, where if checksum equals MyPed parse the string for keywords that would aid in setting up the ped parameters where you would search through a fixed structure you create to get a specific ped.
The string could contain anything you want as long as your string parsing method knows how to handle the data/looks for the right params.
Example String: (the checksum should also determine how the string parser works, on peds or model objects in case you need a different set of parameters)
name:(hawk);pos:(0,0,0);radius:(20);
your fixed structure could have names to match the ped so you could do a formattext to return a checksum %s(0,"myped_%n")$n$ = the_name_parameter_parsed
then you could set its pos and radius if you plan on adding events to the object or really anything, event:(event_to_run);eventtype:(object_in_radius);.
Image
WhoElseButMe on Nov 26, 2009 wrote:It's that lack of respect amongst their peers and ignorance towards modding etiquette that keeps us who know this stuff well from spreading it like wild fire. We do still enjoy playing the game and if you need to cheat to play a game PLAY SOMETHING ELSE YOU DON'T SUCK AT.
Ksk
Posts: 7
Joined: Sun Apr 15, 2012 1:11 am
Contact:

Re: THUG PC questions

Postby Ksk » Thu Apr 19, 2012 4:47 am

Ah yes, I hadn't considered string parsing.

To offer up a little more detail: It is a level editor of sorts that I'm working on, in the same style as Morten's THUG2 editor I suppose. Except I'll actually finish/release it ;) So the objective is to save/reload nodes into a level, where a node may be one of a selection of types that the editor supports - and there could be hundreds or thousands of extra nodes. I saw that in Morten's last post he mentioned that saving/loading 'might' be possible, and I wonder what solution he has in mind.

In my case, I'm sort of impressed that I was even able to get saving to work, though currently it just dumps the entire NodeArray which isn't ideal for many reasons. There don't seem to be many array-manipulation functions available through scripts, so it's definitely a challenge. Anyway, being able to load from in the game would be excellent, but even if it's not possible then I suppose I could write a tool to append them to the level QB so it could at least be distributed.
WhoElseButMe
Posts: 419
Joined: Tue Aug 04, 2009 12:50 am
Location: FL - USA
Contact:

Re: THUG PC questions

Postby WhoElseButMe » Thu Apr 19, 2012 5:12 am

There are plenty of array manipulating functions, typically you have to make a copy of the array first.
You can then...
AddArrayElement - add an element to the array, must be an object of proper type. e.g. if you have an array of integers it must be an integer item that you're adding.
SetArrayElement - set the value of the element at a specific index within the array
GetRandomArrayElement - Returns a random element from an array.
GetNextArrayElement - Returns the next element from an array at current index.
RemoveArrayElement - Removes the array element at a specific index.

You would typically jump into a while loop to parse the array. Check the parameters within the array if it's an array of structures you can use the "StructureContains" function outlined earlier on each element in the array, gathering information for setting up your level objects.
Also, if you're not sure if the current user has the array you can do

Code: Select all

:i if call $GlobalExists$ arguments
      $name$ = $Your_Node_Array_Name$$type$ = $array$
   #/ TODO: parse the array
:i endif
Image
WhoElseButMe on Nov 26, 2009 wrote:It's that lack of respect amongst their peers and ignorance towards modding etiquette that keeps us who know this stuff well from spreading it like wild fire. We do still enjoy playing the game and if you need to cheat to play a game PLAY SOMETHING ELSE YOU DON'T SUCK AT.
Ksk
Posts: 7
Joined: Sun Apr 15, 2012 1:11 am
Contact:

Re: THUG PC questions

Postby Ksk » Thu Apr 19, 2012 5:49 am

I believe AddArrayElement and RemoveArrayElement don't exist in THUG, which makes for a bit of a challenge :s I'm thinking if I want to store only the newly-created nodes then I will need to initiate a large array with tons of empty structures and put a limit on the number of nodes you can create, or something like that.

PS: Thanks for all your help thus far :)
WhoElseButMe
Posts: 419
Joined: Tue Aug 04, 2009 12:50 am
Location: FL - USA
Contact:

Re: THUG PC questions

Postby WhoElseButMe » Thu Apr 19, 2012 7:40 am

Sorry, I was trying to find the function that uses AddArrayElement, one that should be in THUG1 also. Couldn't find it, I'll keep looking, I have way too many decompiled scripts.
Ksk wrote:PS: Thanks for all your help thus far

Not a problem
Image
WhoElseButMe on Nov 26, 2009 wrote:It's that lack of respect amongst their peers and ignorance towards modding etiquette that keeps us who know this stuff well from spreading it like wild fire. We do still enjoy playing the game and if you need to cheat to play a game PLAY SOMETHING ELSE YOU DON'T SUCK AT.
tiki
Posts: 3
Joined: Wed Apr 18, 2012 9:56 am
Contact:

Re: THUG PC questions

Postby tiki » Thu Apr 19, 2012 4:05 pm

i don't mean to slightly drift off topic but i forgot to add

it's nice to see you again :)
Ksk
Posts: 7
Joined: Sun Apr 15, 2012 1:11 am
Contact:

Re: THUG PC questions

Postby Ksk » Thu Apr 19, 2012 10:13 pm

tiki wrote:i don't mean to slightly drift off topic but i forgot to add

it's nice to see you again :)

Thanks! :)

OK, here's another question for you - hope this one makes sense. I'm working on a level-geometry-manipulation tool as part of my editor, and I have run into a bit of a snag. Basically, it can scroll through available LevelGeometry nodes and show you where they are, but I'm not able to operate on them. I'm looping through the nodes and checking each structure's Class to see if it's a LevelObject and such, then I extract the position and name out of the structure.

I know that nodes in the level are basically CompositeObjects which share the node's name, so I'd like to be able to extract that name property and then call a method on it, such as die or hide or something like that. What I'm finding is that when I extract the Name property out of the node structure, I'm getting the checksum value rather than a pointer, so I can't call methods on it as though it were an object.

I suppose the question then is this: how do I retrieve a pointer to a value in a struct, rather than the actual value?

If it helps at all, I've included some of the code below. Pardon the simple syntax, it's from an editor I'm working on.

Code: Select all

// View the next level object in the NodeArray
script LevelEditor_Geom_NextLevelObject
    KillSpawnedScript name = LevelEditor_Geom_HighlightObject
    -> last_node : Unhide
    tmp_na_index = node_array_index
    loop
        change node_array_index = ( -> tmp_na_index + int:1 )
       if GetElement NodeArray Index = node_array_index
            if StructureContains structure = -> Element Class

                geom_cur_node = ( -> Element . Class )
                geom_cur_pos = ( -> Element . Pos )
                geom_cur_name = ( -> Element . Name )

                if ( -> geom_cur_node = LevelGeometry )
                    LevelEditor_Geom_MoveCursor pos = -> geom_cur_pos
                    change last_node = -> geom_cur_name
                    SpawnScript LevelEditor_Geom_HighlightObject params = [ name = -> geom_cur_name ]
                    exitloop
                endif

            endif
        else
            change node_array_index = int:0
            exitloop
       endif
        //wait int:1 gameframe
    endloop
endscript

// Make the currently selected object blink
script LevelEditor_Geom_HighlightObject
    if GotParam name
       loop
       -> name : Hide
       wait int:30 frames
       -> name : unhide
       wait int:30 frames
       endloop
    else
        create_console_message text = "No object name"
    endif
endscript


In this format, -> is used to refer to local variables/parameters. Also, currently LevelEditor_Geom_HighlightObject is making the skater blink :) I think because I'm passing a checksum rather than an object name/pointer, it defaults to the skater. If I explicitly set geom_cur_name in the code, for instance -> geom_cur_name = floor (bottom of the pool in Manhattan), it works fine.

Return to “THUG modding”

Who is online

Users browsing this forum: No registered users and 18 guests