Attribute VB_Name = "modScript"
Option Explicit

Declare Function RunASMScript Lib "script.dll" Alias "RunScript" (Script As Any, FunctionTable As Any, Parameters As Any) As Long
Declare Function SysFreeString Lib "oleaut32.dll" (ByVal StringPointer As Long) As Long
Declare Function SysAllocStringByteLen Lib "oleaut32.dll" (ByVal St As String, ByVal Length As Long) As Long

Public FunctionTable(0 To 255) As Long
Public ScriptRunning As Boolean

Public Parameter(0 To 5) As Long
Public StringStack(0 To 1023) As Long
Public StringPointer As Long
Sub Boot_Player(ByVal Index As Long, ByVal Reason As String)
    BootPlayer Index, 0, StrConv(Reason, vbUnicode)
End Sub
Sub Ban_Player(ByVal Index As Long, ByVal NumDays As Long, ByVal Reason As String)
    BanPlayer Index, 0, NumDays, StrConv(Reason, vbUnicode), "Script Ban"
End Sub
Function Find_Player(ByVal Name As String) As Long
    Find_Player = FindPlayer(StrConv(Name, vbUnicode))
End Function
Function GetObjX(ByVal MapIndex As Long, ByVal ObjIndex As Long) As Long
    If MapIndex >= 1 And MapIndex <= 2000 And ObjIndex >= 0 And ObjIndex <= 79 Then
        With Map(MapIndex).Object(ObjIndex)
            GetObjX = .X
        End With
    End If
End Function
Function GetObjY(ByVal MapIndex As Long, ByVal ObjIndex As Long) As Long
    If MapIndex >= 1 And MapIndex <= 2000 And ObjIndex >= 0 And ObjIndex <= 79 Then
        With Map(MapIndex).Object(ObjIndex)
            GetObjY = .Y
        End With
    End If
End Function
Function GetObjNum(ByVal MapIndex As Long, ByVal ObjIndex As Long) As Long
    If MapIndex >= 1 And MapIndex <= 2000 And ObjIndex >= 0 And ObjIndex <= 79 Then
        With Map(MapIndex).Object(ObjIndex)
            GetObjNum = .Object
        End With
    End If
End Function
Function GetTileAtt(ByVal MapIndex As Long, ByVal X As Long, ByVal Y As Long) As Long
    If MapIndex >= 1 And MapIndex <= 2000 And X >= 0 And X <= 11 And Y >= 0 And Y <= 11 Then
        GetTileAtt = Map(MapIndex).Tile(X, Y).Att
    End If
End Function
Function DestroyObj(ByVal MapIndex As Long, ByVal ObjIndex As Long) As Long
    If MapIndex >= 1 And MapIndex <= 2000 And ObjIndex >= 0 And ObjIndex <= 79 Then
        With Map(MapIndex).Object(ObjIndex)
            .Object = 0
            SendToMap MapIndex, Chr$(15) + Chr$(ObjIndex) 'Erase Map Obj
        End With
    End If
End Function
Function GetObjVal(ByVal MapIndex As Long, ByVal ObjIndex As Long) As Long
    If MapIndex >= 1 And MapIndex <= 2000 And ObjIndex >= 0 And ObjIndex <= 79 Then
        With Map(MapIndex).Object(ObjIndex)
            GetObjVal = .Value
        End With
    End If
End Function
Function NewString(St As String) As Long
    Dim A As Long
    If StringPointer < 1024 Then
        A = SysAllocStringByteLen(St, Len(St))
        StringStack(StringPointer) = A
        StringPointer = StringPointer + 1
        NewString = A
    Else
        NewString = 0
    End If
End Function
Function AttackMonster(ByVal Index As Long, ByVal MonsterIndex As Long, ByVal Damage As Long) As Long
    Dim MapNum As Long, A As Long, B As Long, C As Long
    If Index >= 1 And Index <= MaxUsers And MonsterIndex >= 0 And MonsterIndex <= 9 Then
        If Player(Index).Mode = modePlaying Then
            MapNum = Player(Index).Map
            If Map(MapNum).Monster(MonsterIndex).Monster > 0 Then
                If Damage < 0 Then Damage = 0
                If Damage > 255 Then Damage = 255
                SendSocket Index, Chr$(44) + Chr$(0) + Chr$(MonsterIndex) + Chr$(Damage) 'Hit Monster
                SendToMapAllBut MapNum, Index, Chr$(42) + Chr$(Index)
                With Map(MapNum).Monster(MonsterIndex)
                    .Target = Index
                    If .HP > Damage Then
                        .HP = .HP - Damage
                    Else
                        'Monster Died
                        SendToMapAllBut MapNum, Index, Chr$(39) + Chr$(MonsterIndex) 'Monster Died
                        With Monster(.Monster)
                            SendSocket Index, Chr$(51) + Chr$(MonsterIndex) + QuadChar(.Exp) 'You killed monster
                            GainExp Index, .Exp
                        End With
                        B = Int(Rnd * 3)
                        C = Monster(.Monster).Object(B)
                        If C > 0 Then
                            NewMapObject MapNum, C, Monster(.Monster).Value(B), CLng(.X), CLng(.Y), False
                        End If
                        
                        Parameter(0) = Index
                        Parameter(1) = CStr(.Monster)
                        RunScript "MONSTERDIE"
                        .Monster = 0
                        
                        AttackMonster = True
                    End If
                End With
            End If
        End If
    End If
End Function
Function AttackPlayer(ByVal Index As Long, ByVal Target As Long, ByVal Damage As Long) As Long
    Dim A As Long
    If Player(Target).Dead = True Then Exit Function
    If Index >= 1 And Index <= MaxUsers And Target >= 1 And Target <= MaxUsers Then
        If Player(Index).Mode = modePlaying And Player(Target).Mode = modePlaying Then
            If Damage < 0 Then Damage = 0
            If Damage > 255 Then Damage = 255
            With Player(Target)
                If .HP > Damage Then
                    .HP = .HP - Damage
                Else
                    .HP = 0
                End If
                SendToMap .Map, Chr$(111) + Chr$(.X) + Chr$(.Y) + Chr$(0) + Chr$(22) + CStr(Damage)
            End With
            SendSocket Target, Chr$(49) + Chr$(0) + Chr$(Index) + Chr$(Damage)
            SendSocket Index, Chr$(43) + Chr$(0) + Chr$(Target) + Chr$(Damage)
            SendToMapAllBut Player(Index).Map, Target, Chr$(42) + Chr$(Index)
            
            If Player(Target).HP = 0 Then
                Parameter(0) = Target
                If RunScript("PLAYERDIE") = 0 Then
                    'Player Died
                    If Player(Index).Status <> 1 Then
                        Player(Index).Status = 1
                    End If
                
                    Parameter(0) = Index
                    Parameter(1) = Target
                    RunScript "KILLPLAYER"
                
                    SendSocket Target, Chr$(52) + Chr$(Index) 'Player Killed You
                
                    A = Player(Target).Experience
                    PlayerDied Target
                    A = A - Player(Target).Experience
                
                    SendSocket Index, Chr$(45) + Chr$(Target) + QuadChar(A) 'You Killed Player
                    GainExp Index, A
                    SendAllButBut Index, Target, Chr$(61) + Chr$(Target) + Chr$(Index) 'Player was killed by player
                
                    AttackPlayer = True
                End If
            End If
        End If
    End If
End Function
Function CanAttackMonster(ByVal Index As Long, ByVal MonsterIndex As Long) As Long
    Dim MapIndex As Long
    If Index >= 1 And Index <= MaxUsers And MonsterIndex >= 0 And MonsterIndex <= 9 Then
        If Player(Index).Mode = modePlaying Then
            MapIndex = Player(Index).Map
            If ExamineBit(Map(MapIndex).flags, 5) = False And Map(MapIndex).Monster(MonsterIndex).Monster > 0 Then
                CanAttackMonster = True
            End If
        End If
    End If
End Function
Function CanAttackPlayer(ByVal Player1 As Long, ByVal Player2 As Long) As Long
    Dim PKMap As Boolean
    If Player1 >= 1 And Player1 <= MaxUsers And Player2 >= 1 And Player2 <= MaxUsers Then
        With Player(Player1)
            If ExamineBit(Map(.Map).flags, 0) = False Then
                If .Mode = modePlaying And Player(Player2).Mode = modePlaying Then
                    If .Map = Player(Player2).Map Then
                        PKMap = ExamineBit(Map(.Map).flags, 6)
                        If .Guild > 0 Or PKMap = True Then
                            If Player(Player2).Guild > 0 Or PKMap = True Then
                                CanAttackPlayer = True
                            End If
                        End If
                    End If
                End If
            End If
        End With
    End If
End Function
Function GetAbs(ByVal Value As Long) As Long
    GetAbs = Abs(Value)
End Function
Function GetMaxUsers() As Long
    GetMaxUsers = MaxUsers
End Function
Function GetMonsterType(ByVal MapIndex As Long, ByVal MonsterIndex As Long) As Long
    If MapIndex >= 1 And MapIndex <= 2000 And MonsterIndex >= 0 And MonsterIndex <= 9 Then
        GetMonsterType = Map(MapIndex).Monster(MonsterIndex).Monster
    End If
End Function
Sub DestroyMonster(ByVal MapIndex As Long, ByVal MonsterIndex As Long)
    If MapIndex >= 1 And MapIndex <= 2000 And MonsterIndex >= 0 And MonsterIndex <= 9 Then
        With Map(MapIndex)
            .Monster(MonsterIndex).Monster = 0
            If .NumPlayers > 0 Then SendToMap MapIndex, Chr$(39) + Chr$(MonsterIndex)
        End With
    End If
End Sub
Function GetMonsterTarget(ByVal MapIndex As Long, ByVal MonsterIndex As Long) As Long
    If MapIndex >= 1 And MapIndex <= 2000 And MonsterIndex >= 0 And MonsterIndex <= 9 Then GetMonsterTarget = Map(MapIndex).Monster(MonsterIndex).Target
End Function
Sub NPCSay(ByVal MapIndex As Long, ByVal St As String)
    If MapIndex >= 1 And MapIndex <= 2000 Then
        If Map(MapIndex).NPC > 0 Then SendToMap MapIndex, Chr$(88) + Chr$(Map(MapIndex).NPC) + StrConv(St, vbUnicode)
    End If
End Sub
Sub NPCTell(ByVal Index As Long, ByVal St As String)
    Dim A As Long
    If Index >= 1 And Index <= MaxUsers Then
        With Player(Index)
            If .Mode = modePlaying Then
                A = Map(Player(Index).Map).NPC
                If A > 0 Then SendSocket Index, Chr$(88) + Chr$(A) + StrConv(St, vbUnicode)
            End If
        End With
    End If
End Sub
Sub ResetPlayerFlag(ByVal FlagNum As Long)
    Dim A As Long
    If FlagNum >= 0 And FlagNum <= 127 Then
        A = World.PlayerFlagCounter(FlagNum)
        If A = 2147483647 Then
            A = 0
        Else
            A = A + 1
        End If
        World.PlayerFlagCounter(FlagNum) = A
    End If
End Sub
Sub Reset_Map(ByVal MapNum As Long)
    If MapNum >= 1 And MapNum <= 2000 Then
        ResetMap MapNum
    End If
End Sub
Sub ScriptTimer(ByVal Index As Long, ByVal Seconds As Long, ByVal Script As String)
Dim A As Long
    If Index >= 1 And Index <= MaxUsers Then
        If Seconds > 86400 Then Seconds = 86400
        If Seconds < 0 Then Seconds = 0
        With Player(Index)
            If .Mode = modePlaying Then
                For A = 1 To MaxPlayerTimers
                    If .ScriptTimer(A) = 0 Then
                        .Script(A) = StrConv(Script, vbUnicode)
                        .ScriptTimer(A) = GetTickCount + Seconds * 1000
                        Exit For
                    End If
                Next A
            End If
        End With
    End If
End Sub
Sub MicroTimer(ByVal Index As Long, ByVal MS As Long, ByVal Script As String)
Dim A As Long
    If Index >= 1 And Index <= MaxUsers Then
        If MS > 60000 Then MS = 60000
        If MS < 0 Then MS = 0
        With Player(Index)
            If .Mode = modePlaying Then
                For A = 1 To MaxPlayerTimers
                    If .ScriptTimer(A) = 0 Then
                        .Script(A) = StrConv(Script, vbUnicode)
                        .ScriptTimer(A) = GetTickCount + MS
                        Exit For
                    End If
                Next A
            End If
        End With
    End If
End Sub
Sub SetFlag(ByVal FlagNum As Long, ByVal Value As Long)
    If FlagNum >= 0 And FlagNum <= 255 Then
        World.Flag(FlagNum) = Value
    End If
End Sub
Function GetFlag(ByVal FlagNum As Long) As Long
    If FlagNum >= 0 And FlagNum <= 255 Then
        GetFlag = World.Flag(FlagNum)
    End If
End Function
Function SetMonsterTarget(ByVal MapIndex As Long, ByVal MonsterIndex As Long, ByVal Player As Long) As Long
    If MapIndex >= 1 And MapIndex <= 2000 And MonsterIndex >= 0 And MonsterIndex <= 9 And Player >= 1 And Player <= MaxUsers Then
        With Map(MapIndex).Monster(MonsterIndex)
            .Target = Player
            .Distance = 1
        End With
    End If
End Function
Function GetMonsterX(ByVal MapIndex As Long, ByVal MonsterIndex As Long) As Long
    If MapIndex >= 1 And MapIndex <= 2000 And MonsterIndex >= 0 And MonsterIndex <= 9 Then
        GetMonsterX = Map(MapIndex).Monster(MonsterIndex).X
    End If
End Function
Function GetMonsterY(ByVal MapIndex As Long, ByVal MonsterIndex As Long) As Long
    If MapIndex >= 1 And MapIndex <= 2000 And MonsterIndex >= 0 And MonsterIndex <= 9 Then
        GetMonsterY = Map(MapIndex).Monster(MonsterIndex).Y
    End If
End Function
Function GetSqr(ByVal Value As Long) As Long
    GetSqr = Sqr(Value)
End Function
Function GetTime() As Long
    GetTime = World.Hour
End Function
Function HasObj(ByVal Index As Long, ByVal ObjIndex As Long) As Long
    Dim A As Long, B As Long, C As Long
    If Index >= 1 And Index <= MaxUsers And ObjIndex >= 1 And ObjIndex <= 255 Then
        B = Object(ObjIndex).Type
        With Player(Index)
            For A = 1 To 20
                With .Inv(A)
                    If .Object = ObjIndex Then
                        If B = 6 Then
                            C = .Value
                            Exit For
                        Else
                            C = C + 1
                        End If
                    End If
                End With
            Next A
        End With
        HasObj = C
    End If
End Function
Function GetPlayerName(ByVal Index As Long) As Long
    If Index >= 1 And Index <= MaxUsers Then
        With Player(Index)
            GetPlayerName = NewString(.Name)
        End With
    End If
End Function
Function GetPlayerIP(ByVal Index As Long) As Long
    If Index >= 1 And Index <= MaxUsers Then
        With Player(Index)
            GetPlayerIP = NewString(.IP)
        End With
    End If
End Function
Function GetPlayerUser(ByVal Index As Long) As Long
    If Index >= 1 And Index <= MaxUsers Then
        With Player(Index)
            GetPlayerUser = NewString(.User)
        End With
    End If
End Function
Function GetPlayerDesc(ByVal Index As Long) As Long
    If Index >= 1 And Index <= MaxUsers Then
        With Player(Index)
            GetPlayerDesc = NewString(.desc)
        End With
    End If
End Function
Function GetGuildName(ByVal Index As Long) As Long
    If Index >= 1 And Index <= 255 Then
        With Guild(Index)
            GetGuildName = NewString(.Name)
        End With
    End If
End Function
Function GiveObj(ByVal Index As Long, ByVal ObjIndex As Long, ByVal Amount As Long) As Long
    Dim A As Long, B As Long, C As Long
    If Index >= 1 And Index <= MaxUsers And ObjIndex >= 1 And ObjIndex <= 255 Then
        With Player(Index)
            If .Mode = modePlaying Then
                B = Object(ObjIndex).Type
                If B = 6 Then
                    A = FindInvObject(Index, ObjIndex)
                    If A = 0 Then
                        A = FreeInvNum(Index)
                    Else
                        C = 1
                    End If
                Else
                    A = FreeInvNum(Index)
                End If
                If A > 0 Then
                    With .Inv(A)
                        .Object = ObjIndex
                        
                        Select Case B
                            Case 1, 2, 3, 4 'Weapon, Shield, Armor, Helmut
                                .Value = CLng(Object(ObjIndex).Data(0)) * 10
                            Case 6 'Money
                                If C = 1 Then
                                    .Value = .Value + Amount
                                Else
                                    .Value = Amount
                                End If
                            Case 8 'Ring
                                .Value = CLng(Object(ObjIndex).Data(1)) * 10
                            Case Else
                                .Value = 0
                        End Select
                        
                        SendSocket Index, Chr$(17) + Chr$(A) + Chr$(ObjIndex) + QuadChar(.Value) 'New Inv Obj
                    End With
                End If
            End If
        End With
    End If
End Function
Sub GlobalMessage(ByVal Message As String, ByVal MsgColor As Long)
    MsgColor = MsgColor Mod 16
    SendAll Chr$(56) + Chr$(MsgColor) + StrConv(Message, vbUnicode)
End Sub
Function IsPlaying(ByVal Index As Long) As Long
    If Index >= 1 And Index <= MaxUsers Then
        IsPlaying = Player(Index).Mode = modePlaying
    End If
End Function
Function Free_Map() As Long
    Free_Map = FreeMap
End Function
Sub MapMessage(ByVal Index As Long, ByVal Message As String, ByVal MsgColor As Long)
    If Index >= 1 And Index <= 2000 Then
        MsgColor = MsgColor Mod 16
        SendToMap Index, Chr$(56) + Chr$(MsgColor) + StrConv(Message, vbUnicode)
    End If
End Sub
Sub MapMessageAllBut(ByVal MapIndex As Long, ByVal PlayerIndex As Long, ByVal Message As String, ByVal MsgColor As Long)
    If MapIndex >= 1 And MapIndex <= 2000 Then
        MsgColor = MsgColor Mod 16
        SendToMapAllBut MapIndex, PlayerIndex, Chr$(56) + Chr$(MsgColor) + StrConv(Message, vbUnicode)
    End If
End Sub
Function OpenDoor(ByVal MapNum As Long, ByVal X As Long, ByVal Y As Long) As Long
    Dim A As Long
    If MapNum >= 1 And MapNum <= 2000 And X >= 0 And X <= 11 And Y >= 0 And Y <= 11 Then
        A = FreeMapDoorNum(MapNum)
        If A >= 0 Then
            With Map(MapNum).Door(A)
                .Att = Map(MapNum).Tile(X, Y).Att
                .X = X
                .Y = Y
                .T = GetTickCount
            End With
            Map(MapNum).Tile(X, Y).Att = 0
            SendToMap MapNum, Chr$(36) + Chr$(A) + Chr$(X) + Chr$(Y)
            OpenDoor = 1
        End If
    End If
End Function
Sub PlayerMessage(ByVal Index As Long, ByVal Message As String, ByVal MsgColor As Long)
    If Index >= 1 And Index <= MaxUsers Then
        MsgColor = MsgColor Mod 16
        SendSocket Index, Chr$(56) + Chr$(MsgColor) + StrConv(Message, vbUnicode)
    End If
End Sub
Function RunScript0(ByVal Script As String) As Long
    RunScript0 = RunScript(StrConv(Script, vbUnicode))
End Function
Function RunScript1(ByVal Script As String, ByVal Parm1 As Long) As Long
    Parameter(0) = Parm1
    RunScript1 = RunScript(StrConv(Script, vbUnicode))
End Function
Function RunScript2(ByVal Script As String, ByVal Parm1 As Long, ByVal Parm2 As Long) As Long
    Parameter(0) = Parm1
    Parameter(1) = Parm2
    RunScript2 = RunScript(StrConv(Script, vbUnicode))
End Function
Function RunScript3(ByVal Script As String, ByVal Parm1 As Long, ByVal Parm2 As Long, ByVal Parm3 As Long) As Long
    Parameter(0) = Parm1
    Parameter(1) = Parm2
    Parameter(2) = Parm3
    RunScript3 = RunScript(StrConv(Script, vbUnicode))
End Function
Function RunScript4(ByVal Script As String, ByVal Parm1 As Long, ByVal Parm2 As Long, ByVal Parm3 As Long, ByVal Parm4 As Long) As Long
    Parameter(0) = Parm1
    Parameter(1) = Parm2
    Parameter(2) = Parm3
    Parameter(3) = Parm4
    RunScript4 = RunScript(StrConv(Script, vbUnicode))
End Function
Sub SetPlayerSprite(ByVal Index As Long, ByVal Sprite As Long)
    If Index >= 1 And Index <= MaxUsers And Sprite >= 0 And Sprite <= 255 Then
        With Player(Index)
            If Sprite = 0 Then
                If .Guild > 0 Then
                    If Guild(.Guild).Sprite > 0 Then
                        .Sprite = Guild(.Guild).Sprite
                    Else
                        .Sprite = Class(.Class).Picture + .Gender
                    End If
                Else
                    .Sprite = Class(.Class).Picture + .Gender
                End If
            Else
                .Sprite = Sprite
            End If
            SendAll Chr$(63) + Chr$(0) + Chr$(Index) + Chr$(.Sprite)
        End With
    End If
End Sub
Function SpawnMonster(ByVal MapIndex As Long, ByVal Monster As Long, ByVal X As Long, ByVal Y As Long) As Long
    Dim A As Long
    
    If MapIndex >= 1 And MapIndex <= 2000 And Monster >= 1 And Monster <= 255 And X >= 0 And X <= 11 And Y >= 0 And Y <= 11 Then
        With Map(MapIndex)
            For A = 0 To 9
                With .Monster(A)
                    If .Monster = 0 Then
                        SendToMapRaw MapIndex, SpawnMapMonster(MapIndex, A, Monster, X, Y)
                        SpawnMonster = 1
                        Exit Function
                    End If
                End With
            Next A
        End With
    End If
    
    SpawnMonster = 0
End Function
Function SpawnObject(ByVal MapIndex As Long, ByVal Object As Long, ByVal Value As Long, ByVal X As Long, ByVal Y As Long) As Long
    If MapIndex >= 1 And MapIndex <= 2000 And Object >= 1 And Object <= 255 And Value >= 0 And X >= 0 And X <= 11 And Y >= 0 And Y <= 11 Then
        SpawnObject = NewMapObject(MapIndex, Object, Value, X, Y, True)
    End If
End Function
Function Str(ByVal Value As Long) As Long
    Str = NewString(CStr(Value))
End Function
Function StrCat(ByVal String1 As String, ByVal String2 As String) As Long
    StrCat = NewString(StrConv(String1, vbUnicode) + StrConv(String2, vbUnicode))
End Function

Function StrCmp(ByVal String1 As String, ByVal String2 As String) As Long
    StrCmp = UCase$(StrConv(String1, vbUnicode)) = UCase$(StrConv(String2, vbUnicode))
End Function
Function GetInStr(ByVal String1 As String, ByVal String2 As String) As Long
    GetInStr = InStr(UCase$(StrConv(String1, vbUnicode)), UCase$(StrConv(String2, vbUnicode)))
End Function
Function StrFormat(ByVal String1 As String, ByVal String2 As String) As Long
    Dim St As String, St1 As String, St2 As String
    St1 = StrConv(String1, vbUnicode)
    St2 = StrConv(String2, vbUnicode)
    
    Dim A As Long, B As Byte
    For A = 1 To Len(St1)
        B = Asc(Mid$(St1, A, 1))
        If B = 42 Then
            St = St + St2
        Else
            St = St + Chr$(B)
        End If
    Next A
    
    StrFormat = NewString(St)
End Function
Function GetGuildHall(ByVal Index As Long) As Long
    If Index >= 1 And Index <= 255 Then
        GetGuildHall = Guild(Index).Hall
    End If
End Function
Function GetGuildBank(ByVal Index As Long) As Long
    If Index >= 1 And Index <= 255 Then
        GetGuildBank = Guild(Index).Bank
    End If
End Function
Function GetGuildSprite(ByVal Index As Long) As Long
    If Index >= 1 And Index <= 255 Then
        GetGuildSprite = Guild(Index).Sprite
    End If
End Function
Function GetGuildMemberCount(ByVal Index As Long) As Long
    If Index >= 1 And Index <= 255 Then
        GetGuildMemberCount = CountGuildMembers(Index)
    End If
End Function
Function GetMapPlayerCount(ByVal Index As Long) As Long
    If Index >= 1 And Index <= 2000 Then
        GetMapPlayerCount = Map(Index).NumPlayers
    End If
End Function
Function GetMapName(ByVal Index As Long) As Long
    If Index >= 1 And Index <= 2000 Then
        With Map(Index)
            GetMapName = NewString(.Name)
        End With
    End If
End Function
Function GetMapData(ByVal Index As Long, ByVal MapData As Long) As Long
    If Index >= 1 And Index <= 2000 And MapData >= 0 And MapData <= 6 Then
        With Map(Index)
            If ExamineBit(.flags, CByte(MapData)) = True Then
                GetMapData = 1
            Else
                GetMapData = 0
            End If
        End With
    End If
End Function
Function GetPlayerAccess(ByVal Index As Long) As Long
    If Index >= 1 And Index <= MaxUsers Then
        GetPlayerAccess = Player(Index).Access
    End If
End Function
Function GetPlayerAgility(ByVal Index As Long) As Long
    If Index >= 1 And Index <= MaxUsers Then
        GetPlayerAgility = Player(Index).Agility
    End If
End Function
Function GetPlayerBankObj(ByVal Index As Long, ByVal Slot As Long) As Long
    If Index >= 1 And Index <= MaxUsers And Slot >= 1 And Slot <= 30 Then
        GetPlayerBankObj = Player(Index).Bank(Slot).Object
    End If
End Function
Function GetPlayerBankVal(ByVal Index As Long, ByVal Slot As Long) As Long
    If Index >= 1 And Index <= MaxUsers And Slot >= 1 And Slot <= 30 Then
        GetPlayerBankVal = Player(Index).Bank(Slot).Value
    End If
End Function
Sub SetPlayerBankObj(ByVal Index As Long, ByVal Slot As Long, ByVal Obj As Long)
    If Index >= 1 And Index <= MaxUsers And Slot >= 1 And Slot <= 30 Then
        Player(Index).Bank(Slot).Object = Obj
    End If
End Sub
Sub SetPlayerBankVal(ByVal Index As Long, ByVal Slot As Long, ByVal Val As Long)
    If Index >= 1 And Index <= MaxUsers And Slot >= 1 And Slot <= 30 Then
        Player(Index).Bank(Slot).Value = Val
    End If
End Sub
Function GetPlayerClass(ByVal Index As Long) As Long
    If Index >= 1 And Index <= MaxUsers Then
        GetPlayerClass = Player(Index).Class
    End If
End Function
Function GetPlayerEndurance(ByVal Index As Long) As Long
    If Index >= 1 And Index <= MaxUsers Then
        GetPlayerEndurance = Player(Index).Endurance
    End If
End Function
Function GetPlayerEquipped(ByVal Index As Long, ByVal EquippedIndex As Long) As Long
    If Index >= 1 And Index <= MaxUsers And EquippedIndex >= 1 And EquippedIndex <= 6 Then
        GetPlayerEquipped = Player(Index).EquippedObject(EquippedIndex)
    End If
End Function
Function GetPlayerExperience(ByVal Index As Long) As Long
    If Index >= 1 And Index <= MaxUsers Then
        GetPlayerExperience = Player(Index).Experience
    End If
End Function
Function GetPlayerGender(ByVal Index As Long) As Long
    If Index >= 1 And Index <= MaxUsers Then
        GetPlayerGender = Player(Index).Gender
    End If
End Function
Function GetPlayerGuild(ByVal Index As Long) As Long
    If Index >= 1 And Index <= MaxUsers Then
        GetPlayerGuild = Player(Index).Guild
    End If
End Function
Function GetPlayerGuildRank(ByVal Index As Long) As Long
    If Index >= 1 And Index <= MaxUsers Then
        GetPlayerGuildRank = Player(Index).GuildRank
    End If
End Function
Function GetPlayerHP(ByVal Index As Long) As Long
    If Index >= 1 And Index <= MaxUsers Then
        GetPlayerHP = Player(Index).HP
    End If
End Function
Function GetPlayerIntelligence(ByVal Index As Long) As Long
    If Index >= 1 And Index <= MaxUsers Then
        GetPlayerIntelligence = Player(Index).Intelligence
    End If
End Function
Function GetPlayerConcentration(ByVal Index As Long) As Long
    If Index >= 1 And Index <= MaxUsers Then
        GetPlayerConcentration = Player(Index).Concentration
    End If
End Function
Function GetPlayerVitality(ByVal Index As Long) As Long
    If Index >= 1 And Index <= MaxUsers Then
        GetPlayerVitality = Player(Index).Vitality
    End If
End Function
Function GetPlayerStamina(ByVal Index As Long) As Long
    If Index >= 1 And Index <= MaxUsers Then
        GetPlayerStamina = Player(Index).Stamina
    End If
End Function
Function GetPlayerWisdom(ByVal Index As Long) As Long
    If Index >= 1 And Index <= MaxUsers Then
        GetPlayerWisdom = Player(Index).Wisdom
    End If
End Function
Function SetPlayerStrength(ByVal Index As Long, ByVal Value As Long) As Long
    If Index >= 1 And Index <= MaxUsers Then
        With Player(Index)
            If Value > 255 Then Value = 255
                If Value < 0 Then Value = 0
                .Strength = Value
                SendSocket Index, Chr$(106) + Chr$(0) + Chr$(.Strength)
                SavePlayerData Index
        End With
    End If
End Function
Function SetPlayerAgility(ByVal Index As Long, ByVal Value As Long) As Long
    If Index >= 1 And Index <= MaxUsers Then
        With Player(Index)
            If Value > 255 Then Value = 255
                If Value < 0 Then Value = 0
                .Agility = Value
                SendSocket Index, Chr$(106) + Chr$(1) + Chr$(.Agility)
                SavePlayerData Index
        End With
    End If
End Function
Function SetPlayerEndurance(ByVal Index As Long, ByVal Value As Long) As Long
    If Index >= 1 And Index <= MaxUsers Then
        With Player(Index)
            If Value > 255 Then Value = 255
                If Value < 0 Then Value = 0
                .Endurance = Value
                SendSocket Index, Chr$(106) + Chr$(2) + Chr$(.Endurance)
                SavePlayerData Index
        End With
    End If
End Function
Function SetPlayerIntelligence(ByVal Index As Long, ByVal Value As Long) As Long
    If Index >= 1 And Index <= MaxUsers Then
        With Player(Index)
            If Value > 255 Then Value = 255
                If Value < 0 Then Value = 0
                .Intelligence = Value
                SendSocket Index, Chr$(106) + Chr$(3) + Chr$(.Intelligence)
                SavePlayerData Index
        End With
    End If
End Function
Function SetPlayerConcentration(ByVal Index As Long, ByVal Value As Long) As Long
    If Index >= 1 And Index <= MaxUsers Then
        With Player(Index)
            If Value > 255 Then Value = 255
                If Value < 0 Then Value = 0
                .Concentration = Value
                SendSocket Index, Chr$(106) + Chr$(4) + Chr$(.Concentration)
                SavePlayerData Index
        End With
    End If
End Function
Function SetPlayerVitality(ByVal Index As Long, ByVal Value As Long) As Long
    If Index >= 1 And Index <= MaxUsers Then
        With Player(Index)
            If Value > 255 Then Value = 255
                If Value < 0 Then Value = 0
                .Vitality = Value
                SendSocket Index, Chr$(106) + Chr$(5) + Chr$(.Vitality)
                CalculateStats Index
                SavePlayerData Index
        End With
    End If
End Function
Function SetPlayerStamina(ByVal Index As Long, ByVal Value As Long) As Long
    If Index >= 1 And Index <= MaxUsers Then
        With Player(Index)
            If Value > 255 Then Value = 255
                If Value < 0 Then Value = 0
                .Stamina = Value
                SendSocket Index, Chr$(106) + Chr$(6) + Chr$(.Stamina)
                CalculateStats Index
                SavePlayerData Index
        End With
    End If
End Function
Function SetPlayerWisdom(ByVal Index As Long, ByVal Value As Long) As Long
    If Index >= 1 And Index <= MaxUsers Then
        With Player(Index)
            If Value > 255 Then Value = 255
                If Value < 0 Then Value = 0
                .Wisdom = Value
                SendSocket Index, Chr$(106) + Chr$(7) + Chr$(.Wisdom)
                SavePlayerData Index
                CalculateStats Index
        End With
    End If
End Function
Function SetPlayerClass(ByVal Index As Long, ByVal ClassNum As Long) As Long
    If Index >= 1 And Index <= MaxUsers Then
        If ClassNum >= 1 And ClassNum <= 4 Then
            Player(Index).Class = ClassNum
            Player(Index).Sprite = Class(ClassNum).Picture
            SendAll Chr$(63) + Chr$(0) + Chr$(Index) + Chr$(Player(Index).Sprite)
            CalculateStats Index
        End If
    End If
End Function
Sub SetPlayerDead(ByVal Index As Long, ByVal Dead As Long)
    If Index >= 1 And Index <= MaxUsers And (Dead = 0 Or Dead = 1) Then
        With Player(Index)
            If Dead = 0 Then
                If .Dead = True Then
                    SendAll Chr$(109) + Chr$(0) + Chr$(Index)
                    SendAll Chr$(63) + Chr$(0) + Chr$(Index) + Chr$(.Sprite)
                    SendAll Chr$(91) + Chr$(Index) + Chr$(.Status)
                    .Dead = False
                End If
            End If
            If Dead = 1 Then
                If .Dead = False Then
                    SendAll Chr$(109) + Chr$(1) + Chr$(Index)
                    SendToMapAllBut .Map, Index, Chr$(117)
                    SendToMap .Map, Chr$(111) + Chr$(.X) + Chr$(.Y) + Chr$(0) + Chr$(22) + "Dead!"
                    .Dead = True
                End If
            End If
        End With
    End If
End Sub
Function GetPlayerDead(ByVal Index As Long) As Long
    If Index >= 1 And Index <= MaxUsers Then
        With Player(Index)
            Select Case .Dead
                Case True
                    GetPlayerDead = 1
                Case False
                    GetPlayerDead = 0
            End Select
        End With
    End If
End Function
Function GetPlayerInvObject(ByVal Index As Long, ByVal InvIndex As Long) As Long
    If Index >= 1 And Index <= MaxUsers And InvIndex >= 1 And InvIndex <= 20 Then
        GetPlayerInvObject = Player(Index).Inv(InvIndex).Object
    End If
End Function
Function GetPlayerInvValue(ByVal Index As Long, ByVal InvIndex As Long) As Long
    If Index >= 1 And Index <= MaxUsers And InvIndex >= 1 And InvIndex <= 20 Then
        GetPlayerInvValue = Player(Index).Inv(InvIndex).Value
    End If
End Function
Function GetPlayerLevel(ByVal Index As Long) As Long
    If Index >= 1 And Index <= MaxUsers Then
        GetPlayerLevel = Player(Index).Level
    End If
End Function
Function SetPlayerLevel(ByVal Index As Long, ByVal Level As Long) As Long
    If Index >= 1 And Index <= MaxUsers Then
        If Level >= 1 And Level <= 125 Then
            With Player(Index)
                If Level > .Level Then .StatPoints = .StatPoints + Int(Level * 2)
                If Level < .Level And .StatPoints >= Int(Level * 2) Then .StatPoints = .StatPoints - Int(Level * 2) Else .StatPoints = 0
                .Level = Level
                CalculateStats Index
            End With
        End If
    End If
End Function
Function GetPlayerMana(ByVal Index As Long) As Long
    If Index >= 1 And Index <= MaxUsers Then
        GetPlayerMana = Player(Index).Mana
    End If
End Function
Function GetPlayerMap(ByVal Index As Long) As Long
    If Index >= 1 And Index <= MaxUsers Then
        With Player(Index)
            If .Mode = modePlaying Then
                GetPlayerMap = .Map
            End If
        End With
    End If
End Function
Function GetPlayerMaxHP(ByVal Index As Long) As Long
    If Index >= 1 And Index <= MaxUsers Then
        GetPlayerMaxHP = Player(Index).MaxHP
    End If
End Function
Function GetPlayerMaxMana(ByVal Index As Long) As Long
    If Index >= 1 And Index <= MaxUsers Then
        GetPlayerMaxMana = Player(Index).MaxMana
    End If
End Function
Function GetPlayerSprite(ByVal Index As Long) As Long
    If Index >= 1 And Index <= MaxUsers Then
        GetPlayerSprite = Player(Index).Sprite
    End If
End Function
Function GetPlayerFlag(ByVal Index As Long, ByVal FlagNum As Long) As Long
    If Index >= 1 And Index <= MaxUsers And FlagNum >= 0 And FlagNum <= 127 Then
        With Player(Index).Flag(FlagNum)
            If .ResetCounter = World.PlayerFlagCounter(FlagNum) Then
                GetPlayerFlag = .Value
            Else
                .Value = 0
                .ResetCounter = World.PlayerFlagCounter(FlagNum)
            End If
        End With
    End If
End Function
Sub SetPlayerFlag(ByVal Index As Long, ByVal FlagNum As Long, ByVal Value As Long)
    If Index >= 1 And Index <= MaxUsers And FlagNum >= 0 And FlagNum <= 127 Then
        With Player(Index).Flag(FlagNum)
            .Value = Value
            .ResetCounter = World.PlayerFlagCounter(FlagNum)
        End With
    End If
End Sub
Function GetPlayerStatus(ByVal Index As Long) As Long
    If Index >= 1 And Index <= MaxUsers Then
        GetPlayerStatus = Player(Index).Status
    End If
End Function
Function GetPlayerStrength(ByVal Index As Long) As Long
    If Index >= 1 And Index <= MaxUsers Then
        GetPlayerStrength = Player(Index).Strength
    End If
End Function
Function GetPlayerX(ByVal Index As Long) As Long
    If Index >= 1 And Index <= MaxUsers Then
        GetPlayerX = Player(Index).X
    End If
End Function
Function GetPlayerY(ByVal Index As Long) As Long
    If Index >= 1 And Index <= MaxUsers Then
        GetPlayerY = Player(Index).Y
    End If
End Function
Function GetValue(Value As Long) As Long
    GetValue = Value
End Function
Sub InitFunctionTable()
    FunctionTable(0) = GetValue(AddressOf DeleteString)
    FunctionTable(1) = GetValue(AddressOf StrCat)
    FunctionTable(2) = GetValue(AddressOf StrCmp)
    FunctionTable(3) = GetValue(AddressOf StrFormat)
    
    FunctionTable(4) = GetValue(AddressOf Random)
    
    FunctionTable(5) = GetValue(AddressOf GetPlayerAccess)
    FunctionTable(6) = GetValue(AddressOf GetPlayerMap)
    FunctionTable(7) = GetValue(AddressOf GetPlayerX)
    FunctionTable(8) = GetValue(AddressOf GetPlayerY)
    FunctionTable(9) = GetValue(AddressOf GetPlayerSprite)
    FunctionTable(10) = GetValue(AddressOf GetPlayerClass)
    FunctionTable(127) = GetValue(AddressOf SetPlayerClass)
    FunctionTable(11) = GetValue(AddressOf GetPlayerGender)
    FunctionTable(12) = GetValue(AddressOf GetPlayerHP)
    FunctionTable(14) = GetValue(AddressOf GetPlayerMana)
    FunctionTable(15) = GetValue(AddressOf GetPlayerMaxHP)
    FunctionTable(17) = GetValue(AddressOf GetPlayerMaxMana)
    FunctionTable(124) = GetValue(AddressOf Calculate_Stats)
    
    FunctionTable(18) = GetValue(AddressOf GetPlayerStrength)
    FunctionTable(19) = GetValue(AddressOf GetPlayerEndurance)
    FunctionTable(20) = GetValue(AddressOf GetPlayerIntelligence)
    FunctionTable(21) = GetValue(AddressOf GetPlayerAgility)
    FunctionTable(13) = GetValue(AddressOf GetPlayerConcentration)
    FunctionTable(16) = GetValue(AddressOf GetPlayerVitality)
    FunctionTable(34) = GetValue(AddressOf GetPlayerStamina)
    FunctionTable(101) = GetValue(AddressOf GetPlayerWisdom)
    
    FunctionTable(102) = GetValue(AddressOf SetPlayerStrength)
    FunctionTable(116) = GetValue(AddressOf SetPlayerAgility)
    FunctionTable(117) = GetValue(AddressOf SetPlayerEndurance)
    FunctionTable(118) = GetValue(AddressOf SetPlayerIntelligence)
    FunctionTable(120) = GetValue(AddressOf SetPlayerConcentration)
    FunctionTable(121) = GetValue(AddressOf SetPlayerVitality)
    FunctionTable(122) = GetValue(AddressOf SetPlayerStamina)
    FunctionTable(123) = GetValue(AddressOf SetPlayerWisdom)

    FunctionTable(23) = GetValue(AddressOf GetPlayerExperience)
    FunctionTable(24) = GetValue(AddressOf GetPlayerLevel)
    FunctionTable(125) = GetValue(AddressOf SetPlayerLevel)
    FunctionTable(25) = GetValue(AddressOf GetPlayerStatus)
    FunctionTable(26) = GetValue(AddressOf GetPlayerGuild)
    FunctionTable(144) = GetValue(AddressOf GetPlayerGuildRank)
    
    FunctionTable(22) = GetValue(AddressOf GetPlayerBankObj)
    FunctionTable(91) = GetValue(AddressOf SetPlayerBankObj)
    FunctionTable(130) = GetValue(AddressOf GetPlayerBankVal)
    FunctionTable(131) = GetValue(AddressOf SetPlayerBankVal)
    
    FunctionTable(27) = GetValue(AddressOf GetPlayerInvObject)
    FunctionTable(28) = GetValue(AddressOf GetPlayerInvValue)
    FunctionTable(29) = GetValue(AddressOf GetPlayerEquipped)
    
    FunctionTable(30) = GetValue(AddressOf GetPlayerName)
    FunctionTable(31) = GetValue(AddressOf GetPlayerUser)
    FunctionTable(32) = GetValue(AddressOf GetPlayerDesc)
       
    FunctionTable(33) = GetValue(AddressOf SetPlayerHP)
    FunctionTable(35) = GetValue(AddressOf SetPlayerMana)
    
       
    FunctionTable(36) = GetValue(AddressOf PlayerMessage)
    FunctionTable(37) = GetValue(AddressOf PlayerWarp)
    
    FunctionTable(38) = GetValue(AddressOf MapMessage)
    FunctionTable(39) = GetValue(AddressOf GlobalMessage)
    
    FunctionTable(128) = GetValue(AddressOf Reset_Map)
    
    FunctionTable(40) = GetValue(AddressOf GetGuildHall)
    FunctionTable(41) = GetValue(AddressOf GetGuildBank)
    FunctionTable(42) = GetValue(AddressOf GetGuildMemberCount)
    FunctionTable(43) = GetValue(AddressOf GetGuildName)
    
    FunctionTable(44) = GetValue(AddressOf GetMapPlayerCount)
    FunctionTable(129) = GetValue(AddressOf GetMapName)
    
    FunctionTable(45) = GetValue(AddressOf MapMessageAllBut)
    
    FunctionTable(46) = GetValue(AddressOf HasObj)
    FunctionTable(47) = GetValue(AddressOf TakeObj)
    FunctionTable(48) = GetValue(AddressOf GiveObj)
    
    FunctionTable(49) = GetValue(AddressOf GetTime)
    
    FunctionTable(50) = GetValue(AddressOf GetMaxUsers)
    
    FunctionTable(51) = GetValue(AddressOf RunScript0)
    FunctionTable(52) = GetValue(AddressOf RunScript1)
    FunctionTable(53) = GetValue(AddressOf RunScript2)
    FunctionTable(54) = GetValue(AddressOf RunScript3)
    
    FunctionTable(55) = GetValue(AddressOf OpenDoor)
    
    FunctionTable(56) = GetValue(AddressOf Str)
    
    FunctionTable(57) = GetValue(AddressOf SetPlayerSprite)
    
    FunctionTable(58) = GetValue(AddressOf GetAbs)
    FunctionTable(59) = GetValue(AddressOf GetSqr)
    
    FunctionTable(60) = GetValue(AddressOf CanAttackPlayer)
    FunctionTable(61) = GetValue(AddressOf IsPlaying)
    
    FunctionTable(62) = GetValue(AddressOf AttackPlayer)
    FunctionTable(63) = GetValue(AddressOf AttackMonster)
    FunctionTable(64) = GetValue(AddressOf CanAttackMonster)
    
    FunctionTable(65) = GetValue(AddressOf GetMonsterType)
    FunctionTable(66) = GetValue(AddressOf GetMonsterX)
    FunctionTable(67) = GetValue(AddressOf GetMonsterY)
    FunctionTable(68) = GetValue(AddressOf GetMonsterTarget)
    FunctionTable(69) = GetValue(AddressOf SetMonsterTarget)
    
    FunctionTable(70) = GetValue(AddressOf GetInStr)
    FunctionTable(71) = GetValue(AddressOf SpawnObject)
    
    FunctionTable(72) = GetValue(AddressOf NPCSay)
    FunctionTable(73) = GetValue(AddressOf NPCTell)
    
    FunctionTable(74) = GetValue(AddressOf GetGuildSprite)
    
    FunctionTable(75) = GetValue(AddressOf ScriptTimer)
    FunctionTable(126) = GetValue(AddressOf MicroTimer)
    
    FunctionTable(76) = GetValue(AddressOf SetPlayerGuild)
    
    FunctionTable(77) = GetValue(AddressOf GetFlag)
    FunctionTable(78) = GetValue(AddressOf SetFlag)
   
    FunctionTable(79) = GetValue(AddressOf GetPlayerFlag)
    FunctionTable(80) = GetValue(AddressOf SetPlayerFlag)
    
    FunctionTable(81) = GetValue(AddressOf ResetPlayerFlag)
    
    FunctionTable(82) = GetValue(AddressOf SetPlayerAccess)
    
    FunctionTable(83) = GetValue(AddressOf GetObjX)
    FunctionTable(84) = GetValue(AddressOf GetObjY)
    FunctionTable(85) = GetValue(AddressOf GetObjNum)
    FunctionTable(86) = GetValue(AddressOf GetObjVal)
    FunctionTable(87) = GetValue(AddressOf DestroyObj)
    FunctionTable(88) = GetValue(AddressOf Boot_Player)
    FunctionTable(89) = GetValue(AddressOf Ban_Player)
    FunctionTable(90) = GetValue(AddressOf SetPlayerName)
    FunctionTable(92) = GetValue(AddressOf SetGuildBank)
    FunctionTable(93) = GetValue(AddressOf Find_Player)
    FunctionTable(94) = GetValue(AddressOf StrVal)
    FunctionTable(95) = GetValue(AddressOf GetTileAtt)
    FunctionTable(96) = GetValue(AddressOf GetPlayerIP)
    FunctionTable(97) = GetValue(AddressOf RunScript4)
    FunctionTable(98) = GetValue(AddressOf SpawnMonster)
    FunctionTable(99) = GetValue(AddressOf SetPlayerStatus)
    FunctionTable(100) = GetValue(AddressOf GivePlayerExp)
    FunctionTable(103) = GetValue(AddressOf GetObjectName)
    FunctionTable(104) = GetValue(AddressOf GetObjectData)
    FunctionTable(105) = GetValue(AddressOf GetObjectType)
    FunctionTable(106) = GetValue(AddressOf DisplayObjDur)
    FunctionTable(107) = GetValue(AddressOf SetInvObjectVal)
    FunctionTable(108) = GetValue(AddressOf PlayCustomWav)
    FunctionTable(109) = GetValue(AddressOf GetPlayerArmor)
    FunctionTable(110) = GetValue(AddressOf CreateTileEffect)
    FunctionTable(111) = GetValue(AddressOf CreateCharacterEffect)
    FunctionTable(112) = GetValue(AddressOf CreateMonsterEffect)
    FunctionTable(113) = GetValue(AddressOf CreatePlayerEffect)
    FunctionTable(114) = GetValue(AddressOf LogAction)
    FunctionTable(115) = GetValue(AddressOf GetPlayerDirection)
    FunctionTable(133) = GetValue(AddressOf SetPlayerDead)
    FunctionTable(137) = GetValue(AddressOf GetPlayerDead)
    FunctionTable(134) = GetValue(AddressOf FloatText)
    FunctionTable(135) = GetValue(AddressOf PlayerFloatText)
    FunctionTable(132) = GetValue(AddressOf StaticText)
    FunctionTable(136) = GetValue(AddressOf PlayerStaticText)
    FunctionTable(138) = GetValue(AddressOf GiveMagic)
    FunctionTable(139) = GetValue(AddressOf TakeMagic)
    FunctionTable(140) = GetValue(AddressOf ForceChat)
    FunctionTable(141) = GetValue(AddressOf Free_Map)
    FunctionTable(142) = GetValue(AddressOf DestroyMonster)
    FunctionTable(143) = GetValue(AddressOf GetMapData)
    '145+
End Sub
Function Random(ByVal Max As Long) As Long
    Random = Int(Rnd * Max)
End Function
Sub ForceChat(ByVal Index As Long, ByVal Text As String)
    If Index >= 1 And Index <= MaxUsers Then
        SendSocket Index, Chr$(116) + StrConv(Text, vbUnicode)
    End If
End Sub

Sub FloatText(ByVal Text As String, ByVal Color As Long, ByVal Map As Long, ByVal X As Long, ByVal Y As Long, ByVal Direction As Long)
If Color >= 0 And Color <= 24 Then
    If Text <> "" Then
        If Map >= 1 And Map <= 2000 Then
            If X >= 0 And X <= 11 And Y >= 0 And Y <= 12 Then
                If Direction >= 0 And Direction <= 3 Then SendToMap Map, Chr$(111) + Chr$(X) + Chr$(Y) + Chr$(Direction) + Chr$(Color) + StrConv(Text, vbUnicode)
            End If
        End If
    End If
End If
End Sub
Sub PlayerFloatText(ByVal Index As Long, ByVal Text As String, ByVal Color As Long, ByVal X As Long, ByVal Y As Long, ByVal Direction As Long)
If Color >= 0 And Color <= 24 Then
    If Text <> "" Then
        If Index >= 1 And Index <= MaxUsers Then
            If X >= 0 And X <= 11 And Y >= 0 And Y <= 12 Then
                If Direction >= 0 And Direction <= 3 Then SendSocket Index, Chr$(111) + Chr$(X) + Chr$(Y) + Chr$(Direction) + Chr$(Color) + StrConv(Text, vbUnicode)
            End If
        End If
    End If
End If
End Sub
Sub StaticText(ByVal Text As String, ByVal Color As Long, ByVal Map As Long, ByVal X As Long, ByVal Y As Long)
If Color >= 0 And Color <= 24 Then
    If Text <> "" Then
        If Map >= 1 And Map <= 2000 Then
            If X >= 0 And X <= 11 And Y >= 0 And Y <= 12 Then
                SendToMap Map, Chr$(101) + Chr$(X) + Chr$(Y) + Chr$(Color) + StrConv(Text, vbUnicode)
            End If
        End If
    End If
End If
End Sub
Sub PlayerStaticText(ByVal Index As Long, ByVal Text As String, ByVal Color As Long, ByVal X As Long, ByVal Y As Long)
If Color >= 0 And Color <= 24 Then
    If Text <> "" Then
        If Index >= 1 And Index <= MaxUsers Then
            If X >= 0 And X <= 11 And Y >= 0 And Y <= 12 Then
                SendSocket Index, Chr$(101) + Chr$(X) + Chr$(Y) + Chr$(Color) + StrConv(Text, vbUnicode)
            End If
        End If
    End If
End If
End Sub

Function RunScript(Name As String) As Long
        ScriptRS.Seek "=", Name
        If ScriptRS.NoMatch = False Then
            Dim A As Long, StringCount As Long
            StringCount = StringPointer
            Dim MCode() As Byte
            MCode() = StrConv(ScriptRS!Data, vbFromUnicode)
            RunScript = RunASMScript(MCode(0), FunctionTable(0), Parameter(0))
            For A = StringCount To StringPointer - 1
                SysFreeString StringStack(A)
            Next A
            StringPointer = StringCount
        End If
End Function
Sub SetPlayerName(ByVal Index As Long, ByVal Name As String)
    If Index >= 1 And Index <= MaxUsers Then
        With Player(Index)
            If .Mode = modePlaying Then
                .Name = StrConv(Name, vbUnicode)
                SendAll Chr$(64) + Chr$(Index) + .Name
                RefreshOnline
            End If
        End With
    End If
End Sub
Sub SetPlayerMana(ByVal Index As Long, ByVal Mana As Long)
    If Index >= 1 And Index <= MaxUsers Then
        With Player(Index)
            If .Mode = modePlaying Then
                If Mana > 255 Then Mana = 255
                If Mana < 0 Then Mana = 0
                .Mana = Mana
                SendSocket Index, Chr$(48) + Chr$(Mana)
            End If
        End With
    End If
End Sub
Sub SetPlayerHP(ByVal Index As Long, ByVal HP As Long)
    If Index >= 1 And Index <= MaxUsers Then
        With Player(Index)
            If .Mode = modePlaying Then
                If HP > 255 Then HP = 255
                If HP < 1 Then HP = 1
                .HP = HP
                SendSocket Index, Chr$(46) + Chr$(HP)
            End If
        End With
    End If
End Sub
Sub SetPlayerStatus(ByVal Index As Long, ByVal Status As Long)
If Index >= 1 And Index <= MaxUsers And Status >= 0 And Status <= 100 Then
    With Player(Index)
        If .Mode = modePlaying Then
            .Status = Status
            SendAll Chr$(91) + Chr$(Index) + Chr$(Status)
        End If
    End With
End If
End Sub
Sub SetPlayerGuild(ByVal Index As Long, ByVal GuildIndex As Long, ByVal Rank As Long)
Dim A As Long, B As String
    If Index >= 1 And Index <= MaxUsers And GuildIndex >= 0 And GuildIndex <= 255 Then
        With Player(Index)
            If GuildIndex > 0 Then
                If .Guild <> GuildIndex Then
                    .Guild = GuildIndex
                    If Rank > 3 Then .GuildRank = 3 Else .GuildRank = Rank
                    If Guild(GuildIndex).Sprite > 0 Then
                        .Sprite = Guild(GuildIndex).Sprite
                        SendAll Chr$(63) + Chr$(0) + Chr$(Index) + Chr$(.Sprite)
                    End If
                    SendSocket Index, Chr$(72) + Chr$(GuildIndex) 'Change guild
                    SendAllBut Index, Chr$(73) + Chr$(Index) + Chr$(GuildIndex) 'Player changed guild
                End If
            Else
                If .Guild > 0 Then
                    If Guild(.Guild).Sprite > 0 Then
                        .Sprite = Guild(.Guild).Sprite
                        SendAll Chr$(63) + Chr$(0) + Chr$(Index) + Chr$(.Sprite)
                    End If
                    .Guild = 0
                    SendSocket Index, Chr$(72) + Chr$(0) 'Change guild
                    SendAllBut Index, Chr$(73) + Chr$(Index) + Chr$(0) 'Player changed guild
                End If
            End If
        End With
    End If
End Sub
Sub SetGuildBank(ByVal Index As Long, ByVal Bank As Long)
    If Index >= 1 And Index <= 255 Then
        With Guild(Index)
            If .Name <> "" Then
                .Bank = Bank
                GuildRS.Bookmark = .Bookmark
                GuildRS.Edit
                GuildRS!Bank = Bank
                GuildRS.Update
            End If
        End With
    End If
End Sub
Function PlayerWarp(ByVal Index As Long, ByVal Map As Long, ByVal X As Long, ByVal Y As Long) As Long
    If Index >= 1 And Index <= MaxUsers And Map >= 1 And Map <= 2000 And X >= 0 And X <= 11 And Y >= 0 And Y <= 11 Then
        With Player(Index)
            If .Mode = modePlaying Then
                If Map <> .Map Then
                    Partmap Index
                    .Map = Map
                    .X = X
                    .Y = Y
                    JoinMap Index
                Else
                    ChangeXY Index, X, Y
                End If
            End If
        End With
    End If
End Function
Sub DeleteString(ByVal StPointer As Long)
End Sub
Function StrVal(ByVal String1 As String) As Long
    On Error Resume Next
    StrVal = Int(Val(StrConv(String1, vbUnicode)))
    On Error GoTo 0
End Function

Function TakeObj(ByVal Index As Long, ByVal ObjIndex As Long, ByVal Amount As Long) As Long
    Dim A As Long
    If Index >= 1 And Index <= MaxUsers And ObjIndex >= 1 And ObjIndex <= 255 Then
        With Player(Index)
            If .Mode = modePlaying Then
                A = FindInvObject(Index, ObjIndex)
                If A > 0 Then
                    With .Inv(A)
                        If Object(ObjIndex).Type = 6 Then
                            If .Value >= Amount Then
                                .Value = .Value - Amount
                                If .Value = 0 Then
                                    .Object = 0
                                    SendSocket Index, Chr$(18) + Chr$(A)
                                Else
                                    SendSocket Index, Chr$(17) + Chr$(A) + Chr$(ObjIndex) + QuadChar(.Value) 'New Inv Obj
                                End If
                                TakeObj = Amount
                            End If
                        Else
                            .Object = 0
                            TakeObj = 1
                            SendSocket Index, Chr$(18) + Chr$(A)
                        End If
                    End With
                End If
            End If
        End With
    End If
End Function

Sub SetPlayerAccess(ByVal Index As Long, ByVal Access As Long)
    If Index >= 1 And Index <= MaxUsers Then
        With Player(Index)
            If .Mode = modePlaying And .Access <= 4 Then
                If Access < 0 Then
                    .Access = 0
                ElseIf Access > 4 Then
                    .Access = 4
                Else
                    .Access = Access
                End If
    
                SendSocket Index, Chr$(65) + Chr$(Access)
                If Access > 0 Then
                    SendAllBut Index, Chr$(91) + Chr$(Index) + Chr$(3)
                    .Status = 3
                Else
                    SendAllBut Index, Chr$(91) + Chr$(Index) + Chr$(0)
                    .Status = 0
                End If
            End If
        End With
    End If
End Sub
Sub GivePlayerExp(ByVal Index As Long, ByVal Experience As Long)
If Index >= 1 And Index <= MaxUsers And Experience <= 1000000 Then
    GainExp Index, Experience
    SendSocket Index, Chr$(60) + QuadChar(Player(Index).Experience)
End If
End Sub
Sub GiveMagic(ByVal Index As Long, ByVal MagicNum As Long)
If Index >= 1 And Index <= MaxUsers Then
    If MagicNum >= 1 And MagicNum <= 255 Then
        GivePlayerMagic Index, MagicNum
    End If
End If
End Sub
Sub TakeMagic(ByVal Index As Long, ByVal MagicNum As Long)
If Index >= 1 And Index <= MaxUsers Then
    If MagicNum >= 1 And MagicNum <= 255 Then
        TakePlayerMagic Index, MagicNum
    End If
End If
End Sub
Function GetObjectName(ByVal ObjectNum As Long) As Long
If ObjectNum >= 1 And ObjectNum <= 255 Then
    GetObjectName = NewString(Object(ObjectNum).Name)
End If
End Function
Function GetObjectData(ByVal ObjectNum As Long, ByVal DataNum As Long) As Long
If ObjectNum >= 1 And ObjectNum <= 255 Then
    If DataNum >= 0 And DataNum <= 3 Then
        GetObjectData = Object(ObjectNum).Data(DataNum)
    End If
End If
End Function
Function GetObjectType(ByVal ObjectNum As Long) As Long
If ObjectNum >= 1 And ObjectNum <= 255 Then
    GetObjectType = Object(ObjectNum).Type
End If
End Function
Sub DisplayObjDur(ByVal Index As Long, ByVal ObjectNum As Long)
Dim Percent As Single, St As String, MsgColor As Long

If Index < 1 Or Index > MaxUsers Then Exit Sub
If ObjectNum < 1 Or ObjectNum > 20 Then Exit Sub
If Player(Index).Inv(ObjectNum).Object < 1 Or Player(Index).Inv(ObjectNum).Object > 255 Then Exit Sub
    
Dim Display As Boolean
    Select Case Object(Player(Index).Inv(ObjectNum).Object).Type
    Case 1, 2, 3, 4
        Display = True
    Case Else
        Display = False
    End Select
If Display = True Then
    'Percent = Int((Player(Index).Inv(ObjectNum).Value * 5) / Object(Player(Index).Inv(ObjectNum).Object).Data(0))
    If (Object(Player(Index).Inv(ObjectNum).Object).Data(0)) <> 0 Then
        Percent = Player(Index).Inv(ObjectNum).Value / (Object(Player(Index).Inv(ObjectNum).Object).Data(0) * 10)
    Else
        Percent = 0
    End If
    Percent = Int(Percent * 100)
    If Percent > 100 Then Percent = 100
    If Percent <= 5 Then
        St = "Your " + Object(Player(Index).Inv(ObjectNum).Object).Name + " is about to break!"
        MsgColor = 2
    Else
        St = "Your " + Object(Player(Index).Inv(ObjectNum).Object).Name + " is at " + CStr(Percent) + "% durability."
        MsgColor = 14
    End If
    SendSocket Index, Chr$(56) + Chr$(MsgColor Mod 16) + St
Else
    St = "This is an invalid object or no object."
    MsgColor = 2
    SendSocket Index, Chr$(56) + Chr$(MsgColor Mod 16) + St
End If
End Sub
Sub SetInvObjectVal(ByVal Index As Long, ByVal InvSlot As Long, ByVal NewVal As Long)
If Index >= 1 And Index <= MaxUsers And InvSlot >= 1 And InvSlot <= 20 Then
    Player(Index).Inv(InvSlot).Value = NewVal
End If
End Sub
Sub PlayCustomWav(ByVal Index As Long, ByVal SoundNum As Long)
If Index >= 1 And Index <= MaxUsers And SoundNum <= 255 And SoundNum >= 1 Then
    SendSocket Index, Chr$(96) + Chr$(SoundNum)
End If
End Sub
Function GetPlayerArmor(ByVal Index As Long, ByVal Damage As Long) As Long
If Index >= 1 And Index <= MaxUsers And Damage <= 255 And Damage >= 1 Then
    GetPlayerArmor = PlayerArmor(Index, Damage)
End If
End Function
Sub CreateTileEffect(ByVal Index As Long, ByVal X As Long, ByVal Y As Long, ByVal Sprite As Long, ByVal Speed As Long, ByVal TotalFrames As Long, ByVal LoopCount As Long, ByVal EndSound As Long)
    Dim A As Integer
    If Index >= 1 And Index <= 2000 Then
        If X < 0 Then X = 0
        If X > 11 Then X = 11
        If Y < 0 Then Y = 0
        If Y > 11 Then Y = 11
        SendToMap Index, Chr$(99) + Chr$(1) + Chr$(X) + Chr$(Y) + Chr$(Sprite) + DoubleChar(Speed) + Chr$(TotalFrames) + Chr$(LoopCount) + Chr$(EndSound)
    End If
End Sub
Sub CreateCharacterEffect(ByVal Index As Long, ByVal Player As Long, ByVal Sprite As Long, ByVal Speed As Long, ByVal TotalFrames As Long, ByVal LoopCount As Long, ByVal EndSound As Long)
    If Index >= 1 And Index <= 2000 Then
        SendToMap Index, Chr$(99) + Chr$(2) + Chr$(Player) + Chr$(Sprite) + DoubleChar(Speed) + Chr$(TotalFrames) + Chr$(LoopCount) + Chr$(EndSound)
    End If
End Sub
Sub CreateMonsterEffect(ByVal Index As Long, ByVal Player As Long, ByVal Monster As Long, ByVal Sprite As Long, ByVal Speed As Long, ByVal TotalFrames As Long, ByVal EndSound As Long)
    If Index >= 1 And Index <= 2000 Then
        SendToMap Index, Chr$(99) + Chr$(3) + Chr$(Player) + Chr$(Monster) + Chr$(Sprite) + DoubleChar(Speed) + Chr$(TotalFrames) + Chr$(EndSound)
    End If
End Sub
Sub CreatePlayerEffect(ByVal Index As Long, ByVal SourcePlayer As Long, ByVal TargetPlayer As Long, ByVal Sprite As Long, ByVal Speed As Long, ByVal TotalFrames As Long, ByVal EndSound As Long)
    If Index >= 1 And Index <= 2000 Then
        SendToMap Index, Chr$(99) + Chr$(4) + Chr$(SourcePlayer) + Chr$(TargetPlayer) + Chr$(Sprite) + DoubleChar(Speed) + Chr$(TotalFrames) + Chr$(EndSound)
    End If
End Sub
Sub LogAction(ByVal UserName As String, ByVal St As String)
    PrintToFile StrConv(UserName, vbUnicode) + ".log", StrConv(St, vbUnicode)
End Sub
Function GetPlayerDirection(ByVal Index As Long) As Long
    If Index >= 1 And Index <= MaxUsers Then
        GetPlayerDirection = Player(Index).D
    End If
End Function
Sub Calculate_Stats(ByVal Index As Long)
    If Index >= 1 And Index <= MaxUsers Then
        CalculateStats Index
    End If
End Sub
