|
| 1 | +# Plugin Example |
| 2 | + |
| 3 | +We will take [Permakill](https://github.com/NutScript/NutScript/blob/3ba2083dfae60d4353b4a7e26bcc51870358c539/plugins/permakill.lua){:target="_blank"} as an example of a simple plugin. This plugin automatically bans a character if it dies in certain ways. |
| 4 | + |
| 5 | +## **Starting** |
| 6 | + |
| 7 | +1. We will create a new file called ```permakill.lua``` in the plugins folder. |
| 8 | +2. In it, we will add the following initial information: |
| 9 | + |
| 10 | + ```lua linenums="1" |
| 11 | + PLUGIN.name = "Permakill" |
| 12 | + PLUGIN.author = "Thadah Denyse" |
| 13 | + PLUGIN.desc = "Adds permanent death in the server options." |
| 14 | + ``` |
| 15 | + |
| 16 | +## **Configuration** |
| 17 | + |
| 18 | +We want our plugin to be easily configurated in-game easily, for instance whether it's active at all or dying by falling off a high place will effectively kill our character permanently. Fortunately, NutScript's Framework Libraries are very rich, and will enable us in this process. |
| 19 | + |
| 20 | +In this case, we are going to use ```nut.config.add``` to add our in-game configuration for the server admin. |
| 21 | + |
| 22 | +We want to be able to activate or deactivate permakill as we please, so we will make a configuration that allows us to do so: |
| 23 | + |
| 24 | +```lua linenums="1" |
| 25 | +nut.config.add("pkActive", false, "Whether or not permakill is activated on the server.", nil, { |
| 26 | + category = "Permakill" |
| 27 | +}) |
| 28 | +``` |
| 29 | + |
| 30 | +* The first argument will be the key, which must the unique, therefore adding a prefix (in this case pk) to it is advisable. |
| 31 | + |
| 32 | +* The second argument is the default value. In this case we will use a boolean value, and we will leave Permakill deactivated by default, therefore false |
| 33 | + |
| 34 | +* The third argument is a description, so the admin knows what he is doing when changing the argument. |
| 35 | + |
| 36 | +* The fourth argument is about our configuration using a callback function. The callback will trigger every time the configuration is changed. This doesn't apply to us so we will set it as ```nil``` |
| 37 | + |
| 38 | +* The fifth argument is the data of the configuration, which is a table. In this case, we will set what category should the plugin have inside the Configuration tab, therefore ```{category = "Permakill"}``` |
| 39 | + |
| 40 | +The same goes for the configuration about the world being able to permakill us: |
| 41 | + |
| 42 | +```lua linenums="1" |
| 43 | +nut.config.add("pkWorld", false, "Whether or not world and self damage produce permanent death.", nil, { |
| 44 | + category = "Permakill" |
| 45 | +}) |
| 46 | +``` |
| 47 | + |
| 48 | +## **Functions** |
| 49 | + |
| 50 | +To apply our configurations, we will want somewhere to call them. In this case we will call them inside functions, but it's not limited to them. You can call them from item functions, entities, derma and so on. |
| 51 | + |
| 52 | +We will use the default Gmod functions [PlayerDeath](https://wiki.facepunch.com/gmod/GM:PlayerDeath) and [PlayerSpawn](https://wiki.facepunch.com/gmod/GM:PlayerSpawn), but prefixed with ```PLUGIN``` instead of ```GM```, to prevent overriding them. |
| 53 | + |
| 54 | +### **PlayerDeath** |
| 55 | + |
| 56 | +1. First, the ```PlayerDeath``` function. The function will have the same arguments as its ```GM``` counterpart, therefore: |
| 57 | + ```lua linenums="1" |
| 58 | + function PLUGIN:PlayerDeath(client, inflictor, attacker) |
| 59 | + ``` |
| 60 | + |
| 61 | +2. We don't want to affect our client, but the client's character, therefore we will create a local variable calling the Framework Class ```client:getChar```: |
| 62 | + ```lua linenums="1" hl_lines="2" |
| 63 | + function PLUGIN:PlayerDeath(client, inflictor, attacker) |
| 64 | + local character = client:getChar() |
| 65 | + ``` |
| 66 | + |
| 67 | +3. Next, we will want to know if Permakill is active in the server. This is where our Framework Library ```nut.config.get``` enters the scene: |
| 68 | + ```lua linenums="1" hl_lines="4" |
| 69 | + function PLUGIN:PlayerDeath(client, inflictor, attacker) |
| 70 | + local character = client:getChar() |
| 71 | + |
| 72 | + if (nut.config.get("pkActive")) then |
| 73 | + ``` |
| 74 | + |
| 75 | +4. After that, we want to know if World Damage has been activated inside the server and we want to make it **not permanently kill people if it's deactivated**, therefore: |
| 76 | + ```lua linenums="1" hl_lines="5-7" |
| 77 | + function PLUGIN:PlayerDeath(client, inflictor, attacker) |
| 78 | + local character = client:getChar() |
| 79 | + |
| 80 | + if (nut.config.get("pkActive")) then |
| 81 | + if not (nut.config.get("pkWorld") and (client == attacker or inflictor:IsWorld() then |
| 82 | + return |
| 83 | + end |
| 84 | + ``` |
| 85 | + |
| 86 | + !!! note |
| 87 | + The ```return``` will invalidate everything that comes after that line, making the permakill ineffective if the World Damage is set to false |
| 88 | + |
| 89 | +5. Now that we have verified everything we wanted, we will use ```character:setData``` so that we know that character has been permakilled, this ends the PlayerDeath function as well: |
| 90 | + ```lua linenums="1" hl_lines="8" |
| 91 | + function PLUGIN:PlayerDeath(client, inflictor, attacker) |
| 92 | + local character = client:getChar() |
| 93 | + |
| 94 | + if (nut.config.get("pkActive")) then |
| 95 | + if not (nut.config.get("pkWorld") and (client == attacker or inflictor:IsWorld() then |
| 96 | + return |
| 97 | + end |
| 98 | + character:setData("permakilled", true) |
| 99 | + end |
| 100 | + end |
| 101 | + ``` |
| 102 | + |
| 103 | +### **PlayerSpawn** |
| 104 | + |
| 105 | +Now that we have set the ways the player is permakilled, we will set what happens when a permakilled player tries to spawn again. |
| 106 | + |
| 107 | +1. First, we will get the player's character: |
| 108 | + ```lua linenums="1" |
| 109 | + function PLUGIN:PlayerSpawn(client) |
| 110 | + local character = client:getChar() |
| 111 | + end |
| 112 | + ``` |
| 113 | + |
| 114 | +2. After that, we will verify if permakill is active on the server and we will use ```character:getData``` to verify if the player has been permakilled. If both turn out to be true, we will ban that character with ```character:ban```, so the player can't use it again: |
| 115 | + ```lua linenums="1" hl_lines="3-5" |
| 116 | + function PLUGIN:PlayerSpawn(client) |
| 117 | + local character = client:getChar() |
| 118 | + if (nut.config.get("pkActive") and character and character:getData("permakilled")) then |
| 119 | + character:ban() |
| 120 | + end |
| 121 | + end |
| 122 | + ``` |
| 123 | + |
| 124 | +This finishes our plugin. You can access the full code [here](https://github.com/NutScript/NutScript/blob/3ba2083dfae60d4353b4a7e26bcc51870358c539/plugins/permakill.lua){:target="_blank"}. |
0 commit comments