# attachto_player

No dependencies.

Provides an system for adding and removing attached objects to the player. Prevents conflicts between attached objects.
One example use would be backpacks or pouches, parachutes, jetpacks etc. These mods would want to know that another mod hasn't already attached that same spot on the player.

This **does not attach objects, only keeps track of them**. You still need to use `object:set_attach()`.

If you'd like to fix issues or extend this, feel free to do so, but preferably do so as a pull request on this mod's repo so there aren't lots of different versions of the same API. Changes should not modify the behavior of methods or names of variables however.

Currently, this does **not track the player across sessions**, so when the player leaves or joins, their attached objects will be detached. The system might eventually change to allow for attached things to be re-attached but this is not a priority since the API is not for actually attaching objects, just for keeping track of attached objects. Instead, you should implement your own attach-on-join function to deal with this kind of behavior - your object should keep track of the player it's attached to, rather than this API doing stuff on your object's behalf.

Things this API provides:
- a way to **tell other mods** that your player has stuff of a certain type attached
- methods for checking if certain types / groups of objects are attached to the player
- methods for detaching groups of objects from the player
- the ability to check what groups are attached to the player in realtime (using get_group)
- the ability to have complex attachments like pouches, packs, armour etc.
- can be used as an armour system with the appropriate extensions because groups are added up to a total
  - you can have _attach_groups = {armor = 5, armor_chest = 5, clothing = 1}
  - you could also do complex armor like {armor = 1, armor_blunt = 3, armor_pierce = 1, armor_blast = 4}
  - that would mean you could also have compatability with other systems - you could support both normal armor and complex armor types without having to redo your armor item definitions.
- since the object reference for the child to attach to the player is not important, you could just pass a table with a function and groups, and use it for an item or other non-entity.
- in theory, you don't even need to attach to the player, since this API doesn't rely on the object being attached to being a player object, meaning you could attach the player to a vehicle using the same API. This isn't recommended though, as it can very easily cause problems with unloading and so on.


Here is an example of how you could use the API. These are a best case scenario of what you *should* do. You could avoid adding things to your entity definition for example, but it's probably best to just add it. It makes it easier and more cross compatible.

## Setup for attached objects

When you set up your object entity that will attach to the player, Make sure to set the appropriate variables. Again this isn't *strictly* necessary, but it's a good idea.

```LUA
[...]
  _on_detach = function()
    local blah = "whatever" end,
  _attach_groups = {flight = 1, backpack = 1},
[...]
```
`_on_detach` is the function that is called when this API detaches your entity.

`_attach_groups` is the groups that your entity is tagged with. If a mod wants to remove groups of type "flight" and your entity has this group, it will be detached. Please avoid overriding things by not setting the correct groups; that would mean that you mod essentially doesn't have compatability any more, which is what this API is for.

## Testing for if something attached to player

When you go to use your tool or item which attaches to the player, you can test for if it already has that group attached.
```LUA
my_mod.on_use = function(itemstack, user, pointed_thing)
  if user:get_attach() ~= nil then return itemstack end
  if itemstack:get_wear() >= 65534 then return itemstack end
  -- vvvvvvvvvvvvvvv
  if attachto_player.get_group(user, "flight", 0) then return itemstack end
  -- ^^^^^^^^^^^^^^
  local object = core.add_entity(pos, "my_mod:my_object_ENTITY")
  [...]
```
It's best to depend on this API or else your mod will not have the features by default. Users would have to already have this API installed or manually set it. This makes any checks for `attachto_player ~= nil` redundant.


## Attaching something

When you actually attach, list your attachment in the API.
```LUA
[...]
  self.object:set_attach(player, "", {x = 0, y = 0, z = 0}, {x = 0, y = 0, z = 0})
  if attachto_player then attachto_player.attach(self, player) end
[...]
```
Any time you attach something to the player, you should attach with this method. You can use:
```LUA
attachto_player.set_attach(self, player, {"flight" = 7, "pouch" = 1}, {override = true})
```


## Detaching something

When you detach, make sure you do so in the API too.
```LUA
[...]
  self.object:set_detach()
  if attachto_player then attachto_player.detach_child(self._attached_to_player, self) end
[...]
```


## Detaching everything
You could also want to detach all things in a group from the player, in which case you can use:
```LUA
  attachto_player.detach_all(player)
```
Which will remove every single attached thing from this player (keep in mind, by default, on_dieplayer will call this func).

OR
```LUA
  attachto_player.detach_groups(player, {flight=1, backpack=1})
```
This will detach everything from the player with any of these groups if they have .

If a mod chooses to use `{override = true}` then it will not be affected by these functions.