Jump to content

Getting Actor's Current Car


Panlantix

Recommended Posts

I am having trouble doing things with an actor's current car. This mod requires that it looks at ANY car that the actor is in, and not just a pre-made car because that one might become destroyed.

 

I have it coded so that he goes to a new car automatically, but once he is in, I need to know the health of that car, and if it gets set on fire, get out and go to another one. The problem I am having is the game crashes whenever I try to do something with the new car.

 

 

:Drivingwait 0Actor.StorePos($target, 1@, 2@, 3@)00D9: 4@ = actor $target carif   8185: car 4@ health < 300then

 

 

Through debug code, I have found out that the game crashes the instant it looks at 8185: car 4@ health < 800. Because $target is a global variable, it should already know who $target is...correct? If so, why would it goof up when it already has a valid car handle?

 

What I have tried already:

-Using car $target health < 300 instead of 8185: car 4@ health < 300 (crashed)

-Using 00D9: 4@ = player $PLAYER_CHAR car instead of 00D9: 4@ = actor $target car (crashed)

-Putting Car.RemoveReferences(4@) before getting the car again just in case the game did not redefine it correctly. (still crashed)

-Using Car.Health(4@) < 300 instead of 8185: car 4@ health < 300 (crashed)

-Telling the game to work (crashed)

 

Any help on how to accomplish what I need? Again, the aim is to get a valid car handle for whatever car $target is driving so that I can do things such as check if it is on fire, know what kind of car it is, etc.

Edited by Panlantix
Link to comment
Share on other sites

aStiffSausage

How about using local variable instead of $target? It might help a lot.

 

 

00D6: if 00DF:   actor $TARGET driving 004D: jump_if_false @NotInCar03C0: 4@ = actor $TARGET car00D6: if 056E:   car 4@ defined 004D: jump_if_false @SomethingElse00D6: if 8185:   not car 4@ health >= 300 004D: jump_if_false @SoonBlowingUp

 

 

 

That might work somehow, and I would really recommend using opcodes instead of this method:

 

 

Car.Health(4@) < 300

 

 

It allows easier control of opcodes and explanation, and less conflicts between opcodes. (Same kind of command might mean even 4-5 opcodes, so SannyBuilder can't decide which one should be used.)

Link to comment
Share on other sites

Thanks for the reply, oska.

 

I tried your code and it always thinks that the actor is not driving...therefore it jumps to @NotInCar. When I remove that part, it crashes when it hits 8185: not car 4@ => 300.

 

There are quite a few opcodes that do very similar / the same things I have noticed, and so far none of them are working....I think the problem is the opcodes aren't returning a car handle, they're returning something else. When I try something like

 

When I tried Car.Health(4@) > 300, Sanny Builder told me that the argument was of invalid type, which is what makes me suspect is the case. Making the target local is impractical because I don't wanna have to make a new actor every time I go into this procedure; the purpose is just to check the actor's vehicle if it is weak.

 

I tried doing this:

 

 

:DrivingActor.StorePos($target, 1@, 2@, 3@)Actor.PutAt($target, 0.0, 0.0, 0.0)00D9: 4@ = actor $target carif   8185: car 4@ health < 300 

 

 

It doesn't crash before it does Actor.StorePos, and it actually does move $target to that coordinate, so this makes me think it is just fine with $target. However it still crashes when it hits 00D9: 4@ = actor $target car. I also tried an alternate opcode, 03C0 instead of 00D9, and after I did that, it crashed when it hit 8185: car 4@ health < 300

Edited by Panlantix
Link to comment
Share on other sites

spaceeinstein

Don't use 00D9.

Link to comment
Share on other sites

xD I just edited the post while you put your post. I also tried 03C0, which also didn't work. Is there another opcode that does what I need? Store a car handle of the target to a variable?

Link to comment
Share on other sites

aStiffSausage

I really got no idea what's wrong, but how about this:

 

 

0A96: 5@ = actor $target structif00DF:   actor $PLAYER_ACTOR driving else_jump @NotDriving00D9: 4@ = actor 5@ car // mission only //03C0: 4@ = actor 5@ carif8185:   not car 4@ health >= 300 else_jump @FineCar

 

 

Try with both 00D9 and 03C0, just remove the comment-lines from 03C0 and add ones to 00D9 to switch.

 

And also, showing us the whole code would help, there might be small things that are getting in the way.

Link to comment
Share on other sites

I messed around with it a little and now it won't even work with the definition check.

 

 

{$CLEO .cs}thread 'KillTrg':IsDefinedwait 0if   0256:   player $PLAYER_CHAR definedjf @IsDefinedgosub @MakeChkjump @IsIn:MakeChk   02A7: $P = create_icon_marker_and_sphere 11 at 879.8917 -312.4168 8.7211return:Disable   Marker.Disable($P)return:IsInwait 0if   00F5: player $PLAYER_CHAR 0 879.8917 -312.4168 8.7211 radius 2.0 2.0 2.0then   gosub @Disable //Disable the checkpoints.   03E5: text_box 'INTRO'   03E5: text_box 'QUIT'   $countdown = 600000   014E: set_timer_to $countdown   jump @PortlandStartelseendjump @IsIn:checkR3wait 0if   00E1:   pad 0 key_pressed 18 //R3then   gosub @MakeChk   jump @IsInelse   returnendreturn:checkTime01BD: $time = current_time_in_msif   not 1 > $countdownthen   01BD: $time = current_time_in_ms    0084: $s = $time   0060: $s -= $t   returnelse    gosub @MakeChk   Marker.Disable($marker)   jump @IsInend return:PortlandStartgosub @checkTimewait 00208: 1@ = random_float 1 3Model.Load(#GANG11)Model.Load(#GANG12)Model.Load(#B_MAN3)Model.Load(#FBICAR)if and  Model.Available(#GANG11)  Model.Available(#GANG12)  Model.Available(#B_MAN3)  Model.Available(#FBICAR)else_jump @PortlandStart 038B: load_requested_models $target = Actor.Create(Gang3, #GANG11, 1313.5591, -638.6406, 12.2073)$guard1 = Actor.Create(Gang3, #GANG12, 1310.5591, -638.6406, 12.2073)$guard3 = Actor.Create(Gang3, #GANG12, 1305.5591, -648.6406, 12.2073)$guard5 = Actor.Create(CivMale, #B_MAN3, 1316.1785, -643.7741, 12.2073)035F: set_actor $target armour_to 100 01B2: give_actor $target weapon 2 ammo 500 011A: set_actor $target flags 256 0319: set_actor $target wander_state_to 1035F: set_actor $guard1 armour_to 100 01B2: give_actor $guard1 weapon 3 ammo 500 011A: set_actor $guard1 flags 256 0319: set_actor $guard1 wander_state_to 1035F: set_actor $guard3 armour_to 100 01B2: give_actor $guard3 weapon 4 ammo 9999 011A: set_actor $guard3 flags 256 0319: set_actor $guard3 wander_state_to 1035F: set_actor $guard5 armour_to 100 0245: set_actor $guard5 walk_style_to 15 01B2: give_actor $guard5 weapon 5 ammo 9999 011A: set_actor $guard5 flags 256 0319: set_actor $guard5 wander_state_to 1$marker = Marker.CreateAboveActor($target)1@ = Car.Create(#FBICAR, 1310.0206, -662.8311, 12.2382)Car.Angle(1@) = 270.0Model.Destroy(#GANG11)Model.Destroy(#GANG12)Model.Destroy(#B_MAN3)Model.Destroy(#FBICAR)jump @StrtFBI:StrtFBIif   Car.Wrecked(1@)then   jump @OnFootelseend01D5: actor $guard1 go_to_and_drive_car 1@01D4: actor $target go_to_car 1@ and_enter_it_as_a_passenger01D4: actor $guard3 go_to_car 1@ and_enter_it_as_a_passenger01D4: actor $guard5 go_to_car 1@ and_enter_it_as_a_passengerwait 8000if   Car.Wrecked(1@)then   jump @OnFootelseend01E9: 2@ = car 1@ num_passengersif and   2@ > 2   Actor.InCar($target, 1@)   Actor.Driving($guard1)thenelse   wait 4000   if       Actor.InCar($target, 1@)   then   else       jump @StrtFBI   endendif   Car.Wrecked(1@)then   jump @OnFootelseend00AE: unknown_set_car 1@ to_ignore_traffic_lights 2Car.SetMaxSpeed(1@, 40.0)Car.SetToPsychoDriver(1@)0428: unknown_car 1@ flag 1jump @StartDriving:Drivingwait 0gosub @checkTimegosub @checkR3gosub @CheckTrgDeadif  00DF: actor $guard1 drivingthen   03C0: 4@ = actor $guard1 carelse   jump @OnFootendif  00DF: actor $target drivingthen   03C0: 5@ = actor $target carelse   jump @OnFootendwait 500///////////////Crashes the instant it hits car 4@ defined////////////00BC: show_text_highpriority GXT 'Boom' time 5000 flag 0wait 500if   056E: car 4@ definedthen     if       820D: car 4@ flipped        8185: car 4@ health < 300    then       //Car is trashed, get a new one and get the target to the safe spot!       //045F 4@ 1 //Should make all people in car exit...       01D3: actor $target leave_car 4@       01D3: actor $guard1 leave_car 4@       01D3: actor $guard3 leave_car 4@       01D3: actor $guard5 leave_car 4@       jump @OnFoot   else       //Car is okay.   endelseendif 056E: car 5@ definedthen     if       820D: car 5@ flipped        8185: car 5@ health < 300    then       //045F 4@ 1 //Should make all people in car exit...will try this later once the main problem is resolved.       01D3: actor $target leave_car 5@       01D3: actor $guard1 leave_car 5@       01D3: actor $guard3 leave_car 5@       01D3: actor $guard5 leave_car 5@       jump @OnFoot   else       //Car is okay.   endelseendreturn:CheckTrgDeadif   Actor.Dead($target)then   gosub @MakeChk   $countdown = 0   Marker.Disable($marker)   jump @IsInelse   returnend:OnFootgosub @checkTimegosub @checkR3gosub @CheckTrgDead0209: 1@ = random_int 1 2if   1@ = 1then   0377: set_actor $guard1 objective_to-32   01DF: tie_actor $target to_actor $guard1   jump @OnFootelse   0377: set_actor $target objective_to-32   01DE: tie_actor $guard1 to_actor $targetendif   not Actor.Driving($target) then   01CE: actor $target avoid_player $PLAYER_CHAR   jump @OnFootelse   03C0: 4@ = actor $target car   jump @RandLocationend:StartDrivinggosub @Driving03C0: 4@ = actor $target car      Car.DriveTo(4@, 1331.3835, -713.0719, 15.2504)Car.StorePos(4@, 1@, 2@, 3@)if and   1@ > 1328.3835   1@ < 1334.3835   2@ > -716.0719   2@ < -710.0719 then   jump @RandLocationelse   jump @StartDrivingend:RandLocation  0209: 1@ = random_int 1 3if   1@ = 1then   jump @Hideoutelseendif   1@ = 2then   jump @Dockselseendif   1@ = 3then   jump @Hospitalelseend//-------------------------------------//      FBI Car Driving - Portland//-------------------------------------:Hideoutgosub @Driving03C0: 4@ = actor $target carCar.DriveTo(4@, 838.1024, -275.0005, 4.852)Car.StorePos(4@, 1@, 2@, 3@)if and   1@ < 840.1024   1@ > 836.1024   2@ < -273.0005   2@ > -277.0005then   jump @Hideout2else   jump @Hideoutend:Hideout2gosub @Driving03C0: 4@ = actor $target carCar.DriveTo(4@, 874.6188, -307.0424, 8.4542)Car.StorePos(4@, 1@, 2@, 3@)if and   1@ < 876.6188   1@ > 872.6188   2@ < -305.0424   2@ > -309.0424then   jump @Campelse   jump @Hideout2end:Docksgosub @DrivingCar.DriveTo($car, 1545.1559, -850.0466, 11.8457)Car.StorePos($car, 1@, 2@, 3@)if and   1@ < 1547.1559   1@ > 1543.1559   2@ < -852.0466   2@ > -848.0466then   jump @Campelse   jump @Docksend:Hospitalgosub @Driving03C0: 4@ = actor $target carCar.DriveTo(4@, 1142.5697, -589.4111, 14.9363)Car.StorePos(4@, 1@, 2@, 3@)if and   1@ < 1144.5697   1@ > 1140.5697   2@ < -587.4111   2@ > -591.4111then   jump @Campelse   jump @Docksend:Camp03C0: 4@ = actor $target car01D3: actor $target leave_car 4@01D3: actor $guard1 leave_car 4@01D3: actor $guard3 leave_car 4@01D3: actor $guard5 leave_car 4@jump @IsIn:Procgosub @checkR3if   Actor.Dead($target)then   Marker.Disable($marker)   jump @PortlandStartelseendjump @Proc   

 

 

The problem is at line 191. It freezes the instant it checks to see if the car is defined.

Link to comment
Share on other sites

spaceeinstein

FBI Car? Are you coding for GTA III? Check this for the list of III-compatible opcodes.

Link to comment
Share on other sites

Yeah, I found the opcode on there, but it only works with missions...I either need to emulate a mission through the script somehow or use another opcode to get the car, I think. Would the game understand if I set $ONMISSION equal to 1 in my script? It is used in the main.scm to let the game know that a mission started.

Link to comment
Share on other sites

It's not that 00D9 only works for missions. It's that it's made for missions. It adds the vehicle to the mission cleanup list and marks it as the mission car (which means that the next time that opcode is used, it will be able to retrieve the vehicle handle even if the actor isn't in it).

 

03C0 gets the actors car handle, but obviously the returned handle will be unusable (it returns -1) if the actor isn't in a car.

 

Ready for a little lecture on SCM Handles?

 

By studying how Rockstar uses opcodes in the main.scm and looking at how those opcodes function in the EXE, we can figure out how best to go about doing standard things like this. I'm not sure if this applies the same to GTA III, but certainly for SA.

 

// #1 - R* usually always check if the actor is valid.// Like 056D, 0118 also returns false if the actor handle is invalid.// Thus, 056D isn't necessary a lot of the time.if   8118:   not actor 0@ deadthen   if 00DF:   actor 0@ driving   then 03C0: 1@ = actor 0@ car        // the check above guarantees the car exists   endend// #2 - Like actors, cars work with the "not dead" check.03C0: 1@ = actor 0@ carif 8119:   not car 1@ wreckedthen // car exists and is aliveend// #3 - 03C0 and similar opcodes return -1 if the handle isn't retrieved.// Quicker than checking if the car is defined. R* made it this way for a reason, take advantage!03C0: 1@ = actor 0@ carif not 1@ == -1then // car existsend

 

 

056E isn't a valid opcode in GTA III. They probably didn't need it because of all these other options.

 

 

Also...

 

:RandLocation  0209: 1@ = random_int 1 3if  1@ = 1then  jump @Hideoutelseendif  1@ = 2then  jump @Dockselseendif  1@ = 3then  jump @Hospitalelseend

 

 

 

0209: 1@ = random_int 1 3

 

Would only return 1 or 2. So best change it to:

 

0209: 1@ = random_int 1 4

 

 

Unless it works differently in GTA 3, for some reason tounge.gif

Link to comment
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now
  • 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.