Solved Helicopter Not Staying Locked to Caller

I had to turn off the helis from this plug. Got tired of the complaints. "where did my heli go?" every hour. Folks die and it leaves and shoots innocent folks and 9/10 times someone other than the owner shoots it down. AM I missing a setting that would stop this? Anyone know of another plug that gives tiered heli but they stay with the invoker? Why have a option to turn off vanilla heli then make every heli act vanilla every time someone dies? Sorry if I come off harsh but we are very frustrated.
 

Attachments

What you attached is the config file, but the helicopter settings are actually stored in the data directory, each tier has its own data file. Also I need to know how the helicopters are being triggered, are they spawned automatically, or are players calling them in? If it's player triggered, I'll need the exact command being used. From what you're describing it sounds like the lock-on mechanism isn't being activated at all, that usually points to an issue with how the helicopters are being called, likely a command syntax issue or something misconfigured in the tier settings. Otherwise it's working fine for me and for everyone else using the plugin, so it's definitely a setup problem on your end
 
Sorry for sending the wrong file. These are the call commands for all the tiers we use in GUIShop. When I asked about this in the game4freak discord, I was told the running away behavior was a "feature" to mimic a vanilla heli. Sounds like there is hope for us yet. Thanks for taking your time to help.
Code:
"Command": [
        "cht.heli call Colt $player.id 1"
      ],
"Command": [
        "cht.heli call Philly $player.id 1"
      ],
"Command": [
        "cht.heli call Stallion $player.id 1"
      ],
"Command": [
        "cht.heli call Mustang $player.id 1"
      ],
"Command": [
        "cht.heli call Bronco $player.id 1"
      ],
"Command": [
        "cht.heli call ChallengeBronco $player.id 1"
      ],
"Command": [
        "cht.heli call ExtremeChallengeBronco $player.id 1"
      ],
 

Attachments

Like I expected, the command syntax you're using is incorrect
In your shop, you're using:
Code:
cht.heli call Stallion $player.id 1
…but you're missing the key argument: useCallProfile



If you check the documentation, the correct format for the command is:
Code:
cht.heli call <tierName|random> <playerNameOrId> [numberToSpawn] [useCallProfile]
And just below that, it clearly explains what useCallProfile does:
When useCallProfile is enabled, the plugin will:
  • Check if the target player has permission for a matching call profile
  • Apply the cost and cooldown defined in that profile
  • Lock the helicopter onto that player/team as configured
If disabled, the helicopter is simply sent to their position with no lock-on behavior.
So the correct usage should be:
Code:
cht.heli call Stallion $player.id 1 true
That true at the end is what tells the plugin to apply the call profile and enable lock-on behavior


You also must grant the player the correct permission for the call profile. For example, if your tier is Stallion and your call profile suffix is vip, the full permission would be: customhelicoptertiers2.stallion.vip

The plugin prints all available permissions to the console on reload, you can grab them from there easily. Refer to the Call Profiles section for more details
 
Last edited:
Man do I feel stupid. I set the suffix in the colt heli profile to colt thinking it just needed a name to match the call command...

"Call Profiles": [
{
"Enabled": true,
"Lock On Caller": true,
"Include Caller Allies (teammates, friends, clanmates, and clan allies)": true,
"Suffix": "colt",

I then set the call command to:

"cht.heli call customhelicoptertiers2.colt.colt $player.id 1 true"

In the server console it printed:
Unloaded plugin Custom Helicopter Tiers 2 v1.5.0 by VisEntities
[Custom Helicopter Tiers 2] Automatically Harmony patched 'PatrolHelicopterAI.Update_Patch1' method. (PatrolHelicopterAI_Update_Patch)
[Custom Helicopter Tiers 2] Automatically Harmony patched 'HelicopterTurret.FireGun_Patch1' method. (HelicopterTurret_FireGun_Patch)
[Custom Helicopter Tiers 2] Automatically Harmony patched 'PatrolHelicopterAI.StartStrafe_Patch1' method. (PatrolHelicopterAI_StartStrafe_Patch)
[Custom Helicopter Tiers 2] Automatically Harmony patched 'PatrolHelicopterAI.State_OrbitStrafe_Enter_Patch1' method. (PatrolHelicopterAI_State_OrbitStrafe_Enter_Patch)
[Custom Helicopter Tiers 2] Automatically Harmony patched 'PatrolHelicopterAI.State_Strafe_Think_Patch0' method. (PatrolHelicopterAI_State_Strafe_Think_Patch)
[Custom Helicopter Tiers 2] Automatically Harmony patched 'PatrolHelicopterAI.GenerateRandomDestination_Patch1' method. (PatrolHelicopterAI_GenerateRandomDestination_Patch)
[Custom Helicopter Tiers 2] Automatically Harmony patched 'PatrolHelicopterAI.MakeZone_Patch1' method. (PatrolHelicopterAI_MakeZone_Patch)
[Custom Helicopter Tiers 2] Automatically Harmony patched 'PatrolHelicopterAI+DangerZone.IsStale_Patch1' method. (DangerZone_IsStale_Patch)
[Custom Helicopter Tiers 2] Automatically Harmony patched 'PatrolHelicopterAI.UpdateNoGoZones_Patch1' method. (PatrolHelicopterAI_UpdateNoGoZones_Patch)
[Custom Helicopter Tiers 2] Automatically Harmony patched 'PatrolHelicopterAI.WasAttacked_Patch1' method. (PatrolHelicopterAI_WasAttacked_Patch)
[Custom Helicopter Tiers 2] Automatically Harmony patched 'PatrolHelicopter.OnDied_Patch0' method. (PatrolHelicopter_OnDied_Patch)
[Custom Helicopter Tiers 2] Automatically Harmony patched 'PatrolHelicopter.OnEntityMessage_Patch1' method. (PatrolHelicopter_OnEntityMessage_Patch)
[Custom Helicopter Tiers 2] Initializing helicopter tiers...
[Custom Helicopter Tiers 2] Tier 'Bronco' is enabled.
[Custom Helicopter Tiers 2] Tier 'Bronco' has 1 call definitions:
[Custom Helicopter Tiers 2] - Suffix: '', Permission: ''
[Custom Helicopter Tiers 2] Tier 'ChallengeBronco' is enabled.
[Custom Helicopter Tiers 2] Tier 'ChallengeBronco' has 1 call definitions:
[Custom Helicopter Tiers 2] - Suffix: '', Permission: ''
[Custom Helicopter Tiers 2] Tier 'Colt' is enabled.
[Custom Helicopter Tiers 2] Registered permission: customhelicoptertiers2.colt.colt (Tier=Colt, Profile=colt)
[Custom Helicopter Tiers 2] Tier 'Colt' has 1 call definitions:
[Custom Helicopter Tiers 2] - Suffix: 'colt', Permission: 'customhelicoptertiers2.colt.colt'
[Custom Helicopter Tiers 2] Tier 'ExtremeChallengeBronco' is enabled.
[Custom Helicopter Tiers 2] Tier 'ExtremeChallengeBronco' has 1 call definitions:
[Custom Helicopter Tiers 2] - Suffix: '', Permission: ''
[Custom Helicopter Tiers 2] Tier 'Mustang' is enabled.
[Custom Helicopter Tiers 2] Tier 'Mustang' has 1 call definitions:
[Custom Helicopter Tiers 2] - Suffix: '', Permission: ''
[Custom Helicopter Tiers 2] Tier 'Philly' is enabled.
[Custom Helicopter Tiers 2] Tier 'Philly' has 1 call definitions:
[Custom Helicopter Tiers 2] - Suffix: '', Permission: ''
[Custom Helicopter Tiers 2] Tier 'Stallion' is enabled.
[Custom Helicopter Tiers 2] Tier 'Stallion' has 1 call definitions:
[Custom Helicopter Tiers 2] - Suffix: '', Permission: ''
[Custom Helicopter Tiers 2] Setup is complete. 7 tier(s) are enabled.
Calling 'OnServerInitialized' on 'CustomHelicopterTiers2 v1.5.0' took 597ms
Loaded plugin Custom Helicopter Tiers 2 v1.5.0 by VisEntities

Didnt work of course. Then I realized it was a perm so changed colt to default because you dont have to be vip to buy a heli.

"Suffix": "default",

and changed to call command to:

"cht.heli call customhelicoptertiers2.colt.default $player.id 1 true"

granted the permissions in permission manager (It had the colt one in there as well now) I tried with just the default permission granted (in admin group and default group), restarted everything, (guishop and your plug) and I now I get this in the console:

[Custom Helicopter Tiers 2] Tier 'customhelicoptertiers2.colt.default' not found.

Im wondering if I messed something up by putting colt in the suffix area the first time. You can yell at me if you like as I'm no coder and this is way over my head. Was I supposed to use vip? Is default not a good permission to use? Nothing is working now. Im very sorry for wasting your time you've been so helpful.
 
It does say:
Code:
[Custom Helicopter Tiers 2] Registered permission: customhelicoptertiers2.colt.colt (Tier=Colt, Profile=colt)
So the permission definitely exists and registered, the issue is once again with your command syntax


You currently have:
Code:
cht.heli call customhelicoptertiers2.colt.default $player.id 1 true
…but that's incorrect, you're putting the permission name instead of the tier name.
The correct command should be:
Code:
cht.heli call Colt $player.id 1 true
The plugin automatically handles checking the permission and retrieving the correct call profile


And finally to double-check that the spawned helicopter has lock-on enabled, go to the config and turn on Enable Debug, it'll will display info when a heli is spawned, including whether lock-on is active
 
Call profile in colt.json (only thing I touched is adding colt in the suffix area)

"Call Profiles": [
{
"Enabled": true,
"Lock On Caller": true,
"Include Caller Allies (teammates, friends, clanmates, and clan allies)": true,
"Suffix": "colt",
"Number To Spawn": 1,
"Priority": 1,
"Cooldown Minutes": 360.0,
"Daily Call Limit": 0,
"Personal Message": "You have called in the {TierName} helicopter.",
"Global Message": "{PlayerName} has called in the {TierName} helicopter!",
"Skill Tree XP Rewarded": 1500.0,
"XPerience XP Rewarded": 0.0,
"Cost To Call": [
{

The call command Im using in GUIShop :
"Shop - Shop List": {
"Patrol Heli Colt (10k hp)": {
"DisplayName": "Patrol Heli Colt (10k hp)",
"CraftAsDisplayName": false,
"Shortname": "helieasy",
"ItemId": 0,
"MakeBlueprint": false,
"AllowSellOfUsedItems": false,
"Condition": 0.0,
"EnableBuy": true,
"EnableSell": false,
"Image": "https://i.postimg.cc/WzcWVrBZ/tim-crop.jpg",
"SellPrice": 0.0,
"BuyPrice": 4000.0,
"BuyCooldown": 0,
"SellCooldown": 0,
"BuyQuantity": [],
"SellQuantity": [],
"BuyLimit": 4,
"BuyLimitResetCoolDown": 4,
"SwapLimitToQuantityBuyLimit": false,
"SellLimit": 0,
"SellLimitResetCoolDown": 0,
"SwapLimitToQuantitySoldLimit": false,
"KitName": "",
"Command": [
"cht.heli call colt $player.id 1 true"
],
"RunCommandAndCustomShopItem": false,
"GeneTypes": [],
"SkinId": 0
},

The perm looks like in the picture I sent and when I try to spawn the colt heli I get:
[Custom Helicopter Tiers 2] Tier 'colt' not found.

Questions Do you think maybe the capitol C in colt is the problem?
Do spaces in the name cause issues? (all the other tiers have spaces in the names)
Where is the 'colt' thats not being found?
 

Attachments

  • 20250618113906_1.jpg
    20250618113906_1.jpg
    315.3 KB · Views: 3
You have helicopter tiers named Colt, Bronco, Philly, etc.
These names are:
  • Capitalized
  • Used as-is in the data file name
  • Also set in the "Name" field inside each tier file like this:
    JSON:
    {
      "SchemaVersion": 5,
      "Name": "Colt",
That exact name is what you use in the call command
The correct syntax is:
cht.heli call <tierName|random> <playerNameOrId> [numberToSpawn] [useCallProfile]
So in your shop config, the command should look like this:
JSON:
"Command": [
  "cht.heli call Colt $player.id 1 true"
],


Now about Call Profiles, you currently named your profile colt, which is confusing, because then your permission becomes:
customhelicoptertiers2.colt.colt
Instead I recommend naming your call profiles something like default or vip, so the permission would be something clean like:
customhelicoptertiers2.colt.default
You grant that permission to the player. After that you don't need to reference the profile or suffix anywhere else, the plugin handles it automatically
 
I think I understand now. Thank You for putting up with me and my confusion. The heli isnt running anymore as long as I dont have a team mate anywhere on the map so I can tell folks that if they want to fight it alone, leave whatever team your on. We will not be seeking the refund you were offering for buying the new plug. The staff at TimsPlacePVE thanks you once again. Your plugin is fantastic.
 
The heli isnt running anymore as long as I dont have a team mate anywhere on the map so I can tell folks that if they want to fight it alone, leave whatever team your on.
Leaving the team isn't necessary, the helicopter ai will always prioritize the closest visible and alive player, but if the caller wants to take the heli down solo without any help from their team, that's totally fine if that's their goal

One more thing, to make sure your setup is correct and that the helicopter is actually locked onto the caller, go to the config and set:
JSON:
"Enable Debug": true
This will show floating debug info on the helicopter, and it should clearly say if it's locked onto the caller. Once you have confirmed that, you can set it back to false


We will not be seeking the refund you were offering for buying the new plug. The staff at TimsPlacePVE thanks you once again. Your plugin is fantastic.
As for the discount, just have the license owner who purchased CHT2 contact me directly with proof of purchase, and it's no problem
 
Back
Top
Chat commands start with a /, while console commands can be entered directly in the F1 console or server console. Use find <keyword> in console to search for available commands related to the plugin. Parameters in < > are required, while [ ] are optional.
This plugin uses Oxide's permission system. Grant or revoke permissions using oxide.grant and oxide.revoke. You can assign them to individual players or groups using their Steam id or group name.
Settings are stored in the config file found under the config/ directory. You can edit this file manually, then reload the plugin to apply your changes.
Persistent data is saved in the data/ directory. This includes things like saved settings, usage stats, or player progress depending on the plugin. Deleting a data file will reset stored progress or customizations.
Language files are located in the lang/ folder. To translate messages, copy the en.json file into your target language folder (e.g. fr, de) and edit the values. Reload the plugin after changes to apply new messages.
This section lists public methods exposed by the plugin for use in other plugins. You can call these via the CallHook method. Ensure the plugin is loaded before calling its API to avoid null reference errors.
These are custom hooks that other plugins can listen for. Simply define a method with the same name and expected parameters in your plugin to handle the event. Hooks are triggered at key moments and are useful for extending or reacting to plugin behavior.
These hooks are injected into the game's code using Harmony. They let the plugin run code at key points in the game's internal logic. You can return values to block or modify behavior. Use with caution — these are powerful and can affect core mechanics.
Cart