# Server Script

* Server scripts must exist in the project folder or under the "Scripts" directory with file names like *Hello.lua* to be read properly.

| Script                                                                                       | Description                                                             |
| -------------------------------------------------------------------------------------------- | ----------------------------------------------------------------------- |
| **Server.onJoinPlayer(unit)**                                                                | A new player connects.                                                  |
| **Server.onLeavePlayer(unit)**                                                               | A specific user leaves the game.                                        |
| **Server.SendCenterLabel(text)**                                                             | Display a label on the screen.                                          |
| **Server.SendSay(text, color)**                                                              | Display a message in the chat window.                                   |
| **ScriptEventPublisher Server.GetTopic(topic)**                                              | Register a specific topic to send and receive messages with the client. |
| **Server.FireEvent(topic, args…)**                                                           | Send a message to the client with a specific topic.                     |
| **Server.players**                                                                           | Retrieve a list of players.                                             |
| **Server.fields**                                                                            | Retrieve the entire map list.                                           |
| **Server.CreateEventUnit(name, imageID)**                                                    | Create an event user.                                                   |
| **Server.GetField(dataID)**                                                                  | Retrieve the map of a specific ID.                                      |
| **ScriptUnit**                                                                               | Monsters are objects similar to players.                                |
| **Server.playerLeavePartyCallback(scriptRoomPlayer,scriptParty)**                            | Triggered when a player leaves the party.                               |
| **Server.playerJoinPartyCallback(scriptRoomPlayer,scriptParty)**                             | Triggered when a player joins the party.                                |
| **Server.onAddItem(scriptUnit,titem)**                                                       | Triggered when a user acquires an item.                                 |
| **Server.onRemoveItem(scriptUnit,titem)**                                                    | Triggered when a user removes or uses an item.                          |
| [**ScriptClan**](https://docs.punkland.io/punkland-studio/script/server-script/scriptclan)   | Retrieve the class the user belongs to.                                 |
| [**ScriptColor**](https://docs.punkland.io/punkland-studio/script/server-script/scriptcolor) | Retrieve color information.                                             |

* unit.type = (0=player, 1=event, 2=monster)

Example: Server Script - Display a Message Upon Player Level-Up and Grant an Item at a Specific Level

{% code title="Scripts/Servers/Hello.lua" overflow="wrap" lineNumbers="true" %}

```lua
function onUnitLevelUp(target, level)
    if target.level == 50 then --When a target reaches level 50, a notification will be broadcast to the entire server, and Item 1 will be distributed to the target.
        Server.SendCenterLabel(target.name .. 'has ' .. level .. 'become!')
        target.AddItem(1) 
    elseif target.level == 55 then  --When the target reaches level 55, Skill 5 and 5,000 game money will be awarded. 
        target.AddSkill(5)
        target.AddGameMoney(5000)
    end
end
 
Server.onUnitLevelUp.Add(onUnitLevelUp)
```

{% endcode %}

Example: Server Script - Broadcast a Message to All Players and Grant Rewards for PVP Kills

{% code title="Scripts/Servers/Hello.lua" overflow="wrap" lineNumbers="true" %}

```lua
function onUnitDead(target, attacker) --Target: Deceased, Attacker: Aggressor
    if (target.type==0 and attacker.type==0) then --If it is a PlayerUnit
        Server.SendCenterLabel(target.name..'as \n'..attacker.name..'The attacker killed the target.')
        attacker.AddGameMoney(100) --100 gold is awarded to the attacker.
        if rand(1, 100) <= 50 then
            attacker.AddItem(100) --The attacker has a 50% chance to receive Item 1.
        end
    end
end
Server.onUnitDead.Add(onUnitDead) -- Add the onUnitDead function to Server.onUnitDead.
```

{% endcode %}

Example: Using `onJoinField` - Display Player Name Upon Entering a Specific Map and Send a Server-Wide Message

{% code overflow="wrap" lineNumbers="true" %}

```lua
function onJoinField()
    function onJoinField_1(Field,unit)
        unit.SendCenterLabel(Field.name) -- Temporarily displays field names to units.
        if #Field.playerUnits > 10 then -- # indicates the length of the table.
            Server.SendSay(Field.name.."More than 11 players gathered!")
        end
    end
        local map = Server.GetField(1)
        if map ~= nil then
                map.onJoinField.Add(onJoinField_1)--When entering field 1, the onJoinField_1 function is called.
        end
end
Server.RunLater(onJoinField,1) -- Executes the onJoinField function after 1 second.
-- The reason we run it after 1 second is to avoid referencing nil since the map may not have been created after the server runs.
```

{% endcode %}

onLeaveField - Handle actions when leaving a specific map

> map - ScriptField
>
> unit - ScriptUnit

**File: Script Example for a Specific Map**\
**Usage Example: Decreasing the Value of a World Variable by 1 When Leaving the Map**

{% code overflow="wrap" lineNumbers="true" %}

```lua
function onLeaveField(map,unit)
  print('Leaving: ' .. map.name .. ' ' ..unit.name)
  Server.SetWorldVar(10, Server.GetWorldVar(10)-1)
end

Server.GetField(5).onLeaveField.Add(onLeaveField)
```

{% endcode %}

**Examples of Events Triggered During Specific Actions:**

* **onUseItem**: Triggered when an item is used.
* **onBuyGameMoneyItem**: Triggered when an item is purchased with in-game currency.
* **onSellGameMoneyItem**: Triggered when an item is sold for in-game currency.

{% code overflow="wrap" lineNumbers="true" %}

```lua
Server.onUseItem.Add(
function(unit,item)
    print(unit.name)
    print(item.dataID)
  end)
  
Server.onBuyGameMoneyItem.Add(
  function(unit,itemID,count)
    print(string.format("%s ,%s ,%s",unit.name,itemID,count))
  end)
  
Server.onSellGameMoneyItem.Add(
  function(unit,itemID,count)
    print(string.format("%s,%s,%s",unit.name,itemID,count))
  end)
```

{% endcode %}

Examples: Adding, Removing, and Modifying Item Options (Refer to ScriptUtility)

* Please test the code by removing the applied comments (--). The script below was executed via a touch event - triggered through the script.

{% code overflow="wrap" lineNumbers="true" %}

```lua
-- Get information about the first item in your inventory.
local item = unit.player.GetItems()[1]
local option1 = item.options[1]
--Utility.SetItemOption(option1,option1.type,option1.statID,option1.value+1)
--Server.SendItemUpdated(item)
Utility.AddItemOption(unit.player.GetItems()[1],1,3,5)
--unit.player.RemoveItemOption(item,1)
unit.player.SendItemUpdated(item)
```

{% endcode %}

Example: Event Triggered Upon Joining a Party (playerJoinPartyCallback)

{% code overflow="wrap" lineNumbers="true" %}

```lua
Server.playerJoinPartyCallback =
function(scriptRoomPlayer,scriptParty) 
        print(scriptRoomPlayer.unit.name)
        print(scriptParty.maxPlayer)
        -- A party will be created if return is set to true. You can specify return true or false depending on the condition.
        return true
end
```

{% endcode %}

**Example: Event Triggered Upon Leaving a Party (playerLeavePartyCallback)**

```lua
Server.playerLeavePartyCallback = 
function(scriptRoomPlayer,scriptParty) 
        print(scriptRoomPlayer.unit.name)
        print(scriptParty.maxPlayer)
end
```

Example: Event Triggered Upon Item Acquisition (onAddItem)

{% code overflow="wrap" lineNumbers="true" %}

```lua
Server.onAddItem.Add(
function(scriptUnit,titem) 
        print(scriptUnit.name)
        print(titem.dataID)        
end)
```

{% endcode %}

**Example: Event Triggered Upon Item Removal (onRemoveItem)**

{% code overflow="wrap" lineNumbers="true" %}

```lua
Server.onRemoveItem.Add(
function(scriptUnit,titem) 
        print(scriptUnit.name)
        print(titem.id)
        print(titem.dataID)        
end)
```

{% endcode %}

**Example: Event Triggered When Damage is Applied (damageCallback)**

{% code overflow="wrap" lineNumbers="true" %}

```lua
-- If the damage amount is 0, no damage is output.
-- a,b ScriptUnit
Server.damageCallback = function(a, b, damage, skillDataID, critical, visible)
        damage = a.atk - b.def
        if damage <= 0  then
                visible = false
        end
        return damage, critical, visible;
end
```

{% endcode %}

Example: Event Triggered Upon Completion of a Trade (onTradeDone)

{% code overflow="wrap" lineNumbers="true" %}

```lua
function Trade(sender,receiver,senderItems,receiverItems)
print("sender: ")
print(sender.unit.name)
print("receiver: ")
print(receiver.unit.name)
print("senderItems: ")
print(senderItems)
for i=1 , #senderItems do
        print(i..": ")
        print(Server.GetItem(senderItems[i].dataID).name)
end
print("receiverItems: ")
print(receiverItems)
for j=1 , #receiverItems do
        print(j..": ")
        print(Server.GetItem(receiverItems[j].dataID).name)
end
end

Server.onTradeDone.Add(Trade)
```

{% endcode %}
