Guild System

From VbGORE Visual Basic Online RPG Engine

The guild system is quite basic. It extends the group chat (that, and replaces it). So, what happens is when you run the commands to make a group, you'll actually make a guild. I also added new commands to assign rank and kick a user from the guild. And /ginfo will return the guild name and the users (Rank User (Lvl)). And group members nearby will share xp when pursuing combat. Also, you can't attack fellow members of the guild.

This sets up the foundation for more guild stuff. Btw, if anyone improves on this, It would be much appreciated if you share the improvements.

Contents

Client

We'll start with the Client Side:

DataIDs.bas Find "User_Group_Make As Byte" and below it add this:

<vb> User_Group_Kick As Byte

   User_Group_Assign As Byte</vb>

Then find ".Server_KeepAlive = 121" and below it add

<vb> .User_Group_Kick = 123 'Kicks a user from group

       .User_Group_Assign = 124 'Assigns rank to user in group</vb>


If those numbers are in use, just change them to some other free number.


Input.bas Go to Input_HandleCommands and find "ElseIf Input_GetCommand("/CREATEG")"

Change that block of code to the following:

<vb> ElseIf Input_GetCommand("/CREATEG") Or Input_GetCommand("/MAKEG") Or Input_GetCommand("/NEWG") Then

       s = Input_GetBufferArgs
       If s = vbNullString Then GoTo CleanUp
       sndBuf.Put_Byte DataCode.User_Group_Make
       sndBuf.Put_String s</vb>

and below this add:

<vb> ElseIf Input_GetCommand("/KICK") Then

       s = Input_GetBufferArgs
       If s = vbNullString Then GoTo CleanUp
       sndBuf.Put_Byte DataCode.User_Group_Kick
       sndBuf.Put_String s
  
   ElseIf Input_GetCommand("/ASSIGN") Then
       s = Input_GetBufferArgs
       If s = vbNullString Then GoTo CleanUp
       sndBuf.Put_Byte DataCode.User_Group_Assign
       sndBuf.Put_String s</vb>

Server

Declares.bas Note, you can alter the group settings. just find "'Group settings" in this file. I suggest increasing the max users at least. the default 15 is a bit small.

Find "Type GroupData" and add to it this:

<vb> Name As String</vb>

Find "Type User" and add to it:

<vb> Group As String 'Name of user's group

   GroupRank As Integer    'Rank of user in group (See GroupRanks)</vb>

above the "Type User" line, add this:

<vb>Public GroupRanks(1 To 6) As String</vb>

FileIO.bas go to Load_User and add to the variable declarations at the beginning this:

<vb>Dim GroupInstance As Integer</vb>

Now find "UserList(UserIndex).Stats.ModStat(SID.MaxSTA)" and below that line add:

<vb> UserList(UserIndex).Group = DB_RS!Group

       UserList(UserIndex).GroupRank = DB_RS!GroupRank</vb>

just a bit below that is an "End With" line. below that line add this:

<vb> 'Join/make User's group

   If Len(UserList(UserIndex).Group) > 0 Then
       GroupInstance = -1
       For i = 1 To NumGroups
           If GroupData(i).Name = UserList(UserIndex).Group Then
               GroupInstance = i
               Exit For
           End If
       Next i
      
       If GroupInstance = -1 Then
           'No instance of group found; Create the group
           i = Group_Create(UserIndex)
           If i > 0 Then
               GroupData(i).NumUsers = 1
               ReDim GroupData(i).Users(1 To 1)
               GroupData(i).Users(1) = UserIndex
               UserList(UserIndex).GroupIndex = i
           End If
       Else
           'Instance found; join the group
           Group_AddUser UserIndex, GroupInstance
           UserList(UserIndex).GroupIndex = GroupInstance
       End If
   End If</vb>

go to Save_User and find "DB_RS!stat_sp_max = .Stats.BaseStat(SID.MaxSTA)" and below it add this:

<vb> DB_RS!Group = .Group

       DB_RS!GroupRank = .GroupRank</vb>

Groups.bas at the very beginning, add this sub:

<vb>Public Sub Init_GroupRanks()

   GroupRanks(1) = "General"
   GroupRanks(2) = "Captain"
   GroupRanks(3) = "Lieutenant"
   GroupRanks(4) = "Sergeant"
   GroupRanks(5) = "Corporal"
   GroupRanks(6) = "Recruit"

End Sub</vb>

You can make your ranking system whatever you want. I made it so that the user who makes the guild becomes the "General." The General can enact any guild function (i.e. kick, assign rank, etc.). You can of course alter this and give various ranks different privileges.


TCP.bas Add the following subs:

<vb>Sub Data_User_Group_Assign(ByRef rBuf As DataBuffer, ByVal UserIndex As Integer) '***************************************************************** 'Assign a rank to user from group '<Name(S)> '***************************************************************** Dim tNameRank() As String Dim tName As String Dim tRank As Integer Dim tIndex As Integer Dim Command As String

   'get command from buffer
   Command = rBuf.Get_String
   'Get the name and rank
   tNameRank = Split(Command, " ")
  
   If UBound(tNameRank) <> 1 Then
       ' improper command syntaxx
       Exit Sub
   Else
       If Val(tNameRank(1)) > 0 And Val(tNameRank(1)) < UBound(GroupRanks) And Len(tNameRank(0)) > 0 Then
           tName = tNameRank(0)
           tRank = tNameRank(1)
       Else
           'invalid values for name and or rank
           Exit Sub
       End If
   End If
  
  
   'Make sure the user is in a group
   If UserList(UserIndex).GroupIndex = 0 Then
       Data_Send ToIndex, UserIndex, cMessage(113).Data()
       Exit Sub
   End If
  
    
   'Make sure the user is the leader of the group
   If Not UserList(UserIndex).GroupRank = 1 Then
       Data_Send ToIndex, UserIndex, cMessage(113).Data()
       Exit Sub
   End If
  
  
   'Get the user's index
   tIndex = User_NameToIndex(tName)
  
   'Make sure the user is already part of this group
   If UserList(tIndex).GroupIndex = UserList(UserIndex).GroupIndex Then
       UserList(tIndex).GroupRank = tRank
   End If

End Sub

Sub Data_User_Group_Kick(ByRef rBuf As DataBuffer, ByVal UserIndex As Integer) '***************************************************************** 'Kick a user from group '<Name(S)> '***************************************************************** Dim tName As String Dim tIndex As Integer

   'Get the name
   tName = rBuf.Get_String
  
   'Make sure the user is in a group
   If UserList(UserIndex).GroupIndex = 0 Then
       Data_Send ToIndex, UserIndex, cMessage(113).Data()
       Exit Sub
   End If
  
    
   'Make sure the user is the leader of the group
   If Not UserList(UserIndex).GroupRank = 1 Then
       Data_Send ToIndex, UserIndex, cMessage(113).Data()
       Exit Sub
   End If
  
  
   'Get the user's index
   tIndex = User_NameToIndex(tName)
  
   'Make sure the user is already part of this group
   If UserList(tIndex).GroupIndex = UserList(UserIndex).GroupIndex Then
       Group_RemoveUser tIndex, UserList(tIndex).GroupIndex
      
       UserList(tIndex).Group = ""
       UserList(tIndex).GroupRank = 0
   End If

End Sub</vb>

Locate "Data_User_Group_Info" and change it to this:

<vb>Sub Data_User_Group_Info(ByVal UserIndex As Integer) '***************************************************************** 'User requests the information of their group '<> 'More info: http://www.vbgore.com/GameServer.TCP.Data_User_Group_Info '***************************************************************** Dim i As Byte

   'Check if the user is in a group
   If UserList(UserIndex).GroupIndex = 0 Then
       Data_Send ToIndex, UserIndex, cMessage(123).Data()
       Exit Sub
   End If
  
  
   ConBuf.Clear
  
   '----- Generate the info to return to the user -----
   'Group Name:
   ConBuf.Allocate 9
   ConBuf.Put_Byte DataCode.Comm_Talk
   ConBuf.Put_String UserList(UserIndex).Group
   ConBuf.Put_Byte DataCode.Comm_FontType_Group
  
   'Members List (with level and rank)
   'Returned as: Rank Name (lvl)
   For i = 1 To GroupData(UserList(UserIndex).GroupIndex).NumUsers
       ConBuf.Allocate 9
       ConBuf.Put_Byte DataCode.Comm_Talk
       ConBuf.Put_String "* " & GroupRanks(UserList(GroupData(UserList(UserIndex).GroupIndex).Users(i)).GroupRank) & " " & UserList(GroupData(UserList(UserIndex).GroupIndex).Users(i)).Name & "(" & UserList(GroupData(UserList(UserIndex).GroupIndex).Users(i)).Stats.BaseStat(SID.ELV) & ")"
       ConBuf.Put_Byte DataCode.Comm_FontType_Group
   Next i
  
   'Create the group text packet
   If ConBuf.HasBuffer Then Data_Send ToIndex, UserIndex, ConBuf.Get_Buffer
  

End Sub</vb>

Locate "Data_User_Group_Join" and add the following to the end of it:

<vb> UserList(UserIndex).Group = GroupData(UserList(UserIndex).GroupIndex).Name

   UserList(UserIndex).GroupRank = 6 'set rank to recruit by default</vb>

Locate "Data_User_Group_Leave" and add the following to the bottom of it:

<vb> UserList(UserIndex).Group = ""

   UserList(UserIndex).GroupRank = 0</vb>


Locate "Data_User_Group_Make" and change it to this:

<vb>Sub Data_User_Group_Make(ByRef rBuf As DataBuffer, ByVal UserIndex As Integer) '***************************************************************** 'User wants to create a new group '<> 'More info: http://www.vbgore.com/GameServer.TCP.Data_User_Group_Make '***************************************************************** Dim i As Byte Dim GroupName As String

   'Make sure the user isn't already in a group
   If UserList(UserIndex).GroupIndex > 0 Then Exit Sub
  
   'Get name of new group
   GroupName = rBuf.Get_String
  
  
   'Make sure that group does not already exist
   DB_RS.Open "SELECT DISTINCT users.Group FROM users WHERE `Group`='" & GroupName & "'", DB_Conn, adOpenStatic, adLockOptimistic
  
   If Not DB_RS.EOF Then
       DB_RS.Close
       Exit Sub
   End If
  
   DB_RS.Close
  
  
   'Create the group
   i = Group_Create(UserIndex)
   If i > 0 Then
       Data_Send ToIndex, UserIndex, cMessage(116).Data()
       GroupData(i).NumUsers = 1
       ReDim GroupData(i).Users(1 To 1)
       GroupData(i).Users(1) = UserIndex
       GroupData(i).Name = GroupName
       UserList(UserIndex).GroupIndex = i
       UserList(UserIndex).Group = GroupName
       UserList(UserIndex).GroupRank = 1
   End If

End Sub</vb>

Users.bas Locate User_Attack. Find the line "'Look for user". change that block of code to this:

<vb> 'Look for user

   If MapInfo(AttackPos.Map).Data(AttackPos.X, AttackPos.Y).UserIndex > 0 Then
       TargetIndex = MapInfo(AttackPos.Map).Data(AttackPos.X, AttackPos.Y).UserIndex
      
       If UserList(TargetIndex).GroupIndex <> UserList(UserIndex).GroupIndex Then
           Log "User_Attack: Found a user to attack", CodeTracker '//\\LOGLINE//\\
          
           Damage = User_AttackUser(UserIndex, TargetIndex)
          
           If ObjData.UseGrh(UserList(UserIndex).WeaponEqpObjIndex) > 0 Then
          
               ConBuf.PreAllocate 12
               ConBuf.Put_Byte DataCode.Combo_SlashSoundRotateDamage
               ConBuf.Put_Integer UserList(UserIndex).Char.CharIndex
               ConBuf.Put_Integer UserList(TargetIndex).Char.CharIndex
               ConBuf.Put_Long ObjData.UseGrh(UserList(UserIndex).WeaponEqpObjIndex)
               ConBuf.Put_Byte UseSfx
  
           Else
              
               ConBuf.PreAllocate 8
               ConBuf.Put_Byte DataCode.Combo_SoundRotateDamage
               ConBuf.Put_Integer UserList(UserIndex).Char.CharIndex
               ConBuf.Put_Integer UserList(TargetIndex).Char.CharIndex
               ConBuf.Put_Byte UseSfx
              
           End If
          
           If Damage > 32000 Then ConBuf.Put_Integer 32000 Else ConBuf.Put_Integer Damage
           Data_Send ToPCArea, UserIndex, ConBuf.Get_Buffer
          
           User_AttackUser_ApplyDamage UserIndex, TargetIndex, Damage
          
           Exit Sub
       End If
   End If</vb>

Go to your frmMain code. Go to Form_Load. Find "'Show the form - displays in the "loading" state". above that add this:

<vb> 'Initialize Group Ranks

   Init_GroupRanks</vb>

Go to OnDataArrival and find "Case .User_Use: Data_User_Use rBuf, Index" below that add this:

<vb> Case .User_Group_Kick: Data_User_Group_Kick rBuf, Index

           Case .User_Group_Assign: Data_User_Group_Assign rBuf, Index</vb>

MySQL Database

Go to your users table. Open it to add new columns. Add these two columns:

  • Group

- DataType: tinytext - Comment: Group Name

  • GroupRank

- DataType: tinyint - len: 4 - Default: 0 - Not Null?: checked - Comment: Rank in Guild


That's it (unless I missed something. If you get an error, let me know and I'll post what I overlooked).

Guild Commands

/INVITE <name> invites player to join guild

/LEAVEG leave the guild

/JOING accept an invite to join a guild

/ASSIGN <name> <#> assignes rank to a player

/KICK <name> kicks player from guild.

/CREATEG <name> /MAKEG <name> /NewG <name> all the above make a new guild with the specified name

/G <message> send message to guild members


/GINFO /GROUPI gets info about your guild (members, their ranks, and the guild name)

in the Input_HandleCommands, I changed GROUPI to GUILDI. that's optional of course.

This tutorial is made by: GoreMania

Personal tools