Doolittle 0 Posted October 15, 2002 Hey! Â Here's an update to my Ultimate Vehicle Respawn. Â It only works with 1.85, nothing lower. Â The best thing is there's no continuous loops or @condition statements I'm waiting on!! Â Another best thing is that you only need to add this line to a vehicle's Initialization: [this] exec "respawn.sqs" Add that to any and all vehicles you want to respawn when destroyed. respawn.sqs ;Any Vehicle Respawn ;by Doolittle ;Adjust this to what you want the respawn delay to be _delay = 15 _obj = _this select 0 ? count _this > 1 : goto "alive" _pos = getPos _obj _dir = getDir _obj _handler = format ["[_this select 0, %1, %2] exec ""respawn.sqs""", _pos, _dir] _obj addEventHandler ["Killed", _handler] exit #alive ? alive _obj : exit ~_delay _pos = _this select 1 _dir = _this select 2 _weapons = weapons _obj removeAllWeapons _obj "_obj addMagazine _x" forEach _weapons _obj setPos _pos _obj setDir _dir _obj setDammage 0.3 ~0.1 _obj setDammage 0.1 ~0.1 _obj setDammage 0 _obj setfuel 1 So how does this work? Â We "remeber" a vehicles initial starting point & direction inside the event string! Â Then we just wait for "Killed" to happen and use that information to respawn there. Â There is no need to "stay" in the script and remember local variables for every vehicle. Â I think this is the cleanest way to do respawning thus far. Note, ""_obj addMagazine _x" forEach _weapons" was not possible before 1.85 as forEach did not process local variables. Â (Thanks for fixing this Suma.) Doolittle dbircsak@earthlink.net Share this post Link to post Share on other sites
KaRRiLLioN 0 Posted October 15, 2002 Does this work ok for multiplayer by using the Setdammage command? In the past I tried the same routine where I would remove fuel and weapons and then setdammage gradually back to 0, then add fuel and weapons back. This seemed to result in multiple explosions, etc. for the vehicle since all clients don't process the same information at the same time. Also, this is executed client-side? I haven't had a chance to experiment with event-handlers yet. Currently I use one that detects the vehicle type, dir, pos, etc. and uses CreateVehicle server-side and then can also custom arm vehicles. Rather than wait on a vehicle to be completely "dead" I use @!Canmove _vcl in order to trigger the respawn. There are advantages to using the Setdammage method, such as being able to assign and keep global variable names without having to declare and assign them using the respawn script, so this interests me if it doesn't have the same issues that previous versions of respawn scripts using SetDammage had. It also means that I don't have to detect the vehicle type and several other things as well. Also, another dumb Q I have, in the respawn script where you have Count _this>1:goto "Alive". Tell me if I understand this correctly. The init of the vehicle execs the script the first time and grabs the info, adds the eventhandler, and then exits the script. Then when the vehicle is destroyed, it execs the same script again, and since this is the second time it's exec'd it, then the count is greater than 1? _this is one of those commands that I still don't understand thoroughly even though I've done a lot of scripting. Somehow it seems to represent an array? Like when it's used in CountType, for example. CountType looks for a count of a string, i.e. "M1Abrams" in an array, so if you have a vehicle exec a script like this: [this] exec "script.sqs" and then in the script _vcl=_this Select 0, then for some reason _this is like an array because you can then use the CountType command like so: (("M1Abrams" CountType _this) == 1) I've never really understood why it works like this, because I've tried variations on it, i.e. _vehicles=[]; _vehicles=_vehicles+[_vc] and then tried the CountType on _vehicles. Ah well, sorry to get far afield, but I was just trying to understand how Count _this could be >1. Share this post Link to post Share on other sites
Doolittle 0 Posted October 15, 2002 </span><table border="0" align="center" width="95%" cellpadding="3" cellspacing="1"><tr><td>Quote </td></tr><tr><td id="QUOTE">The init of the vehicle execs the script the first time and grabs the info, adds the eventhandler, and then exits the script.  Then when the vehicle is destroyed, it execs the same script again, and since this is the second time it's exec'd it, then the count is greater than 1?  _this is one of those commands that I still don't understand thoroughly even though I've done a lot of scripting.  Somehow it seems to represent an array?  <span id='postcolor'> Yes, exactly!  And "count _this" just counts how many arguments were passed to it.  The second time it is called, _this has position & direction included, the count is 3. [this] exec "myscript.sqs" -> _this = [calling obj] in array this exec "myscript.sqs" -> _this = calling obj, no array ["fee","fi",this] exec "myscript.sqs" -> _this = ["fee","fi",calling obj] which is a 3 element array </span><table border="0" align="center" width="95%" cellpadding="3" cellspacing="1"><tr><td>Quote </td></tr><tr><td id="QUOTE">Does this work ok for multiplayer by using the Setdammage command? In the past I tried the same routine where I would remove fuel and weapons and then setdammage gradually back to 0, then add fuel and weapons back.  This seemed to result in multiple explosions, etc. for the vehicle since all clients don't  process the same information at the same time. <span id='postcolor'> You know what, I have no idea!  Should I do a check to see if it's being called by the server & only run it if it's the server??  I don't understand that at all. The good thing about setDammage is you get to keep a vehicle's name, if it has one.  This is good incase you have anything looking for that vehicle by name or any triggers set up, etc. createVehicle, you are basically creating a new blank vehicle that doesn't inherit anything from the old vehicle.  I think I'll try to write up a script that uses createVehicle instead. Doolittle Share this post Link to post Share on other sites
Doolittle 0 Posted October 15, 2002 Is there a way to have every vehicle run [this] exec "respawn.sqs" when it is Initialized but without having to put that string in the Initialization field of every vehicle? Â Is there some way in init.sqs or maybe with a trigger that'll loop through all game objects & when it finds a "vehicle" (how test for that??) it will run that script on it?? Thanks for any help! Doolittle Share this post Link to post Share on other sites
dinger 1 Posted October 15, 2002 yes, but it's not pretty. You can either give all the vehicles names, and pass them to an init program, like in init.sqs: (no guarantees it will work) {private [{_bunny}, {_rabbit}]; _bunny = getpos _x; _rabbit = getdir _x; _x addeventhandler [{Killed}, {[_this, _bunny, _rabbit] exec {respawn.sqs}}]} ForEach [vehicle1, Vehicle2, vehicle3, vehicle4] or you can be real ugly, and make a global trigger called "scanvehicles" set to anybody vehicles (vehicles works, right?) present repeatedly have condition: this and startscan then set startscan to true in the init and have: _vehiclelist = list scanvehicles then put that in place of the array at the end of foreach above. Share this post Link to post Share on other sites
KaRRiLLioN 0 Posted October 15, 2002 The reason I asked about server-side is that i'm pretty sure, unless BIS put something in to make it run only server-side, that when an obj's eventhandler execs the script, then it will run on all computers. You can prevent this by placing a GameLogic named Server in the mission editor and then in your script place: ?(Local Server): before each line. Now the only catch to that is, I don't think the SetDammage portion will work properly if only done server-side. I seem to recall trying that and for some reason the info wasn't passed on to clients. The Setpos and SetDir info are passed correctly. Weapons info is passed correctly if done server-side. I haven't tested the SetDammage portion since 1.46 to see if it works server-side now, but it might be a good experiment. CreateVehicle I know works well, but the issue with that is you're going to have to pass the vehicle type information along to the script so that it will know it. This can be done easily, BUT the problem is that you must keep a maintained list of vehicle types in the script. I wish there was a way to extract type without doing it this way, i.e. like this: _type=Type _vcl since CountType seems to require more info. Anyway, here's a simple loop script that can detect the types for you: _WTrucks=["Truck5tOpen","Truck5tRepair","Truck5tReammo","Truck5t Refuel","Truck5t"] _ETrucks=["UralRepair","UralReammo","UralReFuel","Ural"] _CivTrucks=["TruckV3SGCivil","TruckV3SGRefuel","TruckV3SGRepair"," TruckV3SGReammo","TruckV3SG"] _Jeeps=["JeepMG","GJeep","HMMWV","UAZ","SGUAZG" ,"UAZG","Jeep"] _Cars=["Tractor","Rapid","RapidY","Skoda","SkodaBlu e","SkodaRed","SkodaGreen","Trabant"] _Helos=["Cobra","AH64","CH47D","OH58","UH60MG", "UH60","Mi24","Mi17"] _Planes=["Cessna","A10LGB","A10","SU25"] _WArmor=["M1Abrams","M60","Bradley","M113Ambul","Vulc an","M2StaticMGE","M2StaticMG","M113","BoatW" ] _EArmor=["T80","T72","BMP2","BMPAmbul","BMP",&qu ot;BRDM","BoatE","ZSU","T55G"] _Other=["Mash"] _Vehicles=_WTrucks+_ETrucks+_CivTrucks+_Jeeps+_Cars+_Helos+_Planes+_WArmor+_EArmor+_Other _i = 0 #Loop ? (_i > (Count _Vehicles)) : Goto "Skip" _VehicleType = _Vehicles Select _i _VehicleTypeDoesMatch = ((_VehicleType CountType _this) == 1) ? _VehicleTypeDoesMatch : _type = _VehicleType ? _VehicleTypeDoesMatch : Goto "Next" _i = _i + 1 Goto "Loop" This can extract the vcl type if you use CreateVehicle. I'd love to have a better way of doing this without having to loop through all of the types in an array because whenever a new vehicle is added, you have to add the type to the array. If you want an easy way to have all vehicles exec a script, then I think there's an easy way you can do that using NearestObject. I haven't tried this myself, since it's one of those experiments that I never got around to, but create an object somewhere on the map, maybe a GameLogic or a Invisible H and give it a name, like Detector or something. Using the same arrays that are in the loop above, you can have it loop through the array and do something like this: #Init _x=0 #StartLoop ? (_x > (Count _Vehicles)) : Goto "EndLoop" _type = _Vehicles Select _x _vcl=NearestObject [Detector, _type] !(IsNull _vcl):Goto "Exec" Goto "Skip" #Exec [_vcl] exec "respawn.sqs" #Skip Goto "StartLoop" #EndLoop I just whipped that up so it's probably bug-ridden, and probably wouldn't work right anyway. It's just a thought. What it might do it only detect one vehicle of each type that is nearest that object and exec the script for it and not detect any of the other vehicles of the same type, but like I said, just a thought. It really isn't too bad to have to put [this]exec "script.sqs" into the init of each vehicle. You can copy and paste and change vcl types pretty easily and each one you've copied from the original will still have the exec in it. Otherwise, I'm not sure if it's possible to detect empty vehicles using a East or West Present trigger type script. If so, then that might be useful. Hope this at least helps spark the creative juices a bit, even if it's not really workable. Share this post Link to post Share on other sites
Doolittle 0 Posted October 15, 2002 Good stuff! Oh, I also just read this under the "Event handlers" comref section: </span><table border="0" align="center" width="95%" cellpadding="3" cellspacing="1"><tr><td>Quote </td></tr><tr><td id="QUOTE"> MP notes: "Killed" and "Hit" event handlers are executed where given unit is local. All other event handlers are executed on all computers. Events added by addEventHandler may be different on each computer. <span id='postcolor'> But what that means about setDammage, I dunno. I'm doing the ~0.1 timer thing with the setDammage (idea originally by DeaDMeaT) so that (at least on my computer when I check locally) it doesn't re-explode as you mentioned. I did get the re-exploding thing locally when I DIDN'T do that. So maybe the delay fixes the problem you mentioned? Doolittle Share this post Link to post Share on other sites
KaRRiLLioN 0 Posted October 15, 2002 Well the best way is to test it out on a dedicated server with several players. I've had it where it worked fairly well in some regards, and other times it just kept looping over and over again as the vcl died over and over again on each client's machine. Share this post Link to post Share on other sites
Chill 0 Posted October 16, 2002 This works good in Multi but the Ai will not engage the newly spawn vehicle! Any way around it? Share this post Link to post Share on other sites
Doolittle 0 Posted October 16, 2002 Heh, I'm trying to fix the landing gear first. Â I haven't a clue about the AI & I don't think what we have access to would allow us to even fix that. Â This game does weird stuff sometimes. Â For example, do "_obj setDammage 0" and the vehicle will explode. Â Do "_obj setDammage 0.3", etc. before that and it won't explode. Â Wuhh? Â If I shoot a plane down and then "respawn" it, it will have its landing gear up. Â If however I destroy it in a script like "_obj setDammage 1", it will "respawn" with landing gear down. Â This makes me think there's something more happening at death, some other flags being set, than just a change in health. Does the AI go after vehicles that were made with createVehicle?? </span><table border="0" align="center" width="95%" cellpadding="3" cellspacing="1"><tr><td>Quote </td></tr><tr><td id="QUOTE"> MP notes: "Killed" and "Hit" event handlers are executed where given unit is local. All other event handlers are executed on all computers. Events added by addEventHandler may be different on each computer. <span id='postcolor'> My big question now is, if I take off in my heli and go crash somewhere far away on the island, & then the vehicle "respawns" back where it started, WHERE there just happens to be standing my friend, will he see the heli when it is setPos right near them??? Â I think the answer is NO because the script to respawn the heli was only called locally (right?) on my machine, so as far as he is concerned, he doesn't know what is happening to the heli. Â Does anyone know anything about this?? Â I bet it's "once some object comes near another player it will become local to them too and therefore they will see it", right? Doolittle Share this post Link to post Share on other sites
KaRRiLLioN 0 Posted October 17, 2002 Setpos and SetDir, when called locally will have their data transmitted to the other clients. I know this because I had several clients test a VTOL script of mine that used to use Setpos and Setdir when they exec'd their actions on the action menu. Actions on an action menu are exec'd locally on the client and the Setpos and SetDir stuff is updated by each client. Also, when using my vrs.sqs script that respawns vcls using CreateVehicle, it is done only on the server, but the Setpos and Setdir info are updated by all clients after the server does it. Share this post Link to post Share on other sites
Ixian 0 Posted October 17, 2002 Dolittle I d/l one of your previous respawn scripts from OFPEC website. It respawns destroyed and unused vehicles. I don't know if you know but the American Jeep i blew up respawned and it still looked destroyed. But you could drive it. I'm guessing this would be the same for the UAZ since I didnt test it on that. As for all the other vehicles helos and tanks it does work fine. Did you know about this? If so have you found the solution? Share this post Link to post Share on other sites
Doolittle 0 Posted October 17, 2002 Did this happen when you tested it locally? This is the only way I have of testing my scripts unfortunately even though I'm making them with MP in mind. Doolittle Share this post Link to post Share on other sites
KaRRiLLioN 0 Posted October 17, 2002 It's another side-effect of the Setdammage respawn method. I used to respawn choppers like this and they'd come up looking like hell, but they'd fly. The CreateVehicle method starts it off fresh, but of course there are other issues that arise from that. You can get around the limitations though using Global vars that you declare as Public Vars and then have them used by another script to re-localize them if you're trying to use the Global var name of a vcl. Share this post Link to post Share on other sites
Doolittle 0 Posted October 17, 2002 Ok. But basically I was hoping to show a way to respawn/create a vehicle without doing a loop or anything like that in a script. Doolittle Share this post Link to post Share on other sites
KaRRiLLioN 0 Posted October 17, 2002 Well you still can, even if you use the CreateVehicle method, but you'd have to create a new eventhandler for each vcl, I think since it'd be a new object. Share this post Link to post Share on other sites
Doolittle 0 Posted October 24, 2002 KaRRiLLioN, I did more testing and this was the final result. (This is meant to replace my earlier script.) All vehicles that you want to respawn, put [this] exec "vehicle.sqs" in their Initialization field!! For vehicle respawn we are also going to use a new 1.85 function, addEventHandler. I'm also going to use a trick here. I am going to "remember" where each vehicle starts on the map by saving that location inside the handler string that gets sent when the "Killed" event happens. The "getout.sqs" is the script that handles if a vehicle has been left somewhere like off on some far away mountain. A nice thing OFP does is drop any dead bodies out of the vehicle. Like if someone was driving a jeep and the driver was killed but the jeep still worked, usually that jeep would then sit there for the rest of the game. Well this "getout.sqs" script will see that no one is inside and using it anymore, so it will destroy the vehicle. This is when the "killed.sqs" script will take over and respawn it back at base! I wish every map maker would put this in! Vehicle's will respawn in 180 seconds, they will destruct in 120 seconds if empty for that amount of time. *** *** *** vehicle.sqs *** *** *** _obj = _this select 0 ;Respawn vehicle part _pos = getPos _obj _dir = getDir _obj _handler = format ["[_this, %1, %2] exec ""killed.sqs""", _pos, _dir] _obj addEventHandler ["Killed", _handler] ;Destroy abandoned vehicle part _obj addEventHandler ["GetOut", "_this exec ""getout.sqs"""] *** *** *** killed.sqs *** *** *** _obj = (_this select 0) select 0 ~180 ;Killed is also called with setDammage (this script runs twice & the second time nothing happens) ? alive _obj : exit _pos = _this select 1 _dir = _this select 2 _obj setPos _pos _obj setDir _dir _obj setVelocity [0, 0, 0] ;We do this weird thing below so that the vehicle will not crumple again! _obj setDammage 0.3 ~0.5 _obj setDammage 0.1 ~0.5 _obj setDammage 0 _obj setFuel 1 ;Rearm! _weapons = weapons _obj removeAllWeapons _obj "_obj addMagazine _x" forEach _weapons *** *** *** getout.sqs *** *** *** _obj = _this select 0 ? !alive _obj : exit ? count crew _obj > 0 : exit ~120 ;Has anyone gotten in since we started that timer? ? !alive _obj : exit ? count crew _obj > 0 : exit ;Did the vehicle die and is it now just sitting at a respawn spot? ? fuel _obj == 1 : exit ;Do this so that there is no massive explosion! _obj setFuel 0 removeAllWeapons _obj _obj setDammage 1 Share this post Link to post Share on other sites
DeaDMeaT 0 Posted October 27, 2002 Hey guys, ive been respawning vehicles in multiplayer for AGES.....im surprised know-one has actually figured this out.... its dead easy.... first off u dont place the vehicle u create it on mision start...so its important to keep respawning vehicles to a minimum.... I have had a maximum of 16 vehicles respawning with much success.... Basically u need to define vehicle global variables IN GAME so that when u delete the dead vehicle it doesnt come up with an error, also u cant create vehicles with Global variables already being used....(derrr). The reason I worked on this is so my AI could still be ordered into vehicles etc after they had died..... Ill explain how i do this in detail..... Ok u need to create a naming convention cause it can get rather confusing very quickly.....im currently working on a way to do this with preproccessed files, maybe make it better for multiplayer. (although this does work in multiplayer to a degree....im going to be stuffing around with some of the new commands to see if i can fix the one little problem i have with creating vehicles on the fly.....(problem being u cant get into them for the first 10-40 seconds of the vehiles life, just seems like it doesnt update until 10-40 seconds later) OK u need t place a pad or whatever u use to get the position and direction of the unit on respawn..... here is a list of stuff my script does to create a vehicle.... "NOTE::> all vehicle names MUST be placed in 2 scripts" first being to initilize the vehicle at start and second to wait then respawn the vehicle when destroyed or when it cant move or shoot... 1. Initilize vehicle by creating it with the variable name to be used through out the mission.... 2. Once vehicle is destroyed u need to either setpos it away or delete it.... Â "NOTE::> 1.75 and previouse u had to raise the dammage to 0.9 before deleting or u would end up with smoke coming from nothing....if your respawn time is longer than the smoke is there disregard" 3. Create new vehicle on original pad or new position.... Cool thing is u can have battle waging for HOURS....i mean DAYS really..(really cool) also u can have AI using these vehicles with some clever scripting.... maybe u need to destroy all AA before a jet can respawn....all u do there is create the init at the trigger instead of the start of the mission..... Ive made maps with 12 AA and 4 jets that respawn same as the AI controling them......fireworks for ages....cool to watch.... Share this post Link to post Share on other sites