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. Gameplay
      2. Missions
      3. Help & Support
    2. Red Dead Online

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

      1. Recruitment
    2. Events

    1. GTA Online

      1. Arena War
      2. After Hours
      3. Find Lobbies & Players
      4. Guides & Strategies
      5. Vehicles
      6. Content Creator
      7. Help & Support
    2. Grand Theft Auto Series

    3. GTA Next

    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 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 Mods
    10. GTA Vice City

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

      1. Guides & Strategies
      2. Help & Support
      3. GTA 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

If the answer isn't simple, please direct me to info that may help. Any help or suggestions are greatly appreciated.

 

My goal: To make it so that the Infernus is immune to all damage and make the tires invulnerable ONLY if the player is in it and for it to return to normal when exited. This is meant to be "player specific" meaning that only the Infernus the player is currently driving is affected.

My problem: This mod seems to work at first, but the game crashes if you are Busted, Wasted, or enter a mission marker (like the 1st mission, The Party/ but not the 2nd, i.e. dropping off Maria at Pole Position) while in an Infernus. Doing any of the above while NOT in an Infernus has no ill effect on game play.

What I did:

 

;Added these with the rest of create_threads

 

004F: create_thread ££LabelToughInfernus

004F: create_thread ££LabelInfernus2

 

;Added car_generator to spawn an Infernus in front of Ocean View Hotel (just behind the Oceanic)

 

014B: $15 = init_parked_car_generator #INFERNUS 0 0 0 alarm 0 door_lock 0 0 10000 at 245.1562 -1263.957 10.675 angle 165.0

014C: set_parked_car_generator $15 cars_to_generate_to 101

 

;Added just before -Mission 0-

 

:LabelToughInfernus

0001: wait 500 ms

00D6: if 0

00DE: player $PLAYER_CHAR driving_vehicle_type #INFERNUS

004D: jump_if_false ££LabelToughInfernus

03C1: $51A = player $PLAYER_CHAR car

02AC: set_car $51A immunities 1 1 1 1 1

053F: set_car $51A tires_vulnerable 0

 

:LabelInfernus2

0001: wait 500 ms

00D6: if 0

80DE: NOT player $PLAYER_CHAR driving_vehicle_type #INFERNUS

004D: jump_if_false ££LabelInfernus2

02AC: set_car $51A immunities 0 0 0 0 0

053F: set_car $51A tires_vulnerable 1

0002: jump ££LabelToughInfernu

 

 

 

Share this post


Link to post
Share on other sites
random_download

Whenever you reference $PLAYER_CHAR or $PLAYER_ACTOR you should have a

0256:   player $PLAYER_CHAR defined

check before it (although if you reference one of them several times without a wait inbetween, then you only need to check once). The line

004F: create_thread ££LabelInfernus2

should not be there, as this will cause you to have two threads doing the same thing. Your first label loops with the second label, having two create_thread opcodes on the same code will cause two instances of it to run simultaneously.

Instead of using a var like "$51A", you should use a named one such as $PlayersCar or something, this way you make sure that the same var is not used in a mission somewhere, as well as making your code easier to read.

 

Other than those things your code looks good and should function correctly.

Share this post


Link to post
Share on other sites
Demarest

I see what you're doing here. Not bad. I want you to know that it's important you understand the WHY's of everything I'm about to tell you. If not, ASK! No point in making mistakes if we can't learn from them. Also, you can grab my Armor All mod for another example of what you're looking to do here...

 

First things first, you're creating 2 threads. ONE thread would have to have a huge burden in order to justify two threads. That's not the case here. Using two threads when one will suffice is not only wasteful, but it's going to give you a harder time. So let's not get into that habit.

 

Secondly, you are using DMA variables. Don't do that. MB allows you to us $MYCAR, so do that. Or if you want to be least wasteful, you can use local variables ( [email protected]). For more details, consult the MB readme. It's a good idea until you hit your stride to refer to it often; you'll be surprised as you evolve as a coder, how much you'll continue to learn from it despite having read it already.

 

Your first "thread" when it returns true, runs right into your 2nd thread. Then the jump at the end of your 2nd thread goes to an address that doesn't exist. MB will yell at you for such things, so I'll assume you missed a character when copy/pasting.

 

Now it may not be obvious at first why and when to use an if player defined check, but you need to here becuase is player driving car directly refers to the player. Anytime you directly refer to the player, you need an if player defined check. It's opcode 0256 and you'll find it used often in original code.

 

Your 2nd thread doesn't capture the car. I know what you're thinking: But the first one does and it uses a global variable. This is true. However, what if your 2nd thread has focus first after the engine is ready to report you are indeed driving an Infernus? That if will return true, proceed to a command talking to a car the game doesn't know what you mean and... crash.

 

Last but not least, when you're finished with something in the code, you have to tell the engine to let it go. Failure to do so could lead to memory getting stuffed after a while and that will crash it too. Say your code worked and during the course of the game, you get into a dozen Infernus's. You never dismiss them, so the game is going to try and retain them all. This will impact traffic among other things. Search original code for remove_references. You'll find commands for actors and cars.

 

Put it all together and you'll end up with something LIKE the following. Keep in mind I think I use a different MB version than you, so the syntax will be slightly different, but recognizable (should be). And again, if you don't understand ANY element of the above, ASK. I'm not spending the time writing this out for it to go over your head and I like coders that are willing to take baby steps, which this is. That means you have the potential for a good coder if you so desire and I'd like to see that happen the right way. So don't be afraid to ask. colgate.gif

 

 

:TOUGHINFERNUS0001: wait  500& ms00D6: if  0?0256:   player $PLAYER_CHAR defined004D: jump_if_false TOUGHINFERNUS00D6: if  0?00DE:   player $PLAYER_CHAR driving_vehicle_type #INFERNUS004D: jump_if_false TOUGHINFERNUS03C1:  [email protected] = player $PLAYER_CHAR car02AC: set_car  [email protected] immunities  1?  1?  1?  1?  1?053F: set_car  [email protected] tires_vulnerable 0:TOUGHINFERNUS20001: wait  500& ms00D6: if  0?0256:   player $PLAYER_CHAR defined004D: jump_if_false TOUGHINFERNUS300D6: if  0?80E0:    NOT  player $PLAYER_CHAR driving004D: jump_if_false TOUGHINFERNUS2:TOUGHINFERNUS302AC: set_car  [email protected] immunities  0?  0?  0?  0?  0?053F: set_car  [email protected] tires_vulnerable  1?01C3: remove_references_to_car  [email protected]: jump ££TOUGHINFERNUS

 

This only requires the one create_thread of course. I encourage to continue work on this, but to reference my Armor All mod just the same. I know there's at least one feature in it you'd love to have for your super Inferni wink.gif

Share this post


Link to post
Share on other sites
Knowledge Novice

The syntax is a little different, but not a problem. I see now that I wasn't going about it quite right. It's amazing how something that can start to be so frustrating can have such a complexly simple solution. At first glance it threw me off, but after studying it for a few seconds it was like lifting a veil.

I used two threads because (for some reason) I assumed that you had to create a thread for anything that would be "jumped" to. At this point I think I pretty much understand all that you have told me, but I will also check out your Armor All mod for reference and go back through the MB readme.

I have no problem taking baby steps. I'm just glad that there's somebody out there who can help along the way.

 

Just to mention it: My game no longer crashes when being busted or wasted (drive into water) when in the Infernus. Although there still seems to be a conflict when driving it into mission markers as the game still crashes there (The Party).

You have been an enormous help, not only in getting this mod straightened out, but mainly in helping clarify my view of the structure the code should take. I TRULY appreciate your time. Thank you.

 

P.S. I can't seem to get the Search function to work. It says something like "You don't have permission to use this function" and makes reference to maybe not being logged in, when I actually am. I feel at a disadvantage having to go through each individual topic searching for reference material. If the Search function is working it would help to know what I'm doing wrong. Thank you.

 

Share this post


Link to post
Share on other sites
Demarest

It's amazing how something that can start to be so frustrating can have such a complexly simple solution.
Indeed. If you're anything like me though, diagnosing problematic code is just as fun as getting it right the first time... assuming it IS something simple. It's when it's those seemingly unexplainable times that make you want to throw your monitor out the window lol.gif

 

 

I used two threads because (for some reason) I assumed that you had to create a thread for anything that would be "jumped" to.
Nope, in fact, that's the best indicator that you do NOT need a create_thread. The code runs linearly as we read it. So it will continue to trickle downwards until a gosub, jump, or JF (jump_if_false) tells it to do otherwise. You will almost always need a create_thread because you'll almost always be adding stuff to the game. If you're instead just modifying, then you will not need to add a create_thread because whatever it is you're modifying already runs somehow by way of a create_thread already in place. Again, if that's not making sense to you, say so. When I first started writing in SCM, it was my first time working in a (psuedo-) multi-thread environment. So the idea of having multiple threads processing different things wasn't easy. Especially since it IS a psuedo- environment and therefore the various threads need to pass focus back and forth to one another. For that reason, I should've complimented you on your wait 500's. Wait 500 is a low priority thread, which realistically, is what what you're doing SHOULD be. Most newer coders make the mistake of making things too high priority. You'll get the hang of it. Looks like you're already off to a great start.

 

 

I have no problem taking baby steps. I'm just glad that there's somebody out there who can help along the way.
And you know what? I never would've gotten to where I am if it weren't for others helping me along too while taking baby steps myself. And I STILL have to ask questions!

 

 

Just to mention it: My game no longer crashes when being busted or wasted (drive into water) when in the Infernus. Although there still seems to be a conflict when driving it into mission markers as the game still crashes there (The Party).
As I sit here thinking, I cannot figure out why that would be. I'll look into it when I close this post. Strikes me as odd though because the sniffer for The Party checks for you to be on foot. So for as long as you're in the car, in the marker or out should be the same to the game.

 

Perhaps now would be a good time to mention that it is customary to work on your code in a stripped SCM. I believe MB comes with one. This has many advantages, the most pertinent for your predicament there is that it removes all other variables (environmental, not literal storage wink.gif). And being devoid of additional code, your compile times will shrink to almost instantaneous. When you're tweaking something and having to recompile repeatedly, this really helps. Then once you get it working, you can transfer it to its intended home.

 

 

You have been an enormous help, not only in getting this mod straightened out, but mainly in helping clarify my view of the structure the code should take. I TRULY appreciate your time. Thank you.
My pleasure. I don't mind at all helping out those willing to do it right.

 

 

P.S.  I can't seem to get the Search function to work. It says something like "You don't have permission to use this function" and makes reference to maybe not being logged in, when I actually am. I feel at a disadvantage having to go through each individual topic searching for reference material. If the Search function is working it would help to know what I'm doing wrong. Thank you.
We're all in the same boat there. Search has been disabled. I know; a real crime for those of us here for the pool of information a forum is, let alone the #1 spot for modding info. There's a couple workarounds. The first being the pinned threads. Both here and in the tutorials forum. The other is to use google. If you go to google.com and type site:http://gtaforums.com as one of your search terms, it will only return results from this forum. And since google returns have a cached link, it acts almost like a forum backup. Earlier the forums were down and I was actually able to get to the data I was looking for in this method. Hope that helps.

 

I'll let you know if I figure anything out about The Party. If you can come up with comething else you might've changed, please share it.

Share this post


Link to post
Share on other sites
Demarest

Back from testing. First of all, my apologies. I thought The Party's sniffer originated at the docks. I had forgotten about Ken's and Rafael's first. Secondly, my apologies. I looked into the code after I realized I was wrong above and the crash is not only entirely my fault, but 100% preventable. I made a mistake, but it will make for a good lesson here...

00D6: if  0?00E0:   player $PLAYER_CHAR driving004D: jump_if_false £Label03EA5A00DA:  8432?? = player $PLAYER_CHAR car00AA:  8464?? = car  8432?? x_pos,  8468?? = car  8432?? y_pos,  8472?? = car  8432?? z_pos0174:  8476?? = car  8432?? z_angle03F3: get_car  8432?? color  [email protected]  [email protected]:  8436?? = car  8432?? model00D6: if  0?00DC:   player $PLAYER_CHAR driving  8432??004D: jump_if_false £Label03EA53012A: put_player $PLAYER_CHAR at -246.5! -1360.5!  7.1! and_remove_from_car00A6: destroy_car  8432??

There's the reason there is a crash. When you get to the yacht, if you're in a car, the code not only removes you from the car, but destroys it. When the mission encounters its next wait command and the TOUGHINFERNUS thread regains focus, it checks if you are defined and then checks if you are not driving. You're not, so the codes proceded to set characteristics of a car that doesn't exist... crash.

 

Remember what I said before about if player defined? Same goes for actors, cars, and even objects. You have to make sure it's around before you go telling the game to handle it. Here's how the code I offered you before SHOULD look.

:TOUGHINFERNUS0001: wait  500& ms00D6: if  0?0256:   player $PLAYER_CHAR defined004D: jump_if_false ££TOUGHINFERNUS00DE:   player $PLAYER_CHAR driving_vehicle_type #INFERNUS004D: jump_if_false ££TOUGHINFERNUS03C1:  [email protected] = player $PLAYER_CHAR car02AC: set_car  [email protected] immunities  1?  1?  1?  1?  1?053F: set_car  [email protected] tires_vulnerable 0?:TOUGHINFERNUS20001: wait  500& ms00D6: if  0?0256:   player $PLAYER_CHAR defined004D: jump_if_false ££TOUGHINFERNUS300D6: if  0?80E0:    NOT  player $PLAYER_CHAR driving004D: jump_if_false ££TOUGHINFERNUS2:TOUGHINFERNUS300D6: if  0?8119:   NOT  car  [email protected] wrecked004D: jump_if_false ££TOUGHINFERNUS402AC: set_car  [email protected] immunities  0?  0?  0?  0?  0?053F: set_car  [email protected] tires_vulnerable  1?:TOUGHINFERNUS401C3: remove_references_to_car  [email protected]: jump ££TOUGHINFERNUS

Conditionals like is player defined, is car wrecked, and is actor dead are "safe" conditionals. They can NEVER crash the game. Here, the code says "is the car not wrecked? there is no car. return false". So you might ask "Well doesn't the remove references command talk about a car that doesn't exist?" Commands like remove_references, destroy_actor, disable_marker, etc are known as cleanup commands. They too can never crash the game.

 

I'll take it one step further. Let's say for example in TOUGHINFERNUS2, instead of is actor driving, we used 00DC: player $PLAYER_CHAR driving [email protected] Just as I told you initially you need an if player defined check before referring to the player, you also need an if car wrecked check before referencing a car. But since it's written as simply is player driving (at all), we don't actually need to check the status of the car itself until we DO get around to referencing it.

 

I'm really sorry about the mistake. Ask anybody; I'm a stickler for is player defined, is car wrecked and the like. Hopefully it ended up yielding info you can still benefit from.

Share this post


Link to post
Share on other sites
Knowledge Novice

At this point I'm thrilled to see one of my ideas fully functional and seemingly with out any bugs so far. Whith each response I'm enlightened to something that may have otherwise impeded or else halted my progress through shear frustration. The structure of the code, although it makes sense while reading it through at present, will still take me a little while to fully comprehend in my future experiences with modding, but seems understandable enough to grasp with out too much of a problem. Just needs a bit of studying and commiting to memory.

 

I feel that I've learned a little more of the structure that the code must take to successfully complete it's cycle with out causing conflicts with other functions in the code. This will make me more aware of possible glitches in my codes and there fore make them more easily recognizable and fixable.

I will study through the code in this post as well as the material you mentioned earlier (Armor All Mod and MB readme) to try to better grasp what you've shown me and to further my understanding through personal experience. Baby steps.

 

P.S. I submitted a description of this mod (what it does) to GTAGarage.com for approval. It was approved for me to submit my file for final approval, but then I realised the major flaws that were in my code. Due to the fact that your advice and instruction was not only helpful, but crucial in the finishing of this mod I'm not sure I deserve credit for this mod at this point.

Should I remove my submission from GTAGarage.com or should I maybe continue to modify it and give you a major credit recognition for your invaluable help. I needed to be put on the right track and even if I further mod this code I don't want to plagiarize any one else's work. I want to contribute to the community, but don't want to step on any one's toes as I continue to learn. I've only submitted a description of my intended codes effects (which are exactly as I meant them to be, due to your help). I haven't submitted the compiled code for approval due to my uncertainty of the amount of credit I may or may not deserve.

If you feel that I should withdraw my submission until I've had a bit more experience I will totally understand. Other wise, if your cool with me submitting this code I'm open to suggestions or conditions I must meet for using this code. Either way I'm learning and that's my main goal. Just give me your thoughts either way.

Either meet certain conditions (such as making it more my own) or removing my submission (I'm still new to the whole forum format and am not sure how to remove it from GTAGarage.com). Many thanks for your continued support. And I patiently await your response. Thanks Demarest.

 

P.S.

"Perhaps now would be a good time to mention that it is customary to work on your code in a stripped SCM." Thanks for the tip. I did start out coding in one of the stripped SCM, but when I encountered functionality problems adding the mod to the original SCM I was afraid that the problem was that the mod reacted differently with all the added code. But if that's not the case I will definitely start using the stripped SCM, which as you said is much more time efficient.

Edited by Knowledge Novice

Share this post


Link to post
Share on other sites
Demarest

I will study through the code in this post as well as the material you mentioned earlier (Armor All Mod and MB readme) to try to better grasp what you've shown me and to further my understanding through personal experience. Baby steps.
We have a saying around here: immitate existing code. Not going to solve every single issue, but it's a great, general solution. And as you learn what each game CAN do, you quickly realize that the mission sets of each game were essentially a showcase for everything the engine is capable of. So you're sitting there asking yourself, "Well how do I do this?" Then you think of a point in the game where such a thing is done, go there, and read how they did it. Or in the case of the code above. Say you wanted to make the car immune to damage. While immune might not have been your first choice of words, simply searching the opcode database for that word quickly reveals what you're looking for.

 

 

P.S. I submitted a description of this mod (what it does) to GTAGarage.com for approval...
My advice would definitely be to pull it. And while in the end, yes, it's technically not your work, that's not my reason for issuing that advice. My reason is scale. When I write something like Thirst For Blood, I release it in the mod showroom, with a deluxe topic, screens, etc. However, when I whip up just a little script like Armor All, I tend to just post a topic here. The thing you need to realize is the code above is NOT a mod. We had a guy once that took opcode 0109 add_to_player money, set the money amount to 999999 and released that one line as a "mod"! notify.gif That's extreme, but this is really the same thing. It's a little code with very limited ingame yield. Not saying it's worthless because in terms of your development as a coder, it's going to mean everything to YOU. To others though, it would mean nothing. Armor all, does this and a lot more, any trainer can make the car you're in impervious, etc. Not saying you can only release that which is unique, just saying try to take it in context. I realize that as I say that, it's easier for me because I have my own site, so I can throw up a listing for anything no matter how trivial and people can choose for themselves whether to grab that or not. I wouldn't propose to take up the resources of another for somthing of such low impact. You're free to do as you choose, but this is better off as a thread right here saying "look what I did". Consider your audience. This will have interest for 2 types of people: gamers and modders. The gamers would never settle for something like ONLY the Infernus. They want to be able to walk into any car, press a button, and nuke half of Vice City tounge.gif Modders, the other half of the coin, can do this themselves and really only stand to benefit from the dialogue that's taken place surrounding it.

 

 

I needed to be put on the right track and even if I further mod this code I don't want to plagiarize any one else's work.
Not at all, I'm sure. Worry not. Coders tend to be the biggest sharer's of them all. Direct from my website: "I am a firm believer and an avid supporter of freedom. Freedom to be ourselves as well as enjoy ourselves. If you like my mods, my codes, or the ideas they give you, go with that. Use them, abuse them, hack them, duplicate them, distribute them, whatever. Have fun with it. This is, after all, a video game! And if you happen to feel like it, maybe mention that I helped inspire you or you found it here." Just as when I release stuff, I'll even credit people who didn't directly impact the development simply because I refuse to be quick to forget who helped me.

 

You mention development there and I'm glad to hear that and would of course eventually change my suggestion of where/how to release. Not trying to throw everything at you at once, but I like to preen my Neo series when talking about development. It's a great example because v1 was NOTHING. v5 however is lush with all kinds of features v2-4 was the progression from one to the other and to me, a good example of how one can add and expand far enough to re-release and so on.

 

 

If you feel that I should withdraw my submission until I've had a bit more experience I will totally understand.
I'm totally with you. If I had a dollar for every time I thought I "got it", I'd be rich. But I'm constantly learning new ways, new ideas, new approaches. Take Thirst For Blood for example. It was about 80% completed when I said "f*ck it" and started over. Granted, I did a decent amount of copy/pasting to restore the work I had already acoomplished. But it was something I just built and built upon, patching new features in... The first version of the code was UGLY and very hard to read. Now had I realized that it was going to grow to such proportions, I might've taken greater care up front. But that's the point! I should've been anyways so that as my code grows, it doesn't experience any side effects. Now I know and as I set out to write new things (been hammering away at it quite a bit lately), my approach is far improved. "Why do we fall down, Master Bruce? To learn how to pick ourselves back up." I've been doing this for 3 years now and I'm still learning new things.

 

 

Thanks for the tip. I did start out coding in one of the stripped SCM, but when I encountered functionality problems adding the mod to the original SCM I was afraid that the problem was that the mod reacted differently with all the added code.
Exactly! Which is why while it's embarrassing, I'm glad I made the mistake that I did. Because anybody can SAY "use if car wrecked checks", but without an example to help drive home the dangers of not, it's hard for somebody new to the concept to just accept that "that's the way it is". If you look at the code and my explanation of why it crashed, you'll come to the conclusion that in a stripped SCM, it's likely to never crash. It also helps show that when evalutaing your own code, you can't settle for things like "well of course the car isn't wrecked... I just got in the damn thing!" But what happens after you drive it about, running into things? "Well that won't matter because I made it invincible." What about when the car is flipped and marked for termination by the engine? OR when another thread erases the car? Which is exactly as you said: Okay in a stripped SCM, but not with all the other code present. It's not about what WILL happen, it's about making your code ready for anything that CAN happen. Take the time to incorporate such things and you'll develop a reputation of quality mods. Because if somebody adds anything you release and their game crashes, they're going to assume it's your work even if it isn't.

Share this post


Link to post
Share on other sites
Demarest
Been almost a week. Everything going well?

Share this post


Link to post
Share on other sites
Knowledge Novice

I haven't done a whole lot lately. I've actually put the Tough Infernus on the back burner now that you've helped me understand it more clearly. I'm currently trying my hand at something a little more complex (at least for me). No definite storyline yet, but I would like to try making some small missions to add to my game, maybe a "Gimme Guy" who requests simple things like "Go steal me a cop car". BUT I haven't got to the mission part yet. For now I'm trying to understand how to spawn and manipulate actors (like a body guard). I know this has been done before but I've never quite understood how.

So far this is what my added script looks like:

(Note: Only tested in a stripped script, no bugs detected.)

 

My create_thread lines:

 

004F: create_thread ££LabelAiHelper004F: create_thread ££LabelFollowMe00D7: create_thread_with_wasted_busted_check ££LabelBusted

 

 

Placed in Main:

 

:LabelAiHelper03A4: name_thread "AI"0111: set_wasted_busted_check_to  1 (enabled):LabelRequest0001: wait  3000 ms0004: $Busted =  0 ;; integer values0247: request_model #PGA0247: request_model  #ruger038B: load_requested_models:LabelBusted0001: wait  0 ms00D6: if  1      8256:   NOT   player $PLAYER_CHAR defined0112:   wasted or busted004D: jump_if_false ££LabelLoadModel0004: $Busted =  1:LabelLoadModel0001: wait  1000 ms00D6: if  30118:   actor $6 dead0248:   model #PGA available0248:   model  #ruger available0038:   $528 ==  0 ;; integer values004D: jump_if_false ££LabelLoadModel04C4: create_coordinate  [email protected]  [email protected]  [email protected] from_actor $PLAYER_ACTOR offset  1.0  0.0  0.0009A: $6 = create_actor  19 #PGA at  [email protected]  [email protected]  [email protected]: give actor $6 weapon  27 ammo  999902E2: set actor $6 weapon accuracy to  10002AB: set actor  $6 immunities  1  1  1  1  1022E: set player $PLAYER_CHAR to look at actor  $6:LabelFollowMe0001: wait  1000 ms00D6: if  18118:   NOT   actor $PLAYER_ACTOR dead8118:   NOT   actor $6 dead004D: jump_if_false ££DoOver01DF: tie actor $6 to player $PLAYER_CHAR0002: jump ££LabelFollowMe:DoOver 0249: release_model #PGA0249: release_model  #ruger01C2: remove references to actor $6009B: destroy actor instantly $60002: jump ££LabelRequest0459: end thread named "AI"

 

 

I may have stuff in there that's not necessary, but when it did what I wanted I just sat back and took a deep breath.

 

All this does is:

1. Spawn an actor armed with a Ruger who will follow me

2. He will attack who ever I attack (with a weapon, no response if I attack bare-handed)

3. And just for fun Tommy always watches the actor as if he wonders why he's being followed.

 

 

At first I had a bit of trouble. The actor wouldn't always respawn especially after being busted. He'd end up frozen in place near where I'd gotten busted (on foot or in car). I think I've got it running pretty smoothly, but I'm having a bit of trouble figuring out how to manipulate the actor. For example:

 

 

0243: set_actor $14A ped_stats_to  16

 

 

I'm unsure how to use this or what the different ped_stats are. I've looked at the Vice City 2004 script for the body guards script and tried to follow it. One body guard "Natasha" I think (found upstairs in Ocean View Hotel) doesn't like cops and shoots them on sight, but I'm not sure how to go about this. When I use the 0243: set_actor $14A ped_stats_to ?, I've tried different numbers seen in the body guard script but with no noticeable effect.

Can I specify things for the actor to attack on sight (cops, gangs, cop car, etc.)

Can I make the actor attack those who attack me (auto attack w/out me attacking them to trigger the actors attack)?

As usual any advice or suggestions are appreciated.

Edited by Knowledge Novice

Share this post


Link to post
Share on other sites
Demarest

Well no offense, but I don't find it wise to wish to get straight into new missions. It's much wiser to wait until the basics are thoroughly grasped before taking the next step, which still woudln't be new missions.

 

Right off the bat, I notice you have 3 create threads but only one thread. And since the code runs linearly, you essentially have 3 threads doing the same thing. Since you used globals (and worse: DMA), the 3 threads will be fighting over which one is telling who to do what.

 

Next, I've noticed that one of the threads was created with a WB check and the first paragraph also enables the WB check. I've been coding for over 3 years and I've never had the use for either. Not saying there's no use, but I am saying that it's VERY easy to do any number of things without having to specify such things. Regular threads will return true for WB checks that occur fast enough and mission threads already have it built in. So really probably not something you should be just tossing in there until an actual need arises, which I don't foresee.

 

Next, your 2nd paragraph has a wait 3000 right off the bat. The thread just started, so no reason for that. If it's to delay the jumpack at the end of the code, there there's really no reason to not have the wait down there instead.

 

After that, I notice that you have a busted flag, but nothing that ever checks or it changes the way it operates based on the value of that flag. So really, the flag is unnecessary. Also, a WB check should not be lumped with a player defined check. For one, they're superfluous. The ONLY time is player defined returns false is if wasted or busted. You see WB checks in missions because of the way mission threads work (the MB covers this a bit). See, the whole reason missions have gosubs in the beginning instead of just running the code is because if you get wasted/busted, the mission is truncated and the gosub automatically returns. So the reason there's a WB check then is to see if the gosub before it was returned because the mission told it to or because it was truncated due to being wasted/busted. This is so a generic mission failed scenario can be satisfied. For example, say a mission has you paired with a partner. The code is going to regularly check if your buddy is dead and if so, display a mission failed message as well as maybe a "hey, your dude perished" or something to that effect. But no such message if YOU are killed. So it uses a WB check as a catch all to pave the way for such a message. No more no less. Threads in MAIN do not have this luxury. MAYBE if the WB is enabled it will, but again, you don't have any gosubs and your thread does nothing besides set a flag in the event that you DO trip it. Not that that particular check is looped at all.

 

Your next paragraph starts off with an if loaded clump, but has a wait of 1000. The wait for an is loaded loop should always be 0 as it's nearly instantaneous anyways. No need to drag the thread down without a purpose. At the same time, you follow it with a command that refers to the player. Since a wait has occured since the last player defined check, you're risking a crash. You'll need another. OR grab the coordinates after established the player exists in the preceeding paragraph. Since the load will be almost instantaneous anyways. Also, when I was developing Neo, I came face to face with a very odd occurance in GTA engines. To read a player's position, it returns the Z value of your abdomen (center). When using put/create actor commands though, it's referring to their feet (bottom). So when you're creating coordinates, it will read from your chest a value that you later use to create an actor. If you make your Z offset -1.0 (the difference), you'll find that the guy you spawn won't "fall into existence" but will instead be safely grounded to start with. Things like this discrepency as well as the mission return things aren't things you can really know. It just comes with experience and talking to others that already know, so don't feel bad about them. Also, I noticed this clump has an if actor dead check. There is no purpose for this. On initial run, there is NO actor and on subsequent occurances, you've already destroyed that actor.

 

This next point is a sore one because I've already made it. You're using DMA here and you should not do that unless you know what you're doing AND it's necessary. Use $MYACTOR or some other custom label if you insist on not using locals. Using DMA only paves the way for problems that may not even be obvious as to the cause. Also, you check $528 (another DMA), but I see nothing that alters its value, so it's really not necessary.

 

In your followme paragraph, you check if actor $PLAYER_ACTOR is dead. You don't check if you are dead in this manner. You use if player defined. Also, you only need to issue the tie actor command once. Looping it doesn't accomplish anything.

 

Next, your code at the very end releases the models you've used, only to turn around and reload them. Once loaded, they will stay loaded until you issue these commands. So if you have every intention of using them repeatedly, you may want to just leave them loaded the entire time. If not, then you'll want to release them the moment you're done with them. That is, right after you've spawned the guy and again after you've armed him. Otherwise, you've gained nothing in terms of cleanliness since they will continue to occupy game memory. Also, remove references to actor will allow him to act like a normal ped. Destroying him instantly does just that. If you're going to do one, the other is unnecessary. They're both cleanup commands, so there's no potential for crashing the game. Still, it's unnecessary and I thought I'd mention it.

 

Finally, your last command comes after a jump, so it will never be run. If a command will never be run, it shouldn't be there. Also, you meant end_thread, not end_thread_named. Not that you need to end a thread that's constantly running. The game knows not where threads "begin" and "end". You don't need to use the command to fence it off in the SCM; only to actually end a thread. So if you wanted this thread to end at some point, you'd use end_thread and you'd put it in a place that would actually get ran. end_thread_named is a way for thread A to kill thread B. Mostly not needed, but a cool option to have nonetheless.

 

To answer your ped disposition questions, I think cops and such qualify as gangs and therefore yes, you could teach an actor to have a disposition against them. And if I'm not too much mistaken, this WILL cause them to attack such people without you having to attack them first. However, I personaly have dealt with ped attributes very little, so should probably leave it at that.

 

At any rate, using the tips above, your code would look more LIKE...

 

 

:LabelAiHelper03A4: name_thread "AI":LabelRequest0247: request_model #PGA0247: request_model  #ruger038B: load_requested_models:LabelLoadModel0001: wait  0 ms00D6: if  20256:   player $PLAYER_CHAR defined0248:   model #PGA available0248:   model  #ruger available004D: jump_if_false ££LabelLoadModel04C4: create_coordinate  [email protected]  [email protected]  [email protected] from_actor $PLAYER_ACTOR offset  1.0  0.0 -1.0009A: @0 = create_actor  19 #PGA at  [email protected]  [email protected]  [email protected]: release_model #PGA01B2: give actor @0 weapon  27 ammo  99990249: release_model  #ruger02E2: set actor @0 weapon accuracy to  10002AB: set actor  @0 immunities  1  1  1  1  1022E: set player $PLAYER_CHAR to look at actor @001DF: tie actor @0 to player $PLAYER_CHAR:LabelFollowMe0001: wait  1000 ms00D6: if  00118:    actor @0 dead004D: jump_if_false ££LabelFollowMe01C2: remove references to actor @00002: jump ££LabelRequest

 

 

You'll noticed I flipped your last if check. Anytime you have a JF to the very next paragraph followed by a jump with no commands inbetween, you can flip the check to make the code more efficient as well as cleaner looking. This requires you to flip each conditional and if it was an AND check, flip it to an OR check and vice versa. That last part obviously doesn't apply to if's with a single conditional.

 

Any questions, ask away.

Share this post


Link to post
Share on other sites
Knowledge Novice

First of all I know your right. The basics come first. I guess I got a little anxious to learn more and forgot about my baby steps, sorry.

About my create_threads - I remeber now that the "create_thread ££LabelFollowMe" wasn't needed and now I know that I don't have to create a BW check. That BW check was giving me a major dilemma and would have continued to plague me. Again you've cleared the way to better understanding. And though we both know I'll make more mistakes and that my script was likely to crash my game, I feel I'm learning bits along the way. After all it's not too long ago that I wouldn't have made it as far as I did much less got it to work (even though it was a bit sickly).

Also

 

 

This next point is a sore one because I've already made it. You're using DMA here and you should not do that unless you know what you're doing AND it's necessary.

 

The '$' is for Global while '@' is local (I should have used local). I didn't mean to ignore your advice, just a mix up on my part. I hate to ask for fear that I'm just missing it, but what does DMA stand for?

 

After inserting your script things ran more smoothly. The actor is with me from the start instead of dropping down like you mentioned. He respawned after he or I died, but there was one problem. If I got busted he would freeze in place or simply disappear. If he froze in place killing him would cause him to respawn, but if he disappeared I would have to die before he respawned. After placing

 

 

8256:   NOT   player $PLAYER_CHAR defined

 

 

in the :LabelFollowMe and changing it from an IF to an OR statement it seems to be fixed.

 

The final script:

 

:LabelAiHelper03A4: name_thread "AI":LabelRequest0247: request_model #PGA0247: request_model  #ruger038B: load_requested_models:LabelLoadModel0001: wait  0 ms00D6: if  20256:   player $PLAYER_CHAR defined0248:   model #PGA available0248:   model  #ruger available004D: jump_if_false ££LabelLoadModel04C4: create_coordinate  [email protected]  [email protected]  [email protected] from_actor $PLAYER_ACTOR offset  1.0  0.0 -1.0009A: [email protected] = create_actor  19 #PGA at  [email protected]  [email protected]  [email protected]: release_model #PGA01B2: give actor [email protected] weapon  27 ammo  99990249: release_model  #ruger02E2: set actor [email protected] weapon accuracy to  10002AB: set actor  [email protected] immunities  1  1  1  1  1022E: set player $PLAYER_CHAR to look at actor [email protected]: tie actor [email protected] to player $PLAYER_CHAR:LabelFollowMe0001: wait  1000 ms00D6: if  210118:    actor [email protected] dead8256:   NOT   player $PLAYER_CHAR defined004D: jump_if_false ££LabelFollowMe01C2: remove references to actor [email protected]: jump ££LabelRequest

 

 

Many thanks and (as usual) feedback is appreciated.

 

**P.S. With all the different possibilities is there any certain direction you would suggest taking in order to hone my basic skills. When I mentioned making missions it was partly from lack of direction and in hopes that attemting to create a mission would lead me to learning something new, which is my main concern at this point.

 

 

 

 

 

 

Edited by Knowledge Novice

Share this post


Link to post
Share on other sites
Demarest

I hate to ask for fear that I'm just missing it, but what does DMA stand for?
Now's a good time to learn to reconsult the readme as needed wink.gif DMA = Direct Memory Access. Traditionally, when MB goes to compile, it takes all the $X (where X is a number) and compiles them as global vars in the DMA the number indicates. Once that's finished, all the $MYVAR and other custom labeled vars are then added to the pile wherever they can be fit in. Where's the problem? Say you took your mod here and added it to the original game. Or worse, somebody read it and added it to their game themselves. In the original game, $6 and $528 meant something else. So essentially your mod and something else were referring to 2 different things entirely, but were instructed to use the exact same thing. So while your mod would create an actor at $6, maybe other code would later set $6 to some value and when your mod hits an actor $6 command, it will crash. Use locals instead or custom labelled vars and you no longer make this risk.

 

That said, there ARE times when DMA is necessary and that might be beyond the current discussion. It should also be noted that it's been my experience that SAMB in particular is NOT as efficient in mapping out where to place custom labelled globals. If I had to guess, this would be due to the implimentation of arrays that can potentially leave MB unable to determine how many slots to allocate for a DMA slot used in the original code. Finally, the way MB compiles/decompiles code and handles globals, this is also a good time to share why it's important to hold onto the TXT files (source code) of any work you engage in. Start a new "mod" and you should be using a new TXT source code. That way if you later wish to alter your mod, not only will it load faster, but any custom labels you've used will be preserved. This not only makes it easier for you to read, but avoids what was once custom vars from becoming DMA. Which at that point would be no harm, but strays you further from original code which gains NOTHING.

 

 

    After inserting your script things ran more smoothly. The actor is with me from the start instead of dropping down like you mentioned. He respawned after he or I died, but there was one problem. If I got busted he would freeze in place or simply disappear. If he froze in place killing him would cause him to respawn, but if he disappeared I would have to die before he respawned. After placing

 

 

8256:   NOT   player $PLAYER_CHAR defined

 

 

in the :LabelFollowMe and changing it from an IF to an OR statement it seems to be fixed.

Nice job. You've identified a problem and you've implimented a solution colgate.gif

 

 

**P.S.  With all the different possibilities is there any certain direction you would suggest taking in order to hone my basic skills. When I mentioned making missions it was partly from lack of direction and in hopes that attemting to create a mission would lead me to learning something new, which is my main concern at this point.
I certainly feel your pain. I have the same problem often; I have the ability to whip up some pretty wicked sh*t, but don't always have the inspiration to go in a certain direction. Take my recent Thrist For Blood. That stemmed initially from me exploring ONE opcode and its effects ingame. Or how about Pillager? That started off as me realizing there's an opcode that will sniff out a tag based on a particular XYZ you feed it. Then I just go from there.

 

One exercise you might benefit from is: Download a mod. Any old SMALL script mod will do. Play with it ingame. Get a feel for how it behaves. Then go to a stripped SCM and see if you can reproduce it. If something's not working, try to figure out why, keeping in mind that at any time, you have a perfectly good reference in front of you. OR if you're not comfy trying to draft the unfamiliar, just sit back and read its code. See if you can follow along what it's supposed to do and how/why. If not, look it up, make a routine that dabbles in it, etc. I again refer to my Neo series as I first got into that when I was brand new to coding. I had an idea and I made it work. Then from there, I prettied it up, made it run smoother, and just continued to build upon it. It's a process. One you'll get into without any problems; I can tell.

 

Last but not least, I suppose you could read the requests thread/forum and see what kind of things people are asking for. Usually it's dreamers who'd like to be able to press one button and blow up half the city. Other times though, it could be something actually pretty simple from a coder's point of view and just not in their effort level. You could kick around the INI to see what different opcodes are named; see if any pique your interest and inspire you to play with them. You could think of what YOU'D like to accomplish ingame and try to make it a reality. Or read original code, look at particular missions and say "how'd they do this?" It really is a matter of having TOO MANY options wink.gif

Share this post


Link to post
Share on other sites
Knowledge Novice

FINALLY! I thought the site had dissapeared. I've been getting a "Page not found" error.

 

Last time you mentioned spawning the Corpse. I thought it best to respond here since I started this topic. I'm not sure if it matters, I just didn't want to clutter someone else's discussion.

 

**THIS IS FOR GTA3**

What it does: All cars get Immunities, very Heavy, Invulnerable tires, clears wanted level, and fills Life and Armor to 100 (except Corpse). The Corpse gets all benefits [except Immunities]. It gives a Shotgun and will fill it's ammo to a max of 10. It will also Set the weather to be stormy (weather is Released when getting out of Corpse). I took the Immunities off the Corpse because it wouldn't be as cool if you couldn't damage the trunk to expose the body (besides it gives a weapon and there are plenty of other tough cars).

 

Add to Create_thread:

 

004F: create_thread ££ToughCar

 

 

Add just before -MISSION 0-

 

:ToughCar03A4: name thread "Tough"  :InCar0001: wait  50 ms00D6: if  00256:   player $PLAYER_CHAR defined004D: jump_if_false ££InCar00D6: if  000E0:   player $PLAYER_CHAR driving004D: jump_if_false ££InCar03C1:  [email protected] = player $PLAYER_CHAR car0419: [email protected] = player $PLAYER_CHAR weapon  4 ammo01EC: make_car  [email protected] very_heavy  1053F: set_car  [email protected] tires_vulnerable  002AC: set_car  [email protected] immunities  1  1  1  1  10110: clear_player $PLAYER_CHAR wanted_level035E: set_player $PLAYER_CHAR armour_to  1000222: set_player $PLAYER_CHAR health_to  10000D6: if  0 00DE:   player $PLAYER_CHAR driving vehicle type #CORPSE004D: jump_if_false ££Check 01B6: set_weather  202AC: set_car  [email protected] immunities  0  0  0  0  001B1: give player $PLAYER_CHAR weapon  4 ammo  000D6: if  0  002A:    9 >= [email protected] ;; integer values004D: jump_if_false ££Check017A: set player $PLAYER_CHAR weapon  4 ammo to  10:Check0001: wait  50 ms00D6: if  00256:   player $PLAYER_CHAR defined004D: jump_if_false ££OutOfCAr00D6: if  080E0:   NOT   player $PLAYER_CHAR driving004D: jump_if_false ££Check:OutOfCar00D6: if  08119:   NOT   car  [email protected] wrecked004D: jump_if_false ££Remove01EC: make_car  [email protected] very_heavy  0053F: set_car  [email protected] tires_vulnerable  102AC: set_car  [email protected] immunities  0  0  0  0  001B7: release weather:Remove01C3: remove_references_to_car  [email protected] ;; Like turning a car into any random car0002: jump ££InCar

 

 

 

Share this post


Link to post
Share on other sites
Demarest

 

**THIS IS FOR GTA3**

 

053F: set_car  [email protected] tires_vulnerable  0

 

Not only is 053F out of GTA3's range, but the GTA3 engine didn't support poppable tires dontgetit.gif This makes me wonder if you tested this code. If not, you should always post so just in case someting like this comes to light. I'd hate to see the eager new coder crashing his game like that wink.gif

 

The only critique I have--I don't remember the last time code was posted that I ONLY had one critique for wink.gif--is that release_weather strategically makes more sense in :Remove. OR before the if car wrecked check so that it's run regardless.

Share this post


Link to post
Share on other sites
Knowledge Novice

 

Not only is 053F out of GTA3's range, but the GTA3 engine didn't support poppable tires  This makes me wonder if you tested this code. If not, you should always post so just in case someting like this comes to light. I'd hate to see the eager new coder crashing his game like that

Oops. I guess I had Vice City on my mind. I did test it though and 053F didn't seem to have any noticeable side effects. I also see now why the Release_weather would go in Remove. Thanks.

----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------

Now something else I've been working with.

 

 

**This is for Vice City**

 

**I've tested this at least as far as the "Riot" mission, but have not finished the game with it. There are some glitches.

 

What it does:

All cars have Immunities, Invulnerable tires, very heavy, fill health+armor to 100. In addition a Romero spawns across from Ken's office (starting point of game). By pressing the Submission button you can activate/deactivate (there will be a sound) the Romero's extra stats: 1)ignored_by_everyone 2)sets game speed 3) sets weather 4) sets clock to a fixed position. Also if you press the Horn while your vehicle is flipped it will turn right side up again, this also restores the vehicle's health if it catches fire before you turn it back over.

 

Problems:

The only problems I have encountered seem to be associated with the Romero. For instance: 1)After some missions (completed in a Romero) the weather becomes eratic and quickly changes from one weather setting to another. 2)During a mission, any time the game takes control in order to tell you info etc. you lose your Ignored by everyone stat. This can be fixed by turning the Romero's stats off then back on. 3) If you have enabled your Romero stats during a mission, they seem to automatically turn off after the mission is finished.(That's usually when the weather decides to go crazy)

 

Why I did things:

All the cars have Immunities because tough cars a cool. Invulnerable tires because driving an indestructable car with no traction ain't much fun. Then the Romero. I found that I could spawn it, cool. I learned that I could change the weather and game clock, super. Knowing these things I decided to have the Romero change the weather and time to seem gloomy while driving it just for fun.

 

Spawns a Romero across from Ken's office (the lawyer)

 

014B: $15 = init_parked_car_generator #ROMERO  0  0  0 alarm  0 door_lock  0  0  10000 at  92.39964 -817.7905  10.46329 angle  180014C: set_parked_car_generator $15 cars_to_generate_to  101

 

 

Create thread

 

004F: create_thread ££NameIt

 

 

Placed just above --Mission 0--

 

:NameIt03A4: name_thread "GLOOM+":SetStats0001: wait  500 ms00D6: if  00256:   player $PLAYER_CHAR defined004D: jump_if_false ££SetStats00D6: if  000E0:   player $PLAYER_CHAR driving004D: jump_if_false ££SetStats03C1:  [email protected] = player $PLAYER_CHAR car01EC: make_car  [email protected] very_heavy  .5053F: set_car  [email protected] tires_vulnerable  002AC: set_car  [email protected] immunities  1  1  1  1  1035E: set_player $PLAYER_CHAR armour_to  1000222: set_player $PLAYER_CHAR health_to  10000D6: if  000DE:   player $PLAYER_CHAR driving_vehicle_type #ROMERO004D: jump_if_false ££Check  :StealthRomero0001: wait  50 ms00D6: if  080E1:   NOT   key_pressed  0  18004D: jump_if_false ££TurnOver00D6: if  000DE:   player $PLAYER_CHAR driving_vehicle_type #ROMERO004D: jump_if_false ££Check00D6: if  000E1:   key_pressed  0  19004D: jump_if_false ££StealthRomero01B6: set_weather  1003BF: set_player $PLAYER_CHAR ignored_by_everyone_to  1 (true)015D: set_gamespeed  .8018C: play_sound  10 at  0  0  00001: wait  1000 ms:RomeroTime0001: wait  50 ms00D6: if  080E1:   NOT   key_pressed  0  18004D: jump_if_false ££TurnOver00D6: if  000DE:   player $PLAYER_CHAR driving_vehicle_type #ROMERO004D: jump_if_false ££Check00C0: set_current_time  8  000D6: if  000E1:   key_pressed  0  19004D: jump_if_false ££RomeroTime01B7: release weather03BF: set_player $PLAYER_CHAR ignored_by_everyone_to  0 (false)015D: set_gamespeed  1.0018C: play_sound  10 at  0  0  00001: wait 200 ms018C: play_sound  1 at  0  0  00001: wait 200 ms018C: play_sound  10 at  0  0  00001: wait  1000 ms:Check0001: wait  50 ms00D6: if  080E1:   NOT   key_pressed  0  18004D: jump_if_false ££TurnOver00D6: if  080DE:   NOT   player $PLAYER_CHAR driving_vehicle_type #ROMERO004D: jump_if_false ££StealthRomero00D6: if  00256:   player $PLAYER_CHAR defined004D: jump_if_false ££LoseStats00D6: if  080E0:   NOT   player $PLAYER_CHAR driving004D: jump_if_false ££Check:LoseStats0001: wait  0 ms00D6: if  08119:   NOT   car  [email protected] wrecked004D: jump_if_false ££Remove01EC: make_car  [email protected] very_heavy  0053F: set_car  [email protected] tires_vulnerable  102AC: set_car  [email protected] immunities  0  0  0  0  0:Remove01B7: release weather03BF: set_player $PLAYER_CHAR ignored_by_everyone_to  0 (false)015D: set_gamespeed  1.001C3: remove_references_to_car  [email protected];; Like turning a car into any random car0002: jump ££SetStats:TurnOver0001: wait 0 ms00D6: if  001F4:   car  [email protected] flipped004D: jump_if_false ££Check00AA: store car [email protected] position to [email protected] [email protected] [email protected]  0174: [email protected] = car [email protected] z angle00AB: put car  [email protected] at  [email protected]  [email protected]  [email protected]: set car [email protected] z angle to [email protected]: set car [email protected] health to  20000002: jump ££Check

 

 

I just hope I didn't make too many mistakes. smile.gif

Edited by Knowledge Novice

Share this post


Link to post
Share on other sites
Demarest
I just hope I didn't make too many mistakes. smile.gif

moto_whistle.gif

 

First and foremost, your parked car generator was established using DMA. I'm certain I've mentioned such practices more than once sad.gif

 

I can see a few points where player was referenced without being checked first.

 

Also, you can see a lot of redundant code. SOMETIMES this is necessary. I'm almost certain this isn't one of those times. Since you have locals to spare, have you considered making use of flags? If the keypress conditions are met to your liking, check an on/off flag. If the flag is off, set the items you need to and set the flag to on. Or vice versa. Would probably save tons of space.

 

Passing missions can impact this mod in the ways you describe because a lot of missions have release_weather and such built in. I've also seen the command mission_cleanup produce some funky results as well.

 

Rather than wait 1000's, you'd have a smoother, more "professional" mod by taking the time to check for key releases instead.

 

Also, are you sure that the make car heavy command is actually doing anything? Research indicates it's a toggle, which means it only accepts values of 0 or 1. You're feeding it a float. You're lucky it doesn't crash the game.

Share this post


Link to post
Share on other sites
Knowledge Novice

 

First and foremost, your parked car generator was established using DMA. I'm certain I've mentioned such practices more than once

True. Carelessness on my part. I believe I originally used $MyRomero to name my generator, but here I copied it from a decompiled SCM and forgot to rename it. anuj_cop.gif

 

I can see a few points where player was referenced without being checked first.

I think I see where you mean. There are places where I neglected to put a Player_defined check and maybe in some loops where they may be needed?

 

Also, you can see a lot of redundant code. SOMETIMES this is necessary. I'm almost certain this isn't one of those times. Since you have locals to spare, have you considered making use of flags?

I was afraid it may be a bit cluttered. I grasp the difference between Global($) and Local(@) variables now, but I've had no experience with Flags. The Readme file that came with the MB is invaluable in learning the basics needed to code. But the only part I can find that mentions Flags is simply showing examples of Inclusive and Exclusive checks. I don't see any actual examples on how to use Flags. If there is info in the Readme that I'm simply missing I'm sure I'll eventually get it. I'll try to find more info myself but if you know of any tutorial or mod in particular that I may find useful in understanding better I'd appreciate any suggestions.

 

Rather than wait 1000's, you'd have a smoother, more "professional" mod by taking the time to check for key releases instead.

I'm trying to wrap my head around this one, but I'm not sure how to do this either. Do I use

 

00D6: if  080E1:   NOT   key_pressed  0  19004D: jump_if_false ££

 

instead of

 

0001: wait  1000 ms

 

 

Also, are you sure that the make car heavy command is actually doing anything? Research indicates it's a toggle, which means it only accepts values of 0 or 1. You're feeding it a float. You're lucky it doesn't crash 

Another mistake on my part. I wasn't aware that it was a toggle so I tried experimenting a bit. Actually I figured it may need an integer because there was no decimal, but since the game didn't crash I forgot to go back and change it. suicidal.gif

 

 

 

 

 

Share this post


Link to post
Share on other sites
Demarest

Well a variable can be used for whatever you want. If you choose to use it as a flag, then whether it's set as 0 or 1 is how your code will know if something's currently on or off. So you have the same requisites for triggering a function, then you have the function's first duty being to check the flag. If it's equal to 0, then you function is off, so turn it on and set the flag to 1 so your code knows it's on. Otherwise, turn it off and set your flag to 0 so your code knows it's off.

 

A key release loop is just like a keypress loop except that you want it to be trapped in its own loop until the key is no longer being pressed.

Share this post


Link to post
Share on other sites
Knowledge Novice

It's been a little while since I last posted. Last time you suggested looping my code instead of using the Wait command. Also, you suggested using Flags.

 

To loop my code I changed the Wait 1000's to Loop1 and Loop2 and added these:

 

:Loop10001: wait  250 ms00D6: if  0 00E1:   key_pressed  0  19004D: jump_if_false ££RomeroTime0002: jump ££Loop1 :Loop20001: wait  250 ms00D6: if  0 00E1:   key_pressed  0  19004D: jump_if_false ££StealthRomero         0002: jump ££Loop2

 

This one seems simple enough, but until I got it to work I thought I'd never figure it out. I don't know if this is the best way, but it gives me the desired effect.

 

Unfortunately I haven't made any progress with Flags. You've told me that 0 is off and 1 is on, but I'm still not sure how to use this. To be honest I feel completely lost. I see the opcodes that say "Reset_Actor [email protected] flags", but I can't seem to get them to work and I'm not even sure how to attempt to set a flag for a car. I've been searching through different scm's and mods, although they usually leave me a bit confused. I've also been trying to find any tutorial or other info that may give me a more specific example of how to use flags but I haven't found anything yet. I know the answer is right in front of me, but I just don't get it. sad.gif

My code now:

 

014B: $MyRomero = init_parked_car_generator #ROMERO  0  0  0 alarm  0 door_lock  0  0  10000 at  92.39964 -817.7905  10.46329 angle  180014C: set_parked_car_generator $MyRomero cars_to_generate_to  101:NameIt03A4: name_thread "GLOOM+":SetStats0001: wait  500 ms00D6: if  00256:   player $PLAYER_CHAR defined004D: jump_if_false ££SetStats00D6: if  000E0:   player $PLAYER_CHAR driving004D: jump_if_false ££SetStats03C1:  [email protected] = player $PLAYER_CHAR car01EC: make_car  [email protected] very_heavy  1053F: set_car  [email protected] tires_vulnerable  002AC: set_car  [email protected] immunities  1  1  1  1  1035E: set_player $PLAYER_CHAR armour_to  1000222: set_player $PLAYER_CHAR health_to  10000D6: if  000DE:   player $PLAYER_CHAR driving_vehicle_type #ROMERO004D: jump_if_false ££Check  :StealthRomero0001: wait  50 ms00D6: if  00256:   player $PLAYER_CHAR defined004D: jump_if_false ££Check00D6: if  080E1:   NOT   key_pressed  0  18004D: jump_if_false ££TurnOver00D6: if  000DE:   player $PLAYER_CHAR driving_vehicle_type #ROMERO004D: jump_if_false ££Check00D6: if  000E1:   key_pressed  0  19004D: jump_if_false ££StealthRomero01B6: set_weather  1003BF: set_player $PLAYER_CHAR ignored_by_everyone_to  1 (true)015D: set_gamespeed  .8018C: play_sound  1 at  0  0  00002: jump ££Loop1:RomeroTime0001: wait  50 ms00D6: if  00256:   player $PLAYER_CHAR defined004D: jump_if_false ££Check00D6: if  080E1:   NOT   key_pressed  0  18004D: jump_if_false ££TurnOver00D6: if  000DE:   player $PLAYER_CHAR driving_vehicle_type #ROMERO004D: jump_if_false ££Check00C0: set_current_time  8  000D6: if  000E1:   key_pressed  0  19004D: jump_if_false ££RomeroTime01B7: release weather03BF: set_player $PLAYER_CHAR ignored_by_everyone_to  0 (false)015D: set_gamespeed  1.0018C: play_sound  1 at  0  0  00001: wait 200 ms018C: play_sound  1 at  0  0  00001: wait 200 ms018C: play_sound  1 at  0  0  00002: jump ££Loop2:Check0001: wait  50 ms00D6: if  00256:   player $PLAYER_CHAR defined004D: jump_if_false ££LoseStats00D6: if  080E1:   NOT   key_pressed  0  18004D: jump_if_false ££TurnOver00D6: if  080DE:   NOT   player $PLAYER_CHAR driving_vehicle_type #ROMERO004D: jump_if_false ££StealthRomero00D6: if  080E0:   NOT   player $PLAYER_CHAR driving004D: jump_if_false ££Check:LoseStats0001: wait  0 ms00D6: if  08119:   NOT   car  [email protected] wrecked004D: jump_if_false ££Remove01EC: make_car  [email protected] very_heavy  0053F: set_car  [email protected] tires_vulnerable  102AC: set_car  [email protected] immunities  0  0  0  0  0:Remove01B7: release weather03BF: set_player $PLAYER_CHAR ignored_by_everyone_to  0 (false)015D: set_gamespeed  1.001C3: remove_references_to_car  [email protected] ;; Like turning a car into any random car0002: jump ££SetStats:TurnOver0001: wait 0 ms00D6: if  001F4:   car  [email protected] flipped004D: jump_if_false ££Check00AA: store car [email protected] position to [email protected] [email protected] [email protected]  0174: [email protected] = car [email protected] z angle00AB: put car  [email protected] at  [email protected]  [email protected]  [email protected]: set car [email protected] z angle to [email protected]: set car [email protected] health to  20000002: jump ££Check:Loop10001: wait  250 ms00D6: if  0 00E1:   key_pressed  0  19004D: jump_if_false ££RomeroTime0002: jump ££Loop1 :Loop20001: wait  250 ms00D6: if  0 00E1:   key_pressed  0  19004D: jump_if_false ££StealthRomero         0002: jump ££Loop2

 

Share this post


Link to post
Share on other sites
Bigun

 

Unfortunately I haven't made any progress with Flags. You've told me that 0 is off and 1 is on, but I'm still not sure how to use this. To be honest I feel completely lost. I see the opcodes that say "Reset_Actor [email protected] flags", but I can't seem to get them to work and I'm not even sure how to attempt to set a flag for a car. I've been searching through different scm's and mods, although they usually leave me a bit confused. I've also been trying to find any tutorial or other info that may give me a more specific example of how to use flags but I haven't found anything yet. I know the answer is right in front of me, but I just don't get it. sad.gif

No, no no. You got it all wrong... re-read Dem's post. Unfortunately - you CAN'T specify custom flags for actors/vehicles/objects, it would be nice if you could (you can attempt to use already-in-game but unused/useless flags) BUT that isn't what you need to do here at all. Dem didnt mean object flags, he meant use a var in that thread as a flag... Just like you can assign vars to vehicles and people, you can assign them to just numbers (integers or floats) as well and then check them. 0 is off and 1 is on because YOU decide to code it that way (preferably since it is widely common that 0 is off and 1 is on in computing), if you wanted you could set them to 7099 and 2077 and check for those values instead.

psuedo-code using flags:

 

:mod_1wait 1000if 1player $player_char definedkey_pressed Xjump_if_false mod_1if 0key_pressed Yjump_if_false mod_20006: @0 = 1;; integer values; ^^^above line sets local var @0 the integer value 1:mod_2do_stuff;- - - - - - - - - - - later on in the codeif 00039:   @0 ==  1;; integer valuesjump_if_false mod_somelabeldo_other_stuff_here

 

 

That should clear it up.

Important note: There are 2 datatypes for numerical values: floats ("unfull" (dont remember exact wording) numbers, used for things like percents and coordinates - example: 5.317001. when using them for things like coords that it doesnt really matter you CAN use '5.0', but you SHOULDNT use just '5' or you can get unexpected results) and integers (full numbers, like '5'. used to specify a lot of things like values, flags, actions).

The bigger deal is, opcodes (opcodes that set vars as well) are type-specific and var-specific (specific to global OR local vars) so you need to use the right ones.

For example, 0006 is used to set a LOCAL var to an INTEGER. 0004 is used to set a GLOBAL var to an INTEGER, 0005 is used to set a GLOBAL var to a FLOAT, 0039 is used to check a LOCAL var for an INTEGER value, 0042 is used to check a GLOBAL var for a FLOAT, 003B is used to check if 2 LOCAL vars with INTEGER values are equal, and so on. So make sure you use the right opcodes with right data-types (actually if you'll only be using flags all you'll really need for now are 0006 and 0039) - consult original code as well as the opcode database to find needed opcodes. Typhing things like "+=","==" and "=" in MB then pressing F1 to find opcodes also works. Note that in the end of opcodes there is a comment that specifies whether it uses integer values or float values (to know if it uses global or local vars or both you will need to check original code (or F1 function)).

Another note, just for your information there are opcodes that can convert integers to floats and vice versa.

 

If you don't understand anything, just post. smile.gif

 

EDIT: Forgot this is about VC. blush.gif Of course the info is still relevant - but opcodes I mentioned are from SA and some may be different than in VC (though actually I'm pretty sure THESE opcodes are the same in all games), so consult VC's original code and opcode database.

Edited by Bigun

Share this post


Link to post
Share on other sites
ceedj

Excellent post Bigun. A ton of useful information that, for me in the beginning, was not really discussed a whole lot in the tutorials I read at the time. Especially useful is the flags discussion, and how they can be used to "sniff" for certain events. Very insightful; perhaps someone should write an expanded tutorial on basics like these? icon14.gif

Share this post


Link to post
Share on other sites
Bigun

Thanks. The actual code example could of been better though. Yes, I didn't see that explained before, learned it myself from original code mostly. Expanded tutorial? Well, with other things yes (only this is too simple for a tut), someone should write one. Maybe I should, there are too many rather basic things that aren't covered properly that I know - hell, sometimes I need to take a pause when coding to think about some things (usually a bit more complex than this, though), which a proper documentation/explanation on would save doubts. Care to PM me some list of subjects you'd want covered in my tutorial if I'll end up making it (same for others as well that may have questions) ?

Share this post


Link to post
Share on other sites
Knowledge Novice

Thanks for the specifics on what opcodes to use. I saw several dealing with integer value and wasn't sure of the differences between them. That being said, I'm still stuck.

While trying to figure things out I found myself replacing opcode commands with flags. By this I mean at the first instance of each different command I would set a flag, then use that flag throughout the rest of my code.

Example:

 

:SetStats0001: wait  500 ms00D6: if  00256:   player $PLAYER_CHAR defined004D: jump_if_false ££SetStats0006:  [email protected] =  1 ;; integer values00D6: if  0  00E0:   player $PLAYER_CHAR driving004D: jump_if_false ££SetStats0006:  [email protected] =  1 ;; integer values03C1:  [email protected] = player $PLAYER_CHAR car01EC: make_car  [email protected] very_heavy  1053F: set_car  [email protected] tires_vulnerable  002AC: set_car  [email protected] immunities  1  1  1  1  1035E: set_player $PLAYER_CHAR armour_to  1000222: set_player $PLAYER_CHAR health_to  10000D6: if  000DE:   player $PLAYER_CHAR driving_vehicle_type #ROMERO004D: jump_if_false ££Check0006:  [email protected] =  1 ;; integer values:StealthRomero0001: wait  50 ms00D6: if  10039:    [email protected] ==  1 ;; integer values0039:    [email protected] ==  1 ;; integer values004D: jump_if_false ££Check00D6: if  081F4:   NOT   car [email protected] flipped004D: jump_if_false ££TurnOver00D6: if  000E1:   key_pressed  0  19004D: jump_if_false ££StealthRomero01B6: set_weather  1003BF: set_player $PLAYER_CHAR ignored_by_everyone_to  1 (true)015D: set_gamespeed  .8018C: play_sound  1 at  0  0  00002: jump ££Loop1

 

I'm not sure if this makes any sense and I'm not even sure how I got to this point since I started out trying to use flags with key_presses like you guys had mentioned. confused.gif

 

I guess basically I'm still not getting it. I don't mean to be a dunce. I just don't quite grasp it yet. I'll continue to look through the original game code to see what I can find, but honestly at this point I'm not sure exactly what I'm looking for.

 

Some type of documentation/explanation would be fantastic since us begginers would be more likely to learn without asking so many questions or at least have questions that are more specific therefore easier to answer.

 

I also appreciate the code example, but I didn't quite understand it.

Just so I'll know, is there a better way to make a key_press release?

 

Thanks for helping. Any advice is appreciated.

Share this post


Link to post
Share on other sites
random_download

 

:loopwait 100if 1 player $player_char defined key_pressed Xjump_if_false ££loop // Loop until the key is pressedif 0 @0 == 0 // If this var is 0jump_if_false ££loop20006: @0 = 1;; integer values // Set it to 1 and turn features on// Code here to turn special features onjump ££loop:loop2 // If the var was not 00006: @0 = 0 // Make it equal to 0 and turn features off//Code to turn special features offjump ££loop

 

If you look at that code you should see it acts as a toggle. The code simply checks a variable, and executes different code depending upon what that variable is, and in the code that gets executed you swap the value of the variable, so next time it happens the other bit of code is executed, and the time after that the first bit is and so on.

Share this post


Link to post
Share on other sites
Knowledge Novice

Ok. I think I finally get it.

I left out the Set_current_time command because I wasn't sure how to fit it into the loop in a way that it could be toggled on/off and still keep a specific time.

I left out the Set_weather command because some weather is only useable at certain times of the day. (I had my weather set to 10 which is stormy w/black clouds and my time set to 8:00. Once the clock reaches about 22:00 I could no longer see myself or my surroundings.) Since the set_weather and set_time commands cause problems during missions it's no big loss, although I would be interested to know how to add the set_current_time command to this loop if it's possible.

 

Script now:

 

:StealthRomero0001: wait  100 ms   00D6: if  1          0256:   player $PLAYER_CHAR defined 00E1:   key_pressed  0  19004D: jump_if_false ££StealthRomero00D6: if  0                0039:    [email protected] ==  0 ;; integer values004D: jump_if_false ££StealthOff0006:  [email protected] =  1 ;; integer values 015D: set gamespeed  .803BF: set player $PLAYER_CHAR ignored by everyone to  1 (true)018C: play_sound  1 at  0  0  00002: jump ££Loop:StealthOff0006:  [email protected] =  0 ;; integer values         015D: set gamespeed  1.003BF: set player $PLAYER_CHAR ignored by everyone to  0 (false)018C: play_sound  1 at  0  0  00001: wait 200 ms018C: play_sound  1 at  0  0  00001: wait 200 ms018C: play_sound  1 at  0  0  0:Loop0001: wait  50 ms     00D6: if  0          80E1:   NOT   key_pressed  0  19004D: jump_if_false ££Loop0002: jump ££StealthRomero

 

 

I just added a key_press release loop at the end.

 

I get a thrill out of discovering on my own, but if it weren't for the patience and help of others I'd have far fewer thrills. Many thanks. colgate.gif

 

 

Share this post


Link to post
Share on other sites
Knowledge Novice

I've been wanting to learn more about dealing with peds and changing my characters appearance. If possible I'd like to use some of the peds in place of my player_char. While searching for info with this in mind I came across a discussion for a mod to set_wanted_level to 0 as long as player is wearing a cop uniform. It seemed a little complicated for me at this point, so for now I'll try something a little more simple.

I got this piece functional for the most part I believe, but there are still some bugs.

 

What it does - If your wanted_level is greater than 0, then your clothes are automatically changed and your wanted_level is cleared.

 

Known bugs - Sometimes when stealing a cop car the character seems to "flash" outside of the vehicle and once I was even trapped inside. While on a motorcycle the code functions normaly, but while in a car the characters clothes rarely change (although wanted level is still cleared). And, for reasons I don't yet understand, using "PLAYER1" in the code crashes the game.

 

Create thread

 

004F: create_thread ££NameIt

 

 

Script

 

:NameIt03A4: name thread "Schizo":Wanted0001: wait  50 ms00D6: if  10256:   player $PLAYER_CHAR defined010F:   player $PLAYER_CHAR wanted level >  0004D: jump_if_false ££Wanted:Skin10001: wait  50 ms00D6: 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:Skin20001: wait  50 ms00D6: 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                                               :Skin30001: wait  50 ms0006:  [email protected] =  0;; integer values0352: set_actor $PLAYER_ACTOR skin_to "PLAYER4"0050: gosub ££Refresh                         :Refresh038B: load_requested_models0353: refresh_actor $PLAYER_ACTOR0110: clear player $PLAYER_CHAR wanted level0002: jump ££Wanted

 

 

Questions: Do I need a Player_Defined check in :Refresh? And (as usual) how could I have done this better? Advice and suggestions always welcome.

Edited by Knowledge Novice

Share this post


Link to post
Share on other sites
random_download

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

 

:Wanted0001: wait  50 ms00D6: if  00256:   player $PLAYER_CHAR defined004D: jump_if_false ££Wanted00D6: if  0010F:   player $PLAYER_CHAR wanted level >  0004D: jump_if_false ££Wanted

 

This is because if the player is not defined, the game will still check to see if the wanted level is > 0 as you have not told it to jump back to :Wanted until it has checked both of them. This is not what you want as the wanted level opcode uses the $PLAYER_CHAR var, which could cause problems if it is not defined.

In each of your :Skin labels, you have a wait but no player_defined check. As a rule, you need to check if the player is defined before you use an opcode that references $PLAYER_CHAR or $PLAYER_ACTOR, and there has been a wait executed since the last player_defined check. In your code you could either remove the waits from the skin labels, or add a player_defined check into :Refresh to achieve this.

Share this post


Link to post
Share on other sites
Knowledge Novice

If the waits aren't necessary, I'll just remove them so as to save space. Another thing that came to mind is that, since I set the var [email protected] to label my_car, do I need to remove_references_to_car [email protected]? monocle.gif

 

Possible code:

 

:NameIt03A4: name thread "Pschizo":Wanted00D6: if  10256:   player $PLAYER_CHAR defined004D: jump_if_false ££Wanted00D6: if  0010F:   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"0050: gosub ££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"0050: gosub ££Refresh                                               :Skin30006:  [email protected] =  0 ;; integer values0352: set_actor $PLAYER_ACTOR skin_to "PLAYER4"0050: gosub ££Refresh                         :Refresh038B: load_requested_models0353: refresh_actor $PLAYER_ACTOR0110: clear player $PLAYER_CHAR wanted level00D6: 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

 

 

Also, are there any other skins I could use besides these three? I looked in the peds.dat and saw that in addition to Player1 through Player4 there was also SPECIAL, CIVMALE/FEMALE, COP, GANGS1 through GANGS9, EMERGENCY, CRIMINAL, and PROSTITUE but, besides the three I used, all others mentioned crash game. sad.gif

Share this post


Link to post
Share on other sites
ceedj

Some things I noticed:

 

1) "if" statements. Read the READ ME that came with MB, but short form, the code "if 0" means only one condition has to be true. "if 1" includes the AND statement, so two conditions have to be true. In your example in the Wanted section, your using an "if 1" with only one condition listed.

 

2) You never actually declare the [email protected] variable, except to reuse it near the end of the code. Personally, I would use a separate varible for the "flag check" and one for the car.

 

3) Stay away from gosubs without returns; use jumps instead.

 

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

 

5) 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.

 

Hope this helps. smile.gif

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.

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.


  • 2 Users Currently Viewing
    0 members, 0 Anonymous, 2 Guests

×
×
  • Create New...

Important Information

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