Quantcast
Jump to content
Search In
  • More options...
Find results that contain...
Find results in...
    1. Welcome to GTAForums!

    1. Red Dead Redemption 2

      1. PC
      2. Gameplay
      3. Missions
      4. Help & Support
    2. Red Dead Online

      1. Gameplay
      2. Find Lobbies & Outlaws
      3. Help & Support
      4. Frontier Pursuits
    1. Crews & Posses

      1. Recruitment
    2. Events

    1. GTA Online

      1. Diamond Casino & Resort
      2. DLC
      3. Find Lobbies & Players
      4. Guides & Strategies
      5. Vehicles
      6. Content Creator
      7. Help & Support
    2. Grand Theft Auto Series

    3. GTA 6

    4. GTA V

      1. PC
      2. Guides & Strategies
      3. Help & Support
    5. GTA IV

      1. Episodes from Liberty City
      2. Multiplayer
      3. Guides & Strategies
      4. Help & Support
      5. GTA IV Mods
    6. GTA Chinatown Wars

    7. GTA Vice City Stories

    8. GTA Liberty City Stories

    9. GTA San Andreas

      1. Guides & Strategies
      2. Help & Support
      3. GTA SA Mods
    10. GTA Vice City

      1. Guides & Strategies
      2. Help & Support
      3. GTA VC Mods
    11. GTA III

      1. Guides & Strategies
      2. Help & Support
      3. GTA III Mods
    12. Top Down Games

      1. GTA Advance
      2. GTA 2
      3. GTA
    13. Wiki

      1. Merchandising
    1. GTA Modding

      1. GTA V
      2. GTA IV
      3. GTA III, VC & SA
      4. Tutorials
    2. Mod Showroom

      1. Scripts & Plugins
      2. Maps
      3. Total Conversions
      4. Vehicles
      5. Textures
      6. Characters
      7. Tools
      8. Other
      9. Workshop
    3. Featured Mods

      1. DYOM
      2. OpenIV
      3. GTA: Underground
      4. GTA: Liberty City
      5. GTA: State of Liberty
    1. Red Dead Redemption

    2. Rockstar Games

    1. Off-Topic

      1. General Chat
      2. Gaming
      3. Technology
      4. Programming
      5. Movies & TV
      6. Music
      7. Sports
      8. Vehicles
    2. Expression

      1. Graphics / Visual Arts
      2. GFX Requests & Tutorials
      3. Writers' Discussion
      4. Debates & Discussion
    1. News

    2. Forum Support

    3. Site Suggestions

Knowledge Novice

Need help with SCM mod please

Recommended Posts

Knowledge Novice

 

In your example in the Wanted section, your using an "if 1" with only one condition listed.

I see that now, thanks for pointing it out.

 

In the :Wanted label, you may want to separate the player_defined check out eg.:

When I changed my code to seperate my Player_Defined check from the Wanted_level >0 check I forgot to change the number of conditions.

 

 

Personally, I would use a separate varible for the "flag check" and one for the car.

This was tested, but I didn't even realise that I used the same variable for the flag_check AND the car. Looking at it now I could kick myself for making such a simple mistake, especially after testing it and still not catching my error.

 

 

Stay away from gosubs without returns; use jumps instead.

Until writing this I'd never used gosubs before and only knew that they were similar to jumps. Thanks for the advice.

 

 

You CAN use other "Special Actor" skins, but you have to load the models first. In your last bit of code, you're using "load_requested_models" without actually requesting anything to be loaded.

I saw this in another code while searching for info and just imitated it. Thanks for clearing that up.

 

 

Hope this helps.

Very much. If I didn't learn from my most simple mistakes I'd never get anywhere. Thanks ceedj. colgate.gif

 

One more question. Locals are thread_specific right? For example, if I added two new threads to my scm and used [email protected] in both of them, there wouldn't be a conflict, right?

Share this post


Link to post
Share on other sites
Knowledge Novice

***DOUBLE POST***

Edited by Knowledge Novice

Share this post


Link to post
Share on other sites
ceedj

No problem; glad I could help.

 

RE: gosubs. This is a very BASIC-like (not insulting, I'm talking about the programming language biggrin.gif ) opcode that works like this (puesdo code):

 

My Label

Do a command

gosub Subroutine 1

Do another command

Continue with code

 

Subroutine 1

Do commands here

return

 

It DOES work like a jump, but using return with it will take it back to the place it started from and continue on from there.

 

And yes, locals are thread specific; globals are just that - global to the entire script.

Edited by ceedj

Share this post


Link to post
Share on other sites
Bigun

 

4) ALWAYS use a wait before "if" statements at the beginning of a label (you shouldn't need more than one for each group).

To clarify...you only need a wait for loops. You don't need to add a wait to every if check at all (actually it's both a waste of space and a bit risky since player could get undefined etc in that waiting time), despite R* sometimes doing it in original code.

So this is correct:

 

:Skin1;;NO wait here00D6: if  00039:    [email protected] ==  0;; integer values004D: jump_if_false ££Skin20006:  [email protected] =  1;; integer values0352: set_actor $PLAYER_ACTOR skin_to "PLAYER2"0050: gosub ££Refresh;;jump!:Skin2;;NO wait here00D6: if  00039:    [email protected] ==  1;; integer values004D: jump_if_false ££Skin30006:  [email protected] =  2;; integer values0352: set_actor $PLAYER_ACTOR skin_to "PLAYER3"0050: gosub ££Refresh;;jump!

 

 

Since the labels do NOT make any (separate/new) loop, you don't need a wait there. They WILL get repeated, but in the same main loop starting at label :Wanted (which DOES MISS A WAIT!).

 

(This isn't correct either [psuedo-code])

 

:Labelwait 1000if 0player definedjf Labelwait 0;;<-incorrectif 0NOT player drivingjf SomeLabelwait 0;;<-incorrectif 0key_pressed Xjf Labeldo_stuff:SomeLabeldo_stuff

 

Share this post


Link to post
Share on other sites
random_download

Just to clarify on the need for waits. A wait opcode tells the game engine to process other things for the set amount of time. If you have an infinite loop with no waits, the game will crash because it never gets to escape the loop and update what is on the screen. However, you can loop without a wait provided that you can "escape". An example of this is:

 

:[email protected] += 1if [email protected] >= 5jump_if_false ££label

 

You have to be careful though, as sometimes it may look like the loop will escape, but in reality it requires things other than your script to be processed to escape e.g.:

 

:labelif 0player $PLAYER_CHAR drivingjump_if_false ££label

 

In that example, the loop will never escape, as the game will say the player is not driving, and loop back and continue doing this without a pause to process keys being pressed to make the player get in a car. This means that the player will never actually get in a car, and so you will get an infinite loop.

Share this post


Link to post
Share on other sites
Knowledge Novice

I've been trying to follow everyone's advice as closely as possible and hopefully I've corrected all the mistakes that were pointed out to me. I was about to start adding Special Actor Skins to my code, but while editing out the errors in my code I hit a snag.

 

You CAN use other "Special Actor" skins, but you have to load the models first. In your last bit of code, you're using "load_requested_models" without actually requesting anything to be loaded.

Following this advice I removed my load_requested_models command, but once this is done the game crashes any time I do something that would cause me to get a wanted level. (example: Attacking a cop or trying to car jack a cop) Looking at the code now it seems to make sense to only load_requested_models once I've actually requested a model, but removing this command seems to be causing a problem.

 

Current code:

 

:NameIt03A4: name thread "Schizo":Wanted0001: wait  50 ms00D6: if  00256:   player $PLAYER_CHAR defined004D: jump_if_false ££Wanted00D6: if  0  010F:   player $PLAYER_CHAR wanted level >  0004D: jump_if_false ££Wanted:Skin100D6: if  00039:    [email protected] ==  0;; integer values004D: jump_if_false ££Skin20006:  [email protected] =  1;; integer values0352: set_actor $PLAYER_ACTOR skin_to "PLAYER2"0002: jump ££Refresh:Skin200D6: if  00039:    [email protected] ==  1;; integer values004D: jump_if_false ££Skin30006:  [email protected] =  2;; integer values0352: set_actor $PLAYER_ACTOR skin_to "PLAYER3"0002: jump ££Refresh                                              :Skin30006:  [email protected] =  0;; integer values0352: set_actor $PLAYER_ACTOR skin_to "PLAYER4"                         :Refresh038B: load_requested_models0353: refresh_actor $PLAYER_ACTOR0110: clear player $PLAYER_CHAR wanted level 00D6: if  0   00E0:   player $PLAYER_CHAR driving004D: jump_if_false ££Wanted03C1: [email protected] = player $PLAYER_CHAR car0369: put player $PLAYER_CHAR in car [email protected]: remove references to car [email protected]  0002: jump ££Wanted

 

Share this post


Link to post
Share on other sites
Knowledge Novice

I've been messing around with Special Actor skins. As far as I can tell, leaving the load_requested_models command in place hasn't caused any conflicts in the game. This would be good because, by following the examples in the Long Night Mod (by The Fighting Hellfish) it seems I should initiate the skin change and then give the command load_requested_models. In this next piece I've just added on to the last script that I posted. I've added more skins for the Player_Char to change to and I've also added an On/Off option.

 

What it does: Anytime your wanted level registers one star or more your character automatically changes appearance (different clothes or different character skin). Your wanted level is also cleared back to 0. **This can be turned On/Off by pressing Forward+Crouch. A sound will let you know that the function has been changed. (2 chimes for On, 3 for Off)

 

Known problems: When car jacking a cop the Player_char occasionally gets stuck (not frozen) in place just outside of the car. This seems to happen most when entering the car from the passanger side while cop tries to re-enter the driver side. Character is still animated but is unable to move from that spot and game must be restarted.

 

Add to Create_threads

 

004F: create_thread ££NameIt

 

 

 

:NameIt03A4: name thread "Schizo":On/Off0001: wait  250 ms   00D6: if  0         0256:   player $PLAYER_CHAR defined004D: jump_if_false ££On/Off00D6: if  21  80E1:   NOT   key_pressed  0  18 ;; Crouch key80E1:   NOT   key_pressed  0  8 ;; Walk forward key004D: jump_if_false ££Off 00D6: if  1                0039:    [email protected] ==  0 ;; integer values 010F:   player $PLAYER_CHAR wanted level >  0004D: jump_if_false ££On/Off :Skin100D6: if  00039:    [email protected] ==  0 ;; integer values004D: jump_if_false ££Skin20006:  [email protected] =  1 ;; integer values0352: set_actor $PLAYER_ACTOR skin_to "PLAYER2"0002: jump ££Refresh :Skin200D6: if  00039:    [email protected] ==  1 ;; integer values004D: jump_if_false ££Skin30006:  [email protected] =  2 ;; integer values0352: set_actor $PLAYER_ACTOR skin_to "PLAYER3"0002: jump ££Refresh:Skin300D6: if  00039:    [email protected] ==  2 ;; integer values004D: jump_if_false ££Skin40006:  [email protected] =  3 ;; integer values0352: set_actor $PLAYER_ACTOR skin_to "PLAYER4"0002: jump ££Refresh:Skin400D6: if  00039:    [email protected] ==  3 ;; integer values004D: jump_if_false ££Skin50006:  [email protected] =  4 ;; integer values0352: set_actor $PLAYER_ACTOR skin_to "IGBUDDY"0002: jump ££Refresh:Skin500D6: if  00039:    [email protected] ==  4 ;; integer values004D: jump_if_false ££Skin60006:  [email protected] =  5 ;; integer values0352: set_actor $PLAYER_ACTOR skin_to "IGMIKE"0002: jump ££Refresh:Skin600D6: if  00039:    [email protected] ==  5 ;; integer values004D: jump_if_false ££Skin70006:  [email protected] =  6 ;; integer values0352: set_actor $PLAYER_ACTOR skin_to "IGMIKE2"0002: jump ££Refresh:Skin700D6: if  00039:    [email protected] ==  6 ;; integer values004D: jump_if_false ££Skin80006:  [email protected] =  7 ;; integer values0352: set_actor $PLAYER_ACTOR skin_to "IGHLARY"0002: jump ££Refresh:Skin800D6: if  00039:    [email protected] ==  7 ;; integer values004D: jump_if_false ££Skin90006:  [email protected] =  8 ;; integer values0352: set_actor $PLAYER_ACTOR skin_to "IGDIAZ"0002: jump ££Refresh:Skin900D6: if  00039:    [email protected] ==  8 ;; integer values004D: jump_if_false ££Skin100006:  [email protected] =  9 ;; integer values0352: set_actor $PLAYER_ACTOR skin_to "IGPHIL"0002: jump ££Refresh:Skin1000D6: if  00039:    [email protected] ==  9 ;; integer values004D: jump_if_false ££Skin110006:  [email protected] =  10 ;; integer values0352: set_actor $PLAYER_ACTOR skin_to "IGPHIL2"0002: jump ££Refresh  :Skin1100D6: if  00039:    [email protected] ==  10 ;; integer values004D: jump_if_false ££Skin120006:  [email protected] =  11 ;; integer values0352: set_actor $PLAYER_ACTOR skin_to "IGGONZ"0002: jump ££Refresh:Skin1200D6: if  00039:    [email protected] ==  11 ;; integer values004D: jump_if_false ££Skin130006:  [email protected] =  12 ;; integer values0352: set_actor $PLAYER_ACTOR skin_to "IGMERC"0002: jump ££Refresh:Skin130006:  [email protected] =  0 ;; integer values0352: set_actor $PLAYER_ACTOR skin_to "IGPERCY":Refresh038B: load_requested_models0353: refresh_actor $PLAYER_ACTOR0110: clear player $PLAYER_CHAR wanted level 00D6: if  0   00E0:   player $PLAYER_CHAR driving004D: jump_if_false ££On/Off03C1: [email protected] = player $PLAYER_CHAR car0369: put player $PLAYER_CHAR in car [email protected]: remove references to car [email protected] 0002: jump ££On/Off:Off00D6: if  0  0039:    [email protected] ==  0 ;; integer values004D: jump_if_false ££On0006:  [email protected] =  1 ;; integer values018C: play_sound  10 at  0  0  00001: wait 200 ms018C: play_sound  10 at  0  0  00001: wait 200 ms018C: play_sound  10 at  0  0  0:Loop10001: wait  150 ms00D6: if  1 80E1:   NOT   key_pressed  0  18  80E1:   NOT   key_pressed  0  8004D: jump_if_false ££Loop10002: jump ££On/Off:On0006:  [email protected] =  0 ;; integer values018C: play_sound  1 at  0  0  00001: wait  200 ms018C: play_sound  1 at  0.0  0.0  0.0:Loop20001: wait  150 ms     00D6: if  1          80E1:   NOT   key_pressed  0  18  80E1:   NOT   key_pressed  0  8004D: jump_if_false ££Loop20002: jump ££On/Off

 

 

This got a little lengthy so I won't be too surprised when you guys find any mistakes.

 

Question: I came across a mod that used a Repair_car command. I thought I had copied the info from that post but can't seem to find it. Is there a Repair_car command (as in repairing the visual damage to car body) for Vice City or would that be more likely to have been code for SA?

Edited by Knowledge Novice

Share this post


Link to post
Share on other sites
ceedj

The only quibble I would have is this:

 

018C: play_sound  10 at  0  0  0

 

When it should be

 

018C: play_sound  10 at  0.0  0.0  0.0

 

You kind of intermingle the two. While it might not cause any problems, you should get in the habit of using floats where there should be floats.

 

Otherwise, congrats! smile.gif

Share this post


Link to post
Share on other sites
Demarest
I agree that they should not be mixed. However, a 0 is a 0 in both formats. So if the game accepts it, using a 0 instead of 0.0 will save 3 bytes per occurance in VC.

Share this post


Link to post
Share on other sites
random_download
I agree that they should not be mixed. However, a 0 is a 0 in both formats. So if the game accepts it, using a 0 instead of 0.0 will save 3 bytes per occurance in VC.

wow.gif I've never thought of that before. That would work though, as the exe does:

 

movsx   eax, bl

 

When reading an 8-bit integer. If you really wanted to save space I guess you could find out what the values "00 00 00 00" through to "FF 00 00 00" were as floats and use 8-bit integers instead, and the same applies for 16-bit integers.

Share this post


Link to post
Share on other sites
Demarest
Good point. No idea why I've only limited that technique to 0. But yeah, for lines that just set to a particular value, so long as it was within -32768 and 32767, you could save space by instead setting it to its int equivalent.

Share this post


Link to post
Share on other sites
Knowledge Novice

I recently came across this opcode:

 

0548:   unknown_player $PLAYER_CHAR near_peds #HNA or #HNB radius  10.0  10.0  10.0

 

I've used this to alert me when I have a wanted level while driving and an officer is near so I'll have a little warning and can either get out or drive away before he busts me.

 

:NameIt03A4: name_thread "NearLaw":PoPo0001: wait  500 ms00D6: if  00256:   player $PLAYER_CHAR defined004D: jump_if_false ££PoPo00D6: if  200E0:   player $PLAYER_CHAR driving010F:   player $PLAYER_CHAR wanted level >  00548:   unknown player $PLAYER_CHAR near peds #COP or #SWAT radius  12.0  12.0  12.0004D: jump_if_false ££PoPo018C: play_sound  1 at  0  0  00001: wait  800 ms 018C: play_sound  1 at  0  0  00001: wait  800 ms0002: jump ££PoPo

 

I've been looking through the original and modded scm's trying to find more examples of the use of this opcode and it seems it's used with specific characters created for certain missions. I was wondering if there may be a way to set a variable to a ped group and found this

 

03DF: all random peds $5E6

 

The only example that I've found for the use of this seems to be to set radar_icons/models during a Rampage. Is there any way to set a variable to certain ped_groups (ex. [email protected] = #COP) so that those within the set radius can be manipulated (ex. 009B: destroy actor instantly $355 or 0326: $1AA1 = create actor [email protected] fire) or is this not possible? I got the idea from the "Destroy all cars" cheat for GTA3 and was curious about targeting a more specific group.

 

P.S.

 

Good point. No idea why I've only limited that technique to 0. But yeah, for lines that just set to a particular value, so long as it was within -32768 and 32767, you could save space by instead setting it to its int equivalent.

I may have misunderstood this statement, but I took it to mean that in my "near peds #cop or #swat" line above for example, that I could have used "radius 12 12 12" instead of "radius 12.0 12.0 12.0". But when I remove the ".0's" from the line it no longer seems to work. As I said above I may have misunderstood. Just thought I'd mention it. monocle.gif

Share this post


Link to post
Share on other sites
Demarest

I've used this to alert me when I have a wanted level while driving and an officer is near so I'll have a little warning and can either get out or drive away before he busts me.
Cool idea. Does it work? Because I've noticed that auto-generated cops amongst random peds seem to behave under different rules, including things like the inability to capture them as random peds. At any rate, if that's what it does, I'd personally shoot for a wait shorter than 500.

 

 

Is there any way to set a variable to certain ped_groups (ex. [email protected] = #COP)
As explained in the readme, the datatype # is just an indication that the MB is to write a number associated with that name as its listed amongst cars, objects, or in this case, peds. So yes, you can always set a var to #anything and it will operate as you expect it to.

 

 

so that those within the set radius can be manipulated (ex. 009B: destroy actor instantly $355
009B looks for an actor handle, not a ped modelID. And since I mentioned above that one such anomoly that surrounds automatic ped cops is the inability to capture them, you won't be able to write a code that erases all cops in the vicinity. Which is really too bad because that would be cool.

 

 

0326: $1AA1 = create actor  [email protected] fire) or is this not possible?
No, but only because again, that opcode looks for an actor handle, not a ped modelID. In case the difference isn't clear, consider
009A:  2892?? = create_actor  4? #PGA at  [email protected]  [email protected]  [email protected]

The 2892?? is the actor's handle. It's what you would use to refer to THAT actor specifically. In your line of thinking, you'd set some var to #PGA and then use that var in the 3rd parameter's position there. But the var would still contain just a modelID number.

 

 

I got the idea from the "Destroy all cars" cheat for GTA3 and was curious about targeting a more specific group.
I THINK the clear_area command has a parameter that indicates if the command is to handle cars or peds. If you continuously issued such a comman with your location as ground zero and only targeted peds, you'd still be able to find yourself a getaway car and MAYBE clear out any nearby foot soldiers. I've not tried it though, so I might be wrong about that.

 

 

I may have misunderstood this statement, but I took it to mean that in my "near peds #cop or #swat" line above for example, that I could have used "radius  12  12  12" instead of "radius  12.0  12.0  12.0". But when I remove the ".0's" from the line it no longer seems to work. As I said above I may have misunderstood. Just thought I'd mention it.
The only thing you misunderstood is the correlation between floats and ints. And I'll be honest when I say I don't fully understand it. The bottom line is that there's no direct correlation in terms of just dropping the decimal will leave you with an identical integer. This is ONLY true of 0 because no value and no value are the same on any scale. For example here, float 12 is 1094713344 as an integer. And since that integer takes 4 bytes to express, it's no different from saying 12.0, which also takes up 4 bytes. FOR THE MOST PART, that technique we were describing really is more trouble than it's worth, except with 0's and even then, only if an opcode will continue to function with an int where a float is expected. You can for the most part ignore it. Plus as ceedj pointed out and I concurred, it's best that we don't get you hooked on incorrect habits like that. You'll find that in SCM'ing, compression only really matters in SA as the original game is already so close to the ceiling.

 

For those interested in the potential for space saving ints in place of floats, it should be noted that GTA3 floats were 2 bytes in length and therfore only 0 will save you any space at all.

Share this post


Link to post
Share on other sites
Knowledge Novice

 

Cool idea. Does it work?

Yep, it works. I didn't realize there was such a thing, but there it is.

 

At any rate, if that's what it does, I'd personally shoot for a wait shorter than 500.

In shorter codes like this I tend to want to use wait 50 ms, but I sometimes use a longer wait just to be safe (so as not to overload the game).

 

 

I THINK the clear_area command has a parameter that indicates if the command is to handle cars or peds.

 

042B: clear peds from cube  316.5  207.966  9.23  335.8277  190.5508  11.3988

 

Here's the one I used. I'm unfamiliar with this so my code may be a bit off.

 

:NameIt03A4: name_thread "GoAway":PoPo0001: wait  250 ms00D6: if  00256:   player $PLAYER_CHAR defined004D: jump_if_false ££PoPo00D6: if  1010F:   player $PLAYER_CHAR wanted level >  00548:   unknown player $PLAYER_CHAR near peds #COP or #SWAT radius  15.0  15.0  15.0004D: jump_if_false ££PoPo04C4: create_coordinate [email protected]  [email protected]  [email protected] from_actor $PLAYER_ACTOR offset  15.0  15.0  15.004C4: create coordinate [email protected] [email protected] [email protected] from actor $PLAYER_ACTOR offset  -15.0  -15.0  -15.0042B: clear_peds_from_cube  [email protected]  [email protected]  [email protected]  [email protected] [email protected] [email protected]: jump ££PoPo

 

First off I'm not sure that I needed to use the create_coordinate comand twice. I did though because when I used it just once some of the peds wouldn't disapear. Due to this I thought I may need to give opposite coordinates from the first to catch the inbetween, but it seems to work this way where as it didn't before.

 

 

Share this post


Link to post
Share on other sites
Demarest
In shorter codes like this I tend to want to use wait 50 ms, but I sometimes use a longer wait just to be safe (so as not to overload the game).

Oh I could tell you stories about overloading the game. It's more resilient than you might think. If I ever get around to releasing Windshield, you'll see one thread with one wait 0 that has to repeatedly process a LOT of data. Despite only having the one wait, it work great and is well over 900 lines long. You'll know you broke the game when you hear it crash wink.gif

 

Everything else looks good. Yes I think you need to get coords twice. You're sniffing for a sphere, but acting upon a cube. Not that that hurts anything, just pointing it out.

Share this post


Link to post
Share on other sites
Seemann

 

GTA3 floats were 2 bytes in length and therfore only 0 will save you any space at all.

 

Are you sure? Speaking in terms of programming, GTA3 generally has no floats. Instead of them Gta3 SCM uses 16bit integer numbers that should be divided by 16 to get float value. For example: 2.0 is represented in scm as number 32.

 

So, knowing that fact, we can increase free space by replacing all floats in range 0.0 .. 16.0 with their integer equivalent:

 

0.0 -> 0

1.0 -> 16

2.0 -> 32

3.0 -> 48

 

that saves one byte per float.

 

Although, I do not know how the game will behave itself if there is data type 04 (8-bit int) instead of 05 one ("float")

Edited by Seemann

Share this post


Link to post
Share on other sites
Knowledge Novice

 

Everything else looks good. Yes I think you need to get coords twice.

Great. The second coord was just a shot in the dark. I'm glad I was able to get it right.

 

I'm a bit low on inspiration at the moment, but a couple of things have come to mind. I've made small codes that included setting player_char health to 100 after being injured. Although the end result is pretty much the same, I thought it would be kind of cool to make the char's health regenerate gradually.

 

:NameIt03A4: name_thread "HEAL":Wounded0001: wait  50 ms00D6: if  0  0256:   player $PLAYER_CHAR defined004D: jump_if_false ££Wounded00D6: if  0  8183:   NOT   player $PLAYER_CHAR health >  99004D: jump_if_false ££Wounded0225: [email protected] = player $PLAYER_CHAR health0006:  [email protected] =  1 ;; integer values005A: [email protected] += [email protected] ;; integer values (never used in VC or GTA 3)0222: set player $PLAYER_CHAR health to  [email protected]: wait  1000 ms0002: jump ££Wounded

 

 

Then I remembered something from the Final Fantasy series (an RPG) to where a character would gain money equal to the amount of life lost.

 

:NameIt03A4: name_thread "HEAL+":Skin_Cash0001: wait  50 ms00D6: if  0  0256:   player $PLAYER_CHAR defined004D: jump_if_false ££Skin_Cash0006:  [email protected] =  1 ;; integer values0006:  [email protected] =  100 ;; integer values:Wounded0001: wait  1000 ms 00D6: if  0  0256:   player $PLAYER_CHAR defined004D: jump_if_false ££Skin_Cash0225: [email protected] = player $PLAYER_CHAR health00D6: if  0  8183:   NOT   player $PLAYER_CHAR health >  99004D: jump_if_false ££Skin_Cash0062: [email protected] -= [email protected] ;; integer values (never used in VC or GTA 3)0109: player $PLAYER_CHAR money += [email protected]: [email protected] += [email protected] ;; integer values (never used in VC or GTA 3)0006:  [email protected] =  [email protected] ;; integer values0222: set player $PLAYER_CHAR health to  [email protected]: jump ££Wounded

 

I had a bit more trouble with this one. It took some rearranging to get it right, but I think I've got it smoothed out. Just like the "HEAL" thread, the "HEAL+" thread gradually regenerates the char's health but also gives an amount of money equal to the damage recieved. Actually it would probably make more sense to TAKE money in exchange for the gained life points, but you get the picture.

 

When I first started this thread of posts I had all but submitted a "mod" (or so I called it) that didn't even work. I was so anxious to contribute that I didn't realize that I had no idea what I was actually doing. blush.gif Thinking back I'm glad I came here for help. Otherwise I would have crashed and burned.

 

Share this post


Link to post
Share on other sites
Demarest

GTA3 floats were 2 bytes in length and therfore only 0 will save you any space at all.

 

Are you sure?

floats = 4 bytes (or 2 in gta3)
Where I come from, that's about as sure as it gets. I've NEVER seen CyQ wrong and lord knows he had the means of determining such things.

 

@KN: Rather than setting [email protected] to 1 and then adding it to [email protected], why not just increment [email protected] by 1? Furthermore, in HEAL, I think it would be the same thing to have the initial wait be 1000 and obliterate the 2nd wait altogether. Or if you REALLY wanted it to be as realtime as possible, use a local timer to measure when it's been a real second.

Share this post


Link to post
Share on other sites
Knowledge Novice

Rather than setting [email protected] to 1 and then adding it to [email protected], why not just increment [email protected] by 1?

Good call. That'll save room and trouble.

 

Furthermore, in HEAL, I think it would be the same thing to have the initial wait be 1000 and obliterate the 2nd wait altogether.

Works great. At this point, that's something I should have seen. Thanks.

 

Or if you REALLY wanted it to be as realtime as possible, use a local timer to measure when it's been a real second.

Ok. This I'm having trouble with. The Readme says "These variables can be set using the create_thread command", but if the locals were set in another thread how would they work in my Heal+ thread? I've looked through the Readme and searched the forums for "local timer", but with the info I've found I still don't quite get it. In fact I wouldn't be so quick to seek help yet if it weren't for the fact that out of the last 5 times that my game froze, I had to reboot my computer 4 times. Just getting a bit frustrated. At this point I feel like either moving on to something else or throwing my PC out the window. cryani.gif I have no idea how far off it is, but here's what I used the last time I crashed.

 

 

:NameIt03A4: name_thread "HEAL+":Skin_Cash0001: wait  50 ms00D6: if  0  0256:   player $PLAYER_CHAR defined004D: jump_if_false ££Skin_Cash0006:  [email protected] =  100;; integer values0079: [email protected] += unknown inaccurate float timer 1.0;; floating-point (never used in VC or GTA 3):Wounded   00D6: if  0  0256:   player $PLAYER_CHAR defined004D: jump_if_false ££Skin_Cash0225: [email protected] = player $PLAYER_CHAR health00D6: if  0  8183:   NOT   player $PLAYER_CHAR health >  99004D: jump_if_false ££Skin_Cash00D6: if  0002B:   999 >= [email protected];; integer values (never used in VC or GTA 3)004D: jump_if_false ££Wounded0006:  [email protected] =  0;; integer values0062: [email protected] -= [email protected];; integer values (never used in VC or GTA 3)0109: player $PLAYER_CHAR money += [email protected]:  [email protected] +=  1;; integer values0006:  [email protected] =  [email protected];; integer values0222: set player $PLAYER_CHAR health to  [email protected]: jump ££Wounded

 

 

P.S. After reading through several posts I've noticed that the "white" letters put a bit of a strain on the eyes. Maybe I'll start using something a little less bright. Don't wantcha to go blind reading through my endless stream of "help me" posts.

Edited by Knowledge Novice

Share this post


Link to post
Share on other sites
Demarest

I'm going to make this post two part since these are two DIFFERENT items that I think you're confusing as the same. As for local timers (part 1), I'm sorry the readme doesn't explain this well. The forums do however. I don't know if it's in a pinned topic, but I've written on the subject a few times recently. Anyways, here goes:

 

Part 1: In GTA3 and VC, the local timers are [email protected] and [email protected] In SA, they are @32 and @33. These locals are increased as time elapses in milliseconds. So set it to 0 and 500 milliseconds from now, it's going to equal approximately 500. There are several reasons this can be useful, most of which involve your code doing something WHILE that time elapses. Something a simple wait cannot do. I only mentioned it here because your code waits more than 1000 (as it had 2 waits) and THEN does some work and then waits another more than 1000. Well in addition to the more than 1000, the time it spends doing work will also delay it. Not much from one second to the next, but it adds up. And more importantly, will be translated differently on different machines (i.e. slower machines will take longer to process the commands). All negligible, but it's still a way to improve! Here's how I'd change your first offering of HEAL to make it use a local timer

:NameIt03A4: name_thread "HEAL":Wounded0001: wait  50 ms00D6: if  0  0256:   player $PLAYER_CHAR defined004D: jump_if_false ££Wounded00D6: if  10019:    [email protected] >  9998183:   NOT   player $PLAYER_CHAR health >  99004D: jump_if_false ££Wounded0006:  [email protected] =  00225:  [email protected] = player $PLAYER_CHAR health000A:  [email protected] +=  10222: set player $PLAYER_CHAR health to  [email protected]: jump ££Wounded

Granted, this particular snippet is a bad example, since there's very few commands to process. Nevertheless, you can see how resetting the local timer FIRST THING will help you get as close to exactly 1 second as possible. However, it should also be noted that now, your thread's wait time comes under scrutiny once again. The smaller it is, the more likely your mod will increment as true to 1 second as possible. For example, if you used a wait 900, after the first one, [email protected] will be just over 900 in value. Greater than 999? Nope, so let's wait 900 once more. Greater than 999? Yeah, but it's like 1800+, well beyond your target. Of course if you used a wait 0 and used this local timer approach, you'd be as spot on on one second as possible. What you choose is a matter of taste. Any questions about any of that, feel free to ask. As to when to use local timers, it comes with experience. You'll know when it's time to rely upon them.

 

Part 2: The create_thread command is the only opcode in the game that looks for an undetermined amount of parameters. One is required: the starting label (offset). Use just the starting label and the thread you are creating will have a blank slate. That is to say that each and every local var associated with it will start off equal to 0. BUT you can give the create_thread command more parameters. If you give it more, each parameter you give it is essentially kickstarting that thread with its local vars having values already assigned to them. Unfortunately, the best example I can give somebody not yet modding SA isn't terribly useful, but an example nonetheless.

 

In original code, you'll find lots of places in missions where the game wants to put you somewhere. But if it's at a time when it doesn't know if you're in a car or not, it will check. If you are, it will take you out of it and put you at the coords. Since you're on VC right now, here's an example straight out of VC's original code

00D6: if  0?00E0:   player $PLAYER_CHAR driving004D: jump_if_false £Label04208C012A: put_player $PLAYER_CHAR at  433! -574.5!  9.6! and_remove_from_car0002: jump £Label0420A0:Label04208C0055: put_player $PLAYER_CHAR at  433! -574.5!  9.6!:Label0420A0

Sometimes, it will even be used for other actors. At one point, I was trying to compress the overall size of the code. So what I did was created a thread in MAIN with skeleton code resembling the above. It would've looked something like this

:UNIVERSALPUTACTOR00D6: if  0?00DF:   actor  [email protected] driving004D: jump_if_false ££UNIVERSALPUTACTOR20362: remove_actor  [email protected] from_car_and_place_at  [email protected]  [email protected]  [email protected]: jump ££UNIVERSALPUTACTOR3:UNIVERSALPUTACTOR200A1: put_actor  [email protected] at  [email protected]  [email protected]  [email protected]:UNIVERSALPUTACTOR3004E: end_thread

So now you're wondering "Okay, but @'s 0-3 have no value. This will crash the game." Enter the beauty in being able to pass a new thread values. If I have this code in MAIN, then I can replace each instance of my original code sample with the following

004F: create_thread ££UNIVERSALPUTACTOR $PLAYER_ACTOR  433! -574.5!  9.6!

THIS create_thread command has 5 parameters. The first is the label the new thread will begin at. The new thread's [email protected] will be set to $PLAYER_ACTOR, it's [email protected] will be set to 433! and so on. Again, not the best example, but should show you what it means for one thread to be able to pass a new thread values. This almost always has to do with the sake of compression (at least in terms of how R* implimented it) and can largely be ignored. However, should you ever choose to use it, that's how it works. Any questions, ask away.

 

 

When I first started this thread of posts I had all but submitted a "mod" (or so I called it) that didn't even work. I was so anxious to contribute that I didn't realize that I had no idea what I was actually doing. blush.gif  Thinking back I'm glad I came here for help. Otherwise I would have crashed and burned.
You said this earlier and I meant to comment on it. It's not just that you came here, but that you came here with the right attitude. You KNEW there was stuff to learn and you weren't afraid to learn it. You weren't afraid to admit you needed to learn it and you weren't afraid to get down and dirty and try things yourself to figure them out. All to your credit colgate.gif

Share this post


Link to post
Share on other sites
Seemann

 

Where I come from, that's about as sure as it gets. I've NEVER seen CyQ wrong and lord knows he had the means of determining such things.

I don't know a context this was written with, so I don't argue. But GTA3's floats aren't floats like those presented in programming (C++, for example). The smallest float value has 4 bytes of length (as in VC or SA). GTA3 operates with 16-bit integers. That IS the fact. But we call them "floats" because they mean floating-point values in source files and have specific data type (05).

Share this post


Link to post
Share on other sites
random_download
Although, I do not know how the game will behave itself if there is data type 04 (8-bit int) instead of 05 one ("float")

When the game reads an opcode, it collects the parameters and puts their values into memory before returning to the opcode procedure. So if you can get the correct value in memory via a different method it will make no difference. "01 00 00 00" obtained by a float is the same as "01 00 00 00" obtained by an 8-bit integer.

Share this post


Link to post
Share on other sites
Knowledge Novice

Part 1

Oh, ok. I knew from the Readme that [email protected] and [email protected] were used as local timers, but I was unsure exactly how to use them. I thought I needed to use a special opcode to set [email protected] to increase it's value before checking it to see if it had reached the desired amount. That's why I tried using

 

0079: [email protected] += unknown inaccurate float timer 1.0;; floating-point (never used in VC or GTA 3)

 

I was looking for a way to increase it's value to the desired amount.

 

So set it to 0 and 500 milliseconds from now, it's going to equal approximately 500.

But now I see that it starts at 0 and increases automatically.

 

There are several reasons this can be useful, most of which involve your code doing something WHILE that time elapses. Something a simple wait cannot do. I only mentioned it here because your code waits more than 1000 (as it had 2 waits) and THEN does some work and then waits another more than 1000.

I had also tried leaving out the Wait command since the timer (in my mind) would have done the same thing and been as close to one second as possible without any additional wait to add an extra delay. But now you've reminded me that, even if I don't need an additional delay, the wait command is necessary so that the code can carry out other functions while the desired value is accumulating. Same for the difference between using a local_timer opposed to JUST using a Wait. The local_timer in conjunction with a Wait 0 ms allows other things to be checked while the timer continues to increase, whereas ONLY using the wait command puts everything on hold until the wait command runs for it's alloted time.

 

Part 2

 

At one point, I was trying to compress the overall size of the code. So what I did was created a thread in MAIN with skeleton code resembling the above. It would've looked something like this

I believe I see what's happening here. By using

 

004F: create_thread ££UNIVERSALPUTACTOR $PLAYER_ACTOR  433! -574.5!  9.6!

 

you can fill in the coordinates multiple times in a thread without actually having to enter the values each time, only supplying the corresponding variables thereby saving space.

 

One question I would have on this. When using this method

 

The create_thread command is the only opcode in the game that looks for an undetermined amount of parameters.

 

004F: create_thread ££UNIVERSALPUTACTOR $PLAYER_ACTOR  433! -574.5!  9.6!

 

 

As far as coordinates it gives the actor's x,y,z. But what if I wanted to supply the actor's z_angle? Could I do this

 

004F: create_thread ££UNIVERSALPUTACTOR $PLAYER_ACTOR  433! -574.5!  9.6!  180!00A1: put_actor  [email protected] at  [email protected]  [email protected]  [email protected]: set actor [email protected] z angle to  [email protected]

 

 

Or would I need to do this

 

004F: create_thread ££UNIVERSALPUTACTOR $PLAYER_ACTOR  433! -574.5!  9.6!  00A1: put_actor  [email protected] at  [email protected]  [email protected]  [email protected]: set actor [email protected] z angle to  180!

 

 

 

 

 

You said this earlier and I meant to comment on it. It's not just that you came here, but that you came here with the right attitude. You KNEW there was stuff to learn and you weren't afraid to learn it. You weren't afraid to admit you needed to learn it and you weren't afraid to get down and dirty and try things yourself to figure them out. All to your credit

It takes desire and self determination, true enough. But without someone to help guide me when I get stuck in the mudhole known as confusion I'd mainly just end up down and dirty. Ha Ha. tounge.gif Much appreciation man. icon14.gif

 

 

 

Share this post


Link to post
Share on other sites
Bigun

Well, both codes will work (but of course as an example, the code below the create_thread is obviously a separate thread) - but you understand that the 2nd one defeats the purpose, right?

And IMO using a timer is unneeded here. It's good to know how to use it, but just isn't needed in this particular code IMO, a wait will do. It isn't critical if you're a few unknown ms off etc. yawn.gif

As said, timers are for RUNNING certain code WHILE waiting and expire after the time is up etc. For example something as this;

 

 

...0006: @32 = 0:Timer_Test2wait 999if 0NOT @32 > 9999jf Timer_Endplayer $player_char health += 10jump Timer_Test2:Timer_Endend_thread

 

 

The above psuedo-code example will increment the player's health by 10 every (~)second for the duration of (~)10 seconds total. After that, it will end_thread (of course it will need something in the beginning like keypress to activate to be used properly).

But if you didn't want it to stop you could just do

 

:label1wait 1000ifplayer definedjf label1player $player_char health = 100jump label1

 

No need for timers.

 

@Dem: Also about the increment_actor_armor (etc) opcode(s). I thought you mentioned it here too, suppose I got confused with another topic. Anyhow I'll plug this here if nobody minds. >_>

Yeah, it's not SET so to be used properly you'd have to use an if check, get the difference between current armor, etc. Not that it's hard, but shouldn't this [untested actually] workaround be easier/faster (takes less space too)

 

035E: set_player $PLAYER_CHAR armour += -999;set armor to 0. count on engine not to let it go negative anyway035E: set_player $PLAYER_CHAR armour +=  50;set exactly to 50

 

Edited by Bigun

Share this post


Link to post
Share on other sites
Knowledge Novice

I was confused about the extra parameters added to the create_thread command and probably didn't make a good example. I think I may understand better now but here's kind of what I had in mind:

 

@Bigun:In your example the player_char is teleported from a car or from on foot to preset coord's and it's present z_angle. I wanted to know if the z_angle could be preset in the create_thread to be used after being teleported (to look at a certain building, etc) yet do it in the most efficient way. I think this may best explain that part of my question.

 

This teleports the player_actor to the top of the front steps at Vercetti Mansion, player is facing the front door, and the camera is set behind the player. Here's how it would look:

 

004F: create_thread ££NameIt $PLAYER_ACTOR  -379.4463 -534.7212 17.28232  180.0

 

 

 

:NameIt03A4: name_thread "Put":UNIVERSALPUTACTOR0001: wait  20 ms00D6: if  2 0256:   player $PLAYER_ACTOR defined00E1:   key_pressed  0  13 ;;Camera00E1:   key_pressed  0  4  ;;Action/Radio004D: jump_if_false ££UNIVERSALPUTACTOR00D6: if  000DF:   actor  [email protected] driving004D: jump_if_false ££UNIVERSALPUTACTOR20362: remove_actor  [email protected] from_car_and_place_at  [email protected]  [email protected]  [email protected]: jump ££UNIVERSALPUTACTOR3:UNIVERSALPUTACTOR200A1: put_actor  [email protected] at  [email protected]  [email protected]  [email protected]:UNIVERSALPUTACTOR3 0173: set_actor $PLAYER_ACTOR z_angle_to  [email protected]: set camera directly behind player:Loop0001: wait  20 ms 00D6: if  100E1:   key_pressed  0  13 ;;Camera00E1:   key_pressed  0  4  ;;Action/Radio004D: jump_if_false ££UNIVERSALPUTACTOR0002: jump ££Loop

 

I do realize that SETTING the z_angle isn't necessary if all you want to do is change the player_actor's location, but setting it as I have above (to face the mansion when first appearing) won't cause any problems will it?

 

 

The above psuedo-code example will increment the player's health by 10 every (~)second for the duration of (~)10 seconds total. After that, it will end_thread

That's pretty cool. Thanks for the tips and if I'm still not clear on anything (even if I don't realize that I'm not) please clue me in. anuj_cop.gif

 

 

And IMO using a timer is unneeded here. It's good to know how to use it, but just isn't needed in this particular code IMO, a wait will do. It isn't critical if you're a few unknown ms off etc.

Ok. So I can just use a WAIT for a code that may run indefinitely or a TIMER for a shorter lived effect that expires after a preset time limit (like temporary immunities).

 

I also tried this:

 

:NameIt03A4: name_thread "TuffMan"   :Temp_Immune0001: wait  50 ms00D6: if  00256:   player $PLAYER_CHAR defined004D: jump_if_false ££Temp_Immune00D6: if  200E1:   key_pressed  0  16  ;;Sprint00E1:   key_pressed  0  19  ;;Look Behind80E0:   NOT   player $PLAYER_CHAR driving 004D: jump_if_false ££Temp_Immune0006:  [email protected] =  0 ;; integer values02AB: set actor  $PLAYER_ACTOR immunities  1  1  1  1  1018C: play_sound  1 at  0.0  0.0  0.00001: wait  250 ms 018C: play_sound  1 at  0.0  0.0  0.0:Temp_Immune20001: wait  0 ms00D6: if  00256:   player $PLAYER_CHAR defined004D: jump_if_false ££Non_Immune00D6: if  00019:    [email protected] >  19999 ;; integer values  004D: jump_if_false ££Temp_Immune20006:  [email protected] =  0 ;; integer values018C: play_sound  10 at  0.0  0.0  0.00001: wait  250 ms 018C: play_sound  10 at  0.0  0.0  0.00001: wait  250 ms 018C: play_sound  10 at  0.0  0.0  0.002AB: set actor  $PLAYER_ACTOR immunities  0  0  0  0  0:Recharge0001: wait  0 ms00D6: if  00256:   player $PLAYER_CHAR defined004D: jump_if_false ££Temp_Immune00D6: if  0  0019:    [email protected] >  119999 ;; integer values 004D: jump_if_false ££Recharge0002: jump ££Temp_Immune:Non_Immune02AB: set actor  $PLAYER_ACTOR immunities  0  0  0  0  00002: jump ££Temp_Immune

 

This (when not in car) plays sound and sets player immunities for 20 seconds. After 20 seconds immunities are removed and plays a sound. Then it has to Recharge for 2 minutes before it can be used again. Would it have been possible to get this same effect by using "set actor $PLAYER_ACTOR immunities 0 0 0 0 0" only once instead twice? Many flaws?

 

 

P.S.

What does IMO stand for? (Immediate Mission Objective?) monocle.gif

Share this post


Link to post
Share on other sites
random_download

 

004F: create_thread ££NameIt $PLAYER_ACTOR  -379.4463 -534.7212 17.28232  180.0

 

 

 

:NameIt03A4: name_thread "Put":UNIVERSALPUTACTOR0001: wait  20 ms00D6: if  2 0256:   player $PLAYER_ACTOR defined00E1:   key_pressed  0  13;;Camera00E1:   key_pressed  0  4 ;;Action/Radio004D: jump_if_false ££UNIVERSALPUTACTOR00D6: if  000DF:   actor  [email protected] driving004D: jump_if_false ££UNIVERSALPUTACTOR20362: remove_actor  [email protected] from_car_and_place_at  [email protected]  [email protected]  [email protected]: jump ££UNIVERSALPUTACTOR3:UNIVERSALPUTACTOR200A1: put_actor  [email protected] at  [email protected]  [email protected]  [email protected]:UNIVERSALPUTACTOR3 0173: set_actor $PLAYER_ACTOR z_angle_to  [email protected]: set camera directly behind player:Loop0001: wait  20 ms 00D6: if  100E1:   key_pressed  0  13;;Camera00E1:   key_pressed  0  4 ;;Action/Radio004D: jump_if_false ££UNIVERSALPUTACTOR0002: jump ££Loop

 

I do realize that SETTING the z_angle isn't necessary if all you want to do is change the player_actor's location, but setting it as I have above (to face the mansion when first appearing) won't cause any problems will it?

That code is fine, you can have as many parameters on the create_thraed opcode as you like (until you go past the last local var [email protected]). Although "0173: set_actor $PLAYER_ACTOR z_angle_to [email protected]" Should probably be "0173: set_actor [email protected] z_angle_to [email protected]"

 

 

I also tried this:

 

:NameIt03A4: name_thread "TuffMan"   :Temp_Immune0001: wait  50 ms00D6: if  00256:   player $PLAYER_CHAR defined004D: jump_if_false ££Temp_Immune00D6: if  200E1:   key_pressed  0  16 ;;Sprint00E1:   key_pressed  0  19 ;;Look Behind80E0:   NOT   player $PLAYER_CHAR driving 004D: jump_if_false ££Temp_Immune0006:  [email protected] =  0;; integer values02AB: set actor  $PLAYER_ACTOR immunities  1  1  1  1  1018C: play_sound  1 at  0.0  0.0  0.00001: wait  250 ms 018C: play_sound  1 at  0.0  0.0  0.0:Temp_Immune20001: wait  0 ms00D6: if  00256:   player $PLAYER_CHAR defined004D: jump_if_false ££Non_Immune00D6: if  00019:    [email protected] >  19999;; integer values  004D: jump_if_false ££Temp_Immune20006:  [email protected] =  0;; integer values018C: play_sound  10 at  0.0  0.0  0.00001: wait  250 ms 018C: play_sound  10 at  0.0  0.0  0.00001: wait  250 ms 018C: play_sound  10 at  0.0  0.0  0.002AB: set actor  $PLAYER_ACTOR immunities  0  0  0  0  0:Recharge0001: wait  0 ms00D6: if  00256:   player $PLAYER_CHAR defined004D: jump_if_false ££Temp_Immune00D6: if  0  0019:    [email protected] >  119999;; integer values 004D: jump_if_false ££Recharge0002: jump ££Temp_Immune:Non_Immune02AB: set actor  $PLAYER_ACTOR immunities  0  0  0  0  00002: jump ££Temp_Immune

 

This (when not in car) plays sound and sets player immunities for 20 seconds. After 20 seconds immunities are removed and plays a sound. Then it has to Recharge for 2 minutes before it can be used again. Would it have been possible to get this same effect by using  "set actor  $PLAYER_ACTOR immunities  0  0  0  0  0" only once instead twice? Many flaws?

You should remove the :Non_Immune label completely, and change the jump to back to itself:

 

:Temp_Immune20001: wait  0 ms00D6: if  00256:   player $PLAYER_CHAR defined004D: jump_if_false ££Temp_Immune2

 

This is because setting the player's immunities after finding out that the player is not defined isn't going to make the engine very happy. Also, the player becomes undefined when getting in/out of a car, and so this would disrupt your timing.

 

 

P.S.

What does IMO stand for? (Immediate Mission Objective?) monocle.gif

IMO = In My Opinion

Share this post


Link to post
Share on other sites
Bigun

(IMO means 'in my opinion'. Yeah, not as cool as Immediate Mission Objective, too bad)

 

First,

 

@Bigun:In your example the player_char is teleported from a car or from on foot to preset coord's and it's present z_angle. I wanted to know if the z_angle could be preset in the create_thread to be used after being teleported (to look at a certain building, etc) yet do it in the most efficient way. I think this may best explain that part of my question.

It's Demarest's code. And it checks if the specified actor (can be $player_actor) is driving. If he isn't, then it will put_actor-him ( biggrin.gif ) to the specified coords. If he is, then it will remove_from_car_and_put_actor-him instead. It doesn't do anything with the z_angle, so yes, it will remain unchanged.

 

A few comments to Dem on it, though:

-You don't need the 0002:jump opcode and the :UNIVERSALPUTACTOR3 line. Remove them both, it should do no harm.

-Did you check if the remove_from_car_and_put_at opcode can work on onfoot actors too? If it does you can obviously make the code even compacter.

 

Okay, back to you. Dem made the thread so he can compress code (for example, Rockstar's default missions) by shortening functions that are used a lot of times by creating a single block of code/thread that does that function and then changing other places ie missions to use THAT block of code instead of every single mission having "its own copy" of that code. The thread is started with the initializing local variables of @0, @1, @2, @3, and it treats @0 as the actor (ANY actor, not just the player. so including $player_defined in that code ain't useful as well as checking for keypresses) and the rest as the coordinates. You don't have to use it, it's just to compact code...You can call it with an additional value that will get stored to @4 and set the actor's (@0) z_angle to that in the end of the code, here is the CORRECT thread with added z_angle changes:

 

instead of using a block of code to move actor etc instead call the thread with:

 

004F: create_thread ££UNIVERSALPUTACTOR $actor  x_coord y_coord z_coord z_angle

 

for example:

 

004F: create_thread ££UNIVERSALPUTACTOR $PLAYER_ACTOR  433! -574.5!  9.6! 180.0!

 

 

the actual thread (shortened from Dem's and added optional z_angle change)

 

:UNIVERSALPUTACTOR00D6: if  0?00DF:   actor  [email protected] driving004D: jump_if_false ££UNIVERSALPUTACTOR20362: remove_actor  [email protected] from_car_and_place_at  [email protected]  [email protected]  [email protected]:UNIVERSALPUTACTOR200A1: put_actor  [email protected] at  [email protected]  [email protected]  [email protected]: if 0?8039:   NOT [email protected] = 0;;integer values004D: jump_if_false ££UNIVERSALPUTACTOR30173: set_actor [email protected] z_angle_to  [email protected];---below is optional additions commented out to set camera behind player if the;---actor is the player. unsure if it will work, but I remember int compare opcodes;---could be used to compare handles or something as well. if someone knows;---about this please clarify ;00D6: if 0;003C:   $PLAYER_ACTOR = [email protected];004D: jump_if_false ££UNIVERSALPUTACTOR3;0373: set camera directly behind player:UNIVERSALPUTACTOR3004E: end_thread

 

 

Again, you don't really need to understand/use this. It also won't yield much effect unless you replace all similar put_actor routines in the SCM to call the thread like Dem.

 

In your new Temp_Immune code, the only benefit using a timer has that if the player becomes undefined DURIGN the waiting time, the code will execute the jump_if_false line. So the player can skip the waiting time by dying, etc. Also he will become unimmune if he does die (not sure if it's needed as he possibly becomes unimmuned after death by default anyway) while immuned.

If you want that, you need to use a timer. Otherwise, you can use a single 'wait X', followed by an 'if player defined' instead.

 

 

Also, the player becomes undefined when getting in/out of a car, and so this would disrupt your timing.

...Really? Are you sure? notify.gif

Share this post


Link to post
Share on other sites
Knowledge Novice

I've noticed that when you guys Quote someone it shows the name of the person being quoted, whereas mine do not. How do I get it to do that?

 

 

(random_download)

You should remove the :Non_Immune label completely, and change the jump to back to itself:

CODE 

:Temp_Immune2

0001: wait  0 ms

00D6: if  0

0256:  player $PLAYER_CHAR defined

004D: jump_if_false ££Temp_Immune2

 

 

(Bigun)

In your new Temp_Immune code, the only benefit using a timer has that if the player becomes undefined DURIGN the waiting time, the code will execute the jump_if_false line. So the player can skip the waiting time by dying, etc. Also he will become unimmune if he does die (not sure if it's needed as he possibly becomes unimmuned after death by default anyway) while immuned. If you want that, you need to use a timer. Otherwise, you can use a single 'wait X', followed by an 'if player defined' instead.

 

That's what I was aiming for. If I'm busted I don't really care so much, but I'd like to be able to use my immunities again imediately after being wasted and without the Recharge delay. (You were right. The immunities are automatically removed once player is undefined.) Would this code make more sense?

 

:NameIt03A4: name_thread "TuffMan"   :Temp_Immune0001: wait  50 ms00D6: if  00256:   player $PLAYER_CHAR defined004D: jump_if_false ££Temp_Immune00D6: if  200E1:   key_pressed  0  16;;Sprint00E1:   key_pressed  0  19;;Look Behind80E0:   NOT   player $PLAYER_CHAR driving 004D: jump_if_false ££Temp_Immune0006:  [email protected] =  0;; integer values02AB: set actor  $PLAYER_ACTOR immunities  1  1  1  1  1018C: play_sound  1 at  0.0  0.0  0.00001: wait  250 ms 018C: play_sound  1 at  0.0  0.0  0.0:Temp_Immune20001: wait  0 ms00D6: if  0  8118:   NOT   actor $PLAYER_ACTOR dead004D: jump_if_false ££Temp_Immune00D6: if  00256:   player $PLAYER_CHAR defined004D: jump_if_false ££Temp_Immune200D6: if  00019:    [email protected] >  19999;; integer values  004D: jump_if_false ££Temp_Immune20006:  [email protected] =  0;; integer values02AB: set actor  $PLAYER_ACTOR immunities  0  0  0  0  0018C: play_sound  10 at  0.0  0.0  0.00001: wait  250 ms 018C: play_sound  10 at  0.0  0.0  0.00001: wait  250 ms 018C: play_sound  10 at  0.0  0.0  0.0:Recharge0001: wait  0 ms00D6: if  0  8118:   NOT   actor $PLAYER_ACTOR dead004D: jump_if_false ££Temp_Immune00D6: if  00256:   player $PLAYER_CHAR defined004D: jump_if_false ££Recharge00D6: if  0  0019:    [email protected] >  119999;; integer values 004D: jump_if_false ££Recharge0002: jump ££Temp_Immune

 

Here I removed the :Non_Immune label and added <8118: NOT actor $PLAYER_ACTOR dead> in my :Temp_Immune2 and :Recharge labels so that anytime the player dies while immune or during the Recharge period it loops back to :Temp_Immune to get a fresh start without any delays. This seems to work, but is it correct?

 

 

QUOTE (random_download)

Also, the player becomes undefined when getting in/out of a car, and so this would disrupt your timing.

 

(Bigun)

...Really? Are you sure?

If the player becomes undefined when getting in/out of a car wouldn't that trigger this code to bypass the Recharge delay?

 

:Recharge0001: wait  0 ms00D6: if  00256:   player $PLAYER_CHAR defined004D: jump_if_false ££Temp_Immune00D6: if  0  0019:    [email protected] >  119999;; integer values 004D: jump_if_false ££Recharge0002: jump ££Temp_Immune

 

Or remove my immunities here?

 

:Temp_Immune20001: wait  0 ms00D6: if  00256:   player $PLAYER_CHAR defined004D: jump_if_false ££Non_Immune00D6: if  00019:    [email protected] >  19999;; integer values  004D: jump_if_false ££Temp_Immune20006:  [email protected] =  0;; integer values018C: play_sound  10 at  0.0  0.0  0.00001: wait  250 ms 018C: play_sound  10 at  0.0  0.0  0.00001: wait  250 ms 018C: play_sound  10 at  0.0  0.0  0.002AB: set actor  $PLAYER_ACTOR immunities  0  0  0  0  0

 

Because, regardless of whether I'm in the :Recharge loop or the :Temp_Immune2 loop, I can enter/exit a vehicle multiple times without any noticable effects that would be caused by triggering the

 

00D6: if  00256:   player $PLAYER_CHAR defined004D: jump_if_false ££

 

Not disagreeing. Just trying to better understand. confused.gif

 

 

First,

QUOTE (Knowledge Novice)

@Bigun:In your example the player_char is teleported from a car or from on foot to preset coord's and it's present z_angle. I wanted to know if the z_angle could be preset in the create_thread to be used after being teleported (to look at a certain building, etc) yet do it in the most efficient way. I think this may best explain that part of my question.

 

It's Demarest's code.

Oops. I got a little mixed up. Sorry.

Share this post


Link to post
Share on other sites
Demarest

But now I see that it starts at 0 and increases automatically.
*starts at whatever value you set it at and increases automatically. What's the difference? Well in Thirst For Blood, I have a timer check of > 600 IIRC. But I didn't want everything calling on that feature to take the full 600 ms, so if those other circumstances were met, I set the local timer to 300 or 550 IIRC.

 

 

As far as coordinates it gives the actor's x,y,z. But what if I wanted to supply the actor's z_angle? Could I do this
004F: create_thread ��UNIVERSALPUTACTOR $PLAYER_ACTOR  433! -574.5!  9.6!  180!00A1: put_actor  [email protected] at  [email protected]  [email protected]  [email protected]: set actor [email protected] z angle to  [email protected]

Or would I need to do this

004F: create_thread ��UNIVERSALPUTACTOR $PLAYER_ACTOR  433! -574.5!  9.6!  00A1: put_actor  [email protected] at  [email protected]  [email protected]  [email protected]: set actor [email protected] z angle to  180!

 

Depends. If every use was with a z_angle of 180, the latter would suffice. Otherwise, the former would be what you wanted.

 

 

It takes desire and self determination, true enough. But without someone to help guide me when I get stuck in the mudhole known as confusion I'd mainly just end up down and dirty.
Well we're always here to help. Just more often than not a new person comes in expecting either for one of us to do everything for them (despite having done so and documenting it years ago) or to become the next Barton overnight. Then when their unrealistic expectations cause them to crash and burn, it's OUR fault.

 

 

Ok. So I can just use a WAIT for a code that may run indefinitely or a TIMER for a shorter lived effect that expires after a preset time limit (like temporary immunities).
You can use either for either. What Bigun was saying was that HE felt it wasn't necessary here. He was essentially asserting that because the original way might take 1.02 seconds, it was negligible. Which is true except a) there's nothing wrong with improving code and b) there's nothing wrong with learning how to use local timers in the process.

 

 

:NameIt03A4: name_thread "TuffMan"   :Temp_Immune0001: wait  50 ms00D6: if  00256:   player $PLAYER_CHAR defined004D: jump_if_false ��Temp_Immune00D6: if  200E1:   key_pressed  0  16 ;;Sprint00E1:   key_pressed  0  19 ;;Look Behind80E0:   NOT   player $PLAYER_CHAR driving 004D: jump_if_false ��Temp_Immune0006:  [email protected] =  0;; integer values02AB: set actor  $PLAYER_ACTOR immunities  1  1  1  1  1018C: play_sound  1 at  0.0  0.0  0.00001: wait  250 ms 018C: play_sound  1 at  0.0  0.0  0.0:Temp_Immune20001: wait  0 ms00D6: if  00256:   player $PLAYER_CHAR defined004D: jump_if_false ��Non_Immune00D6: if  00019:    [email protected] >  19999;; integer values  004D: jump_if_false ��Temp_Immune20006:  [email protected] =  0;; integer values018C: play_sound  10 at  0.0  0.0  0.00001: wait  250 ms 018C: play_sound  10 at  0.0  0.0  0.00001: wait  250 ms 018C: play_sound  10 at  0.0  0.0  0.002AB: set actor  $PLAYER_ACTOR immunities  0  0  0  0  0:Recharge0001: wait  0 ms00D6: if  00256:   player $PLAYER_CHAR defined004D: jump_if_false ��Temp_Immune00D6: if  0  0019:    [email protected] >  119999;; integer values 004D: jump_if_false ��Recharge0002: jump ��Temp_Immune:Non_Immune02AB: set actor  $PLAYER_ACTOR immunities  0  0  0  0  00002: jump ��Temp_Immune

 

Because your mod is written in a sequential manner, there's no reason to have to use 2 different local timers.

 

 

:UNIVERSALPUTACTOR00D6: if  0?00DF:   actor  [email protected] driving004D: jump_if_false ��UNIVERSALPUTACTOR20362: remove_actor  [email protected] from_car_and_place_at  [email protected]  [email protected]  [email protected]:UNIVERSALPUTACTOR200A1: put_actor  [email protected] at  [email protected]  [email protected]  [email protected]: if 0?8039:   NOT [email protected] = 0;;integer values004D: jump_if_false ��UNIVERSALPUTACTOR30173: set_actor [email protected] z_angle_to  [email protected];---below is optional additions commented out to set camera behind player if the;---actor is the player. unsure if it will work, but I remember int compare opcodes;---could be used to compare handles or something as well. if someone knows;---about this please clarify ;00D6: if 0;003C:   $PLAYER_ACTOR = [email protected];004D: jump_if_false ��UNIVERSALPUTACTOR3;0373: set camera directly behind player:UNIVERSALPUTACTOR3004E: end_thread

 

First of all, there is no purpose in checkig if [email protected] is equal to zero or not. Secondly, you want to check if [email protected] equals $PLAYER_ACTOR, not the other way around. Not that I understand why you'd compound the code with a 0373 in the first place; if the mission wanted that opcode run, it will have it immediately after the code being farmed out anyways.

 

 

I've noticed that when you guys Quote someone it shows the name of the person being quoted, whereas mine do not. How do I get it to do that?
You're hitting quote and then copy/pasting the text in. Each post has a quote button. Hit that and you will be presented with two text fields, one for your free reply and one for the post of the person you're quoting. If you post it from there, everything in the 2nd field will be within properly credited quote tags. Or if you're replying to several points from the same post, you can put SOMETHING in the first field and then hit preview post. At which point you'll have just one field, complete with whatever you put in, plus the properly credited quote tags. From there, you can copy paste those quote tags so that each item is properly credited.

 

 

If I'm busted I don't really care so much, but I'd like to be able to use my immunities again imediately after being wasted and without the Recharge delay. (You were right. The immunities are automatically removed once player is undefined.) Would this code make more sense?
No. With the player, you use if player defined checks. With other actors, you check if they're dead. Precedent aside, you're essentially checking the same thing twice in a row, which is unnecessary. Your code was fine the first time beside the separate immunities off line like random pointed out.

 

 

If the player becomes undefined when getting in/out of a car wouldn't that trigger this code to bypass the Recharge delay?
Yes. And since that's not how it plays out, you can rest assured that the initial claim is false. is player defined will ONLY return false if the player is currently busted or wasted.

Share this post


Link to post
Share on other sites
Knowledge Novice

QUOTE (Knowledge Novice @ Nov 4 2006, 01:08)

Ok. So I can just use a WAIT for a code that may run indefinitely or a TIMER for a shorter lived effect that expires after a preset time limit (like temporary immunities). 

You can use either for either. What Bigun was saying was that HE felt it wasn't necessary here. He was essentially asserting that because the original way might take 1.02 seconds, it was negligible. Which is true except a) there's nothing wrong with improving code and b) there's nothing wrong with learning how to use local timers in the process.

 

I'm glad to be learning how to use both. The more options the better. Even if I never use a timer in place of a simple wait, I'm sure I can get some use out of it's ability to cause timed/limited effects.

 

 

QUOTE (Knowledge Novice @ Nov 4 2006, 19:19)

If I'm busted I don't really care so much, but I'd like to be able to use my immunities again imediately after being wasted and without the Recharge delay. (You were right. The immunities are automatically removed once player is undefined.) Would this code make more sense?

No. With the player, you use if player defined checks. With other actors, you check if they're dead. Precedent aside, you're essentially checking the same thing twice in a row, which is unnecessary. Your code was fine the first time beside the separate immunities off line like random pointed out.

Oops, tripped in the mud. Removed the actor checks, set the JF in both my :Temp_Immune2 and :Recharge labels to jump back to :Temp_Immune (so when I die I start fresh without lingering immunities or the :Recharge delay). I also reset [email protected] to 0 and reused it for the second timer as well (is that what you meant by " there's no reason to have to use 2 different local timers."?). After testing, it seems to run fine.

 

:NameIt03A4: name_thread "TuffMan"   :Temp_Immune0001: wait  50 ms00D6: if  00256:   player $PLAYER_CHAR defined004D: jump_if_false ££Temp_Immune00D6: if  200E1:   key_pressed  0  16;;Sprint00E1:   key_pressed  0  19;;Look Behind80E0:   NOT   player $PLAYER_CHAR driving 004D: jump_if_false ££Temp_Immune0006:  [email protected] =  0;; integer values02AB: set actor  $PLAYER_ACTOR immunities  1  1  1  1  1018C: play_sound  1 at  0.0  0.0  0.00001: wait  250 ms 018C: play_sound  1 at  0.0  0.0  0.0:Temp_Immune20001: wait  0 ms00D6: if  00256:   player $PLAYER_CHAR defined004D: jump_if_false ££Temp_Immune00D6: if  00019:    [email protected] >  19999;; integer values  004D: jump_if_false ££Temp_Immune20006:  [email protected] =  0;; integer values02AB: set actor  $PLAYER_ACTOR immunities  0  0  0  0  0018C: play_sound  10 at  0.0  0.0  0.00001: wait  250 ms 018C: play_sound  10 at  0.0  0.0  0.00001: wait  250 ms 018C: play_sound  10 at  0.0  0.0  0.0:Recharge0001: wait  0 ms00D6: if  00256:   player $PLAYER_CHAR defined004D: jump_if_false ££Temp_Immune00D6: if  0  0019:    [email protected] >  119999;; integer values 004D: jump_if_false ££Recharge0002: jump ££Temp_Immune   

 

 

P.S.

Thanks for the info on "Quoting", Dem. It's not clear yet, but I'll figure it out. (I hope.) notify.gif

 

Edited by Knowledge Novice

Share this post


Link to post
Share on other sites

Join the conversation

You can post now and register later. If you have an account, sign in now to post with your account.
Note: Your post will require moderator approval before it will be visible.

Guest
Reply to this topic...

×   Pasted as rich text.   Paste as plain text instead

  Only 75 emoji are allowed.

×   Your link has been automatically embedded.   Display as a link instead

×   Your previous content has been restored.   Clear editor

×   You cannot paste images directly. Upload or insert images from URL.


  • 1 User Currently Viewing
    0 members, 0 Anonymous, 1 Guest

×
×
  • Create New...

Important Information

By using GTAForums.com, you agree to our Terms of Use and Privacy Policy.