Quincy Posted August 21, 2013 Report Share Posted August 21, 2013 Hi, I'm trying to make it so this script can also pickup objects that fire fighters can pull (i.e. rubble on top of victims). If tried what I think would work and it doesnt. I know it has to do with the CheckTarget loop but I just don't know what to write to make that happen, I've tried multiple things with no success. (Script Credit: Kreuzung from emergency-forum.de) Snippet of code I need help with: object HeliLift : CommandScript{HeliLift(){SetPossibleCallers(ACTOR_VEHICLE);SetValidTargets(ACTOR_VEHICLE | ACTOR_OBJECT);SetRestrictions(RESTRICT_NOTBURNING);SetGroupID(CGROUP_CRANE);SetIcon("liftwithcrane");SetCursor("liftwithcrane");} bool CheckPossible(GameObject *caller) { return caller->IsChildEnabled("hook") && Game::ExistsObjectWithFlagSet(OF_RECOVERABLE); }bool CheckGroupVisibility(GameObject *caller) { return caller->IsChildEnabled("hook"); } bool CheckTarget(GameObject *caller, Actor *target, int childID){GameObject tgt(target); if(!tgt.IsFlagSet(OF_RECOVERABLE))return false; if(tgt.GetType() == ACTOR_VEHICLE){Vehicle v(target);if(v.IsSmoking() || v.GetNumPassengers() || v.GetNumTransported() || v.HasAnyAction()|| ((v.HasCommand("flyto") || v.GetVehicleType() == VT_TV_HELI) && !v.IsOnGround()))return false;if(v.GetVehicleType() > VT_NOSQUAD && (v.GetVehicleType() < VT_TAXI || v.GetVehicleType() > VT_TV_HELI) && !v.IsCommandable())return false;}return true;} Full Script: (For Reference) /*Helicopter lift script by KreuzungPublished under the CreativeCommons Attribution License Features:- Helicopters can lift objects and vehicles, including empty squad ones- While carrying something, helis will have to fly slower (configurable) Known bugs:- Sometimes dropping an object drops it slightly below the ground, I've setup the drop offset to minimize this- The person routefinder refuses to guide persons around dropped vehicles, either move the vehicle (if you can) or guide the persons around it manually- Sometimes you can lift a squad vehicle when you shouldn't be able to- The wheels of vehicles rotate while lifting/dropping them... xD How to use:- It really works the same as the standard crane How to add to your mod:- Put this file in your command script folder- Assign the commands "HeliLift" and "HeliDrop" to the helicopter- Add a child called "hook" to the helicopter (important!), this is used to determine if the helicopter is carrying something and where exactly objects will be attached- If you want other commands to not work while lifting something, check if the "hook" child is enabled in their CheckPossible part - it will be disabled while lifting*/const float LIFT_MAX_DISTANCE = 25f; //how far the heli can be away from the object to be liftedconst float LIFT_SPEED = 10f; //how fast the heli can lift/drop things, slower means higher accuracy when putting the object to the ground, so you might want to adjust drop offset as well when you change thisconst float DROP_HEIGHTOFFSET = 15f; //prevents the object from dropping into the ground, the default value is ideal for a lift speed of 10const float LIFTED_HEIGHTOFFSET = 250f; //how high the heli will stay above the lifted objectconst float SPEED_MULTIPLIER_CARRYING = 0.5f; //speed multiplier while carrying somethingnamespace Utils{GameObject GetHook(int id){GameObjectList l("hook");for(int i = 0; i < l.GetNumObjects(); i++)if(l.GetObject(i)->GetUserData() == id)return l.GetObject(i);return NULL;} GameObject GetLiftedObject(GameObject hook){GameObjectList l = Game::GetGameObjects();GameObject result = l.GetObject(0);for(int i = 0; i < l.GetNumObjects(); i++)if(l.GetObject(i)->HasCommand("DummyHeliLifted") && (!result.IsValid() || l.GetObject(i)->DistanceXY(hook) < result.DistanceXY(hook)))result = l.GetObject(i);if(result.HasCommand("DummyHeliLifted"))return result;return NULL;}}; object HeliLift : CommandScript{HeliLift(){SetPossibleCallers(ACTOR_VEHICLE);SetValidTargets(ACTOR_VEHICLE | ACTOR_OBJECT);SetRestrictions(RESTRICT_NOTBURNING);SetGroupID(CGROUP_CRANE);SetIcon("liftwithcrane");SetCursor("liftwithcrane");} bool CheckPossible(GameObject *caller) { return caller->IsChildEnabled("hook") && Game::ExistsObjectWithFlagSet(OF_RECOVERABLE); }bool CheckGroupVisibility(GameObject *caller) { return caller->IsChildEnabled("hook"); } bool CheckTarget(GameObject *caller, Actor *target, int childID){GameObject tgt(target); if(!tgt.IsFlagSet(OF_RECOVERABLE))return false; if(tgt.GetType() == ACTOR_VEHICLE){Vehicle v(target);if(v.IsSmoking() || v.GetNumPassengers() || v.GetNumTransported() || v.HasAnyAction()|| ((v.HasCommand("flyto") || v.GetVehicleType() == VT_TV_HELI) && !v.IsOnGround()))return false;if(v.GetVehicleType() > VT_NOSQUAD && (v.GetVehicleType() < VT_TAXI || v.GetVehicleType() > VT_TV_HELI) && !v.IsCommandable())return false;}return true;} void PushActions(GameObject *caller, Actor *target, int childID){GameObject tgt(target);switch(childID){Vehicle v(caller);if(caller->DistanceXY(tgt) > LIFT_MAX_DISTANCE || v.IsOnGround()){caller->PushActionFlyTo(ACTION_NEWLIST, tgt.GetPosition(), false, -1);caller->PushActionExecuteCommand(ACTION_APPEND, "HeliLift", target, 0, true);return;} GameObject hook = Game::CreateObject(tgt.GetPrototypeFileName(), "hook");hook.SetPlacementNone();hook.SetPosition(caller->GetChildPosition("hook") + Vector(0, 0, -LIFTED_HEIGHTOFFSET));hook.SetRotation(caller);hook.SetFlag(OF_HIDDEN);hook.SetUserData(caller->GetID());hook.SetSpeed(caller->GetSpeed()); caller->SetCommandable(false);caller->SetChildEnabled("hook", false);caller->SetSpeed(caller->GetSpeed() * SPEED_MULTIPLIER_CARRYING); tgt.SetCommandable(false);tgt.AssignCommand("DummyHeliLifted");tgt.SetPlacementNone();tgt.PushActionMoveToPoint(ACTION_NEWLIST, &hook, LIFT_SPEED);tgt.PushActionExecuteCommand(ACTION_APPEND, "HeliLift", &hook, 1, false);break; case 1: //caller = object / target = hookVehicle heli(&Game::GetActor(tgt.GetUserData()));heli.SetCommandable(true);heli.AddTrainWaggon(caller);heli.AddTrainWaggon(&tgt);tgt.SetFlag(OF_HIDDEN);tgt.PushActionExecuteCommand(ACTION_NEWLIST, "HeliLift", caller, 2, false);break; case 2: //caller = hook / target = object... somehow it works better to have 2 train wagons (disables autorotate) and set the rotation manuallyVehicle heli(&Game::GetActor(caller->GetUserData()));if(!heli.IsValid() || tgt.IsCurrentAction("EActionMoveToPoint"))return;bool burningVehicle = false;if(tgt.GetType() == ACTOR_VEHICLE){Vehicle v(target);if(v.IsSmoking())burningVehicle = true;}if(heli.IsDestroyed() || burningVehicle){heli.RemoveTrainWaggon(caller);heli.RemoveTrainWaggon(&tgt);heli.SetChildEnabled("hook", true);tgt.SetPlacement(PLACEMENT_ALIGNED_CORNERS);tgt.EnablePhysicsSimulation();tgt.UnfreezePhysics();caller->PushActionDeleteOwner(ACTION_NEWLIST);}Vector fixedZ = tgt.GetPosition();fixedZ.z = heli.GetChildPosition("hook").z -LIFTED_HEIGHTOFFSET;tgt.SetPosition(fixedZ);tgt.SetRotation(&heli);caller->PushActionExecuteCommand(ACTION_NEWLIST, "HeliLift", target, 2, false);break;}}}; object HeliDrop : CommandScript{GameObject hook;HeliDrop(){SetPossibleCallers(ACTOR_VEHICLE);SetValidTargets(ACTOR_FLOOR | ACTOR_VIRTUAL | ACTOR_OBJECT);SetGroupID(CGROUP_CRANE);SetIcon("drop");SetCursor("drop");SetHighlightingEnabled(false);} bool CheckPossible(GameObject *caller) { return !caller->IsChildEnabled("hook"); }bool CheckGroupVisibility(GameObject *caller) { return !caller->IsChildEnabled("hook"); } bool CheckTarget(GameObject *caller, Actor *target, int childID){hook = Utils::GetHook(caller->GetID());return Game::FindFreePosition(&hook, Game::GetCommandPos(), 0);} void PushActions(GameObject *caller, Actor *target, int childID){switch(childID){case 0:caller->PushActionFlyTo(ACTION_NEWLIST, Game::GetCommandPos(), false, -1);caller->PushActionExecuteCommand(ACTION_APPEND, "HeliDrop", NULL, 1, true);return; case 1:hook = Utils::GetHook(caller->GetID());GameObject lifted = Utils::GetLiftedObject(hook);Vector dropPos = caller->GetPosition();dropPos.z = Game::GetFloorHeight(dropPos.x, dropPos.y) + DROP_HEIGHTOFFSET; hook.SetRotation(caller); caller->SetCommandable(false);Vehicle heli(caller);heli.RemoveTrainWaggon(&hook);heli.RemoveTrainWaggon(&lifted); hook.SetPlacement(lifted.GetType() == ACTOR_VEHICLE ? PLACEMENT_CUSTOM_PLACEMENT : PLACEMENT_ALIGNED_CORNERS);hook.SetPosition(dropPos); lifted.PushActionMoveToPoint(ACTION_NEWLIST, &hook, LIFT_SPEED);lifted.PushActionExecuteCommand(ACTION_APPEND, "HeliDrop", &hook, 2, false);break; case 2:Vehicle heli(&Game::GetActor(target->GetUserData()));hook = new GameObject(target);heli.SetCommandable(true);heli.SetChildEnabled("hook", true);heli.SetSpeed(hook.GetSpeed()); hook.PushActionDeleteOwner(ACTION_NEWLIST);caller->SetPlacement(caller->GetType() == ACTOR_VEHICLE ? PLACEMENT_CUSTOM_PLACEMENT : PLACEMENT_ALIGNED_CORNERS);caller->SetCommandable(true);caller->RemoveCommand("DummyHeliLifted");}}}; object DummyHeliLifted : CommandScript{};BTW the CODE tag on the forum is broken, had to use quote tag. Quote Link to comment Share on other sites More sharing options...
Hoppah Posted August 21, 2013 Report Share Posted August 21, 2013 Make sure the objects that can be picked up have a flag set that's called 'RECOVERABLE'. That seems to be the only restriction for objects that are no vehicles. The rubble probably only has the flag set 'PULLABLE', so you may want to change that for either the object in the editor, or change the script so the heli can also pick up objects with the flag set 'PULLABLE'. Quote Link to comment Share on other sites More sharing options...
The Loot Posted August 21, 2013 Report Share Posted August 21, 2013 This looks like a nifty script. Hope the kinks get worked out. Quote Link to comment Share on other sites More sharing options...
Quincy Posted August 21, 2013 Author Report Share Posted August 21, 2013 I mean is there a way I can just change the script restrictions to allow recoverable and pullable? Quote Link to comment Share on other sites More sharing options...