22-10-2006, 05:45 AM
Difficulty: 1/5 - I Walked Through Even The Simplest of Code so Anyone Can Add This Code.
Just Make Sure you Read!!!!!!
First off, lets start with the most obvious two variables that needed to be added, are they (and by they, i mean the npc) achilles, and if they are, what weapon is their weakness? So on the Client and Server Add the Following Two Variables to the NPCRec
Now since the "common" piece of the puzzle has been added, lets start with the client
Now That We Have That Setup, lets open frmNpcEditor and get the system ready to go. First add a checkbox to the form, and name it chkAchilles. Next, make a Combo Box, and name it cmbAchilles. In the Object Properties for the combo box you just created, make sure you set the "Style" to "2 - Dropdown List". Also, make sure that the Combo box is not enabled (in the properties list, set Enabled to false). Now, if you click twice on the Checkbox that you just created (chkAchilles) it should open your code and create a new sub, called
If it does NOT create this sub, then near the top, just below the menu toolbar, you will see two drop down lists, one that says chkAchilles and the other may say something like Double Click, all you have to do is drop-down that list and select "Click", when you do, it will create the sub for you, or you can copy/paste the one from the code i provided above.
Now in that sub, if the box is checked, we want the combo box to be enabled, so the admin can actually select which weapon is going to be used to kill this particular NPC. So in the sub we add this code
If the box is checked, it enables it, if the box isn't checked, it disables it. That's Simple enough, right?
Moving along, we need to tell the Editor How it should handle the variable after it is recieved or before it is sent. So search for the Sub "NpcEditorInit". After locating the sub, which should look similar to the following
The first thing you want to do is at the top, below the "On Error Resume Next", add
you may also want to remove the On Error Resume Next (it's problematic when trying to debug, but unrelated to what we're doing, you can leave it if you like). Now, below the line
we need to add
Let Me Break This Down Line by Line, The First Line, will either Check, or Uncheck the CheckBox we created Earlier, if the enemy was already saved, and that box had been checked.
Next, the Combo Box we created needed to be cleared, so we created the line to empty the box.
The Next 3 Lines are what's called a For Loop. This loop (which starts at 1), will go through, and add everything contained in it, until it reaches its max value, in this case, the value for MAX_ITEMS, which is by default, 255. (i.e., It will start at #1, and then it will start going until it finds the "next", once it finds the next, it goes back to the beginning, and then does the same thing for #2, all of the way up until the maximum value that the user specifies. If you have trouble understanding the concept of For Loops, i'm sure there are several members here who are more qualified than i am to explain it to you.)
The Line Within The For Loop, frmnpceditor.cmbachilles.additem i & ": " & Trim$(Item(i).Name), simply adds the number that the loop is currently on, a semicolon and a space, and then the name of the item that the loop is on (e.g., if we're on loop number one, it would add this to the combo box.... 1: ItemOneName) Now, all of that will happen when the editor loads, but what about after we're done?
The Sub Below our Current Sub Should Be
If it is not, you can search for it. In The Sub, Just before the line that reads
Add these two new lines
Your New Sub Should Look Liek This
That sets up the tone for our next stanza. Right now that NPC according to the client has that information, but it isn't being sent to the server to be stored, so we need to do that so find Sub SendSaveNpc(ByVal NpcNum As Long).
When you've located it, you'll see a long line of code that's preceded by a "Packet =", this whole sub is the code that sends all of your NPC information to the server to be saved!
*Brief Explanation of Mirage's Packet System*, each packet is sent as a string. When the packet is recieved, it is divided up, based on the location of the "SEPERATOR", and then it continues to the next portion of the packet, until it reaches the "ENDING". This are defined in Mirage as a Single Character (Char), and Look like the following:
SEPERATOR:
SEP_CHAR
ENDING:
END_CHAR
If you do not seperate each value, when your packet is recieved by the server, it will "slur" it all together, so it is vital that you seperate each value, and have a seperator, just before the end of the packet.
Now That We Understand how Mirage uses packets, we can knock this out easily, right?
our original packet looks similar to this:
all we have to do, is before the packet is ended, add our two new variables (IsAchilles, and Achilles)!
So the new packet should look similar to this:
Now, we have the packet actually being sent by the client, but the server has no idea how to handle it correctly since we added new variables to it!
Lets update that packet and make sure it works!!!
*Another Brief Mirage Packet Explanation*
When a packet is recieved, the only way that it can be understood is to read the "name" of the packet and seperate them out. If you look on your client, the name of the packet was "savenpc" (including quotes). When the packets are divided up as mentioned earlier, it starts at 0 (e.g., packet = "savenpc" & sep_char ......... the first thing to show up, is the packet name, and since it starts at 0, this is part 0 of the packet).
Well that's all well and fine, but why was that relevant? Because now we have to update our "savenpc" on the server.
so do a search for "savenpc", you're looking for the line of code that looks like:
if lcase(parse(0)) = "savenpc" then
once you've found that line you'll be looking at a code similar to this:
now, we added our new pieces to the packet after MAGI, remember? So all we have to do now is add these below magi
So your result should be
Now the server recieved the data, but it wasn't saved, yet. So find
And we have to add our new information again. Can you guess where?
If you said, below magi, that is correct. The Sub (after you add the new code) should look like this:
So what we have so far is...
It's Loaded On The Editor
Sent From The Editor
Recieved By The Server
Saved By The Server
There are three more things we need to do before we are done. Load it on the server, send it to the client, and then write the actual code to keep the npc from being killed.
First let's load it, that's pretty simple.Still on the server, find this sub
yes... this sub also has an on error resume next, you can remove it if you'd like, it may be problematic if you have to debug later. Again, that part is your choice. now we have to tell it to load our variables... so add it below magi again!
the result (after you add the variables) should look like this:
Now, let's add the code to tell the server to send the NPC Information to the client, and the client understand it.
So Find this Sub
Remember how we managed the packet earlier? Same concept here, at the end, before the end_char, we need to add our new variables accordingly.
The Final Result after adding the variables should look like this:
Now it's sent to the client, but the client doesn't manage it correctly yet, so lets find it and fix it for the client.
Search for the line of code (remember, the packet name) that looks like this:
Now all we have to do is update that packet to work correctly, the final result should look like this:
[code]
' :::::::::::::::::::::
' :: Edit npc packet ::
Just Make Sure you Read!!!!!!
First off, lets start with the most obvious two variables that needed to be added, are they (and by they, i mean the npc) achilles, and if they are, what weapon is their weakness? So on the Client and Server Add the Following Two Variables to the NPCRec
Code:
IsAchilles as Byte ' This is a Yes/No and it saves more space to use a byte, not a boolean
Achilles as Long ' This will be the ItemNum that is able to defeat them
Now since the "common" piece of the puzzle has been added, lets start with the client
Code:
:::::::::::::::::
:: Client Side ::
:::::::::::::::::
Now That We Have That Setup, lets open frmNpcEditor and get the system ready to go. First add a checkbox to the form, and name it chkAchilles. Next, make a Combo Box, and name it cmbAchilles. In the Object Properties for the combo box you just created, make sure you set the "Style" to "2 - Dropdown List". Also, make sure that the Combo box is not enabled (in the properties list, set Enabled to false). Now, if you click twice on the Checkbox that you just created (chkAchilles) it should open your code and create a new sub, called
Code:
Private Sub chkAchilles_Click()
End Sub
If it does NOT create this sub, then near the top, just below the menu toolbar, you will see two drop down lists, one that says chkAchilles and the other may say something like Double Click, all you have to do is drop-down that list and select "Click", when you do, it will create the sub for you, or you can copy/paste the one from the code i provided above.
Now in that sub, if the box is checked, we want the combo box to be enabled, so the admin can actually select which weapon is going to be used to kill this particular NPC. So in the sub we add this code
Code:
If chkAchilles.Value = 1 Then
cmbAchilles.Enabled = True
Else
cmbAchilles.Enabled = False
End If
If the box is checked, it enables it, if the box isn't checked, it disables it. That's Simple enough, right?
Moving along, we need to tell the Editor How it should handle the variable after it is recieved or before it is sent. So search for the Sub "NpcEditorInit". After locating the sub, which should look similar to the following
Code:
On Error Resume Next
frmNpcEditor.picSprites.Picture = LoadPicture(App.Path & "\sprites.bmp")
frmNpcEditor.txtName.Text = Trim(Npc(EditorIndex).Name)
frmNpcEditor.txtAttackSay.Text = Trim(Npc(EditorIndex).AttackSay)
frmNpcEditor.scrlSprite.Value = Npc(EditorIndex).Sprite
frmNpcEditor.txtSpawnSecs.Text = STR(Npc(EditorIndex).SpawnSecs)
frmNpcEditor.cmbBehavior.ListIndex = Npc(EditorIndex).Behavior
frmNpcEditor.scrlRange.Value = Npc(EditorIndex).Range
frmNpcEditor.txtChance.Text = STR(Npc(EditorIndex).DropChance)
frmNpcEditor.scrlNum.Value = Npc(EditorIndex).DropItem
frmNpcEditor.scrlValue.Value = Npc(EditorIndex).DropItemValue
frmNpcEditor.scrlSTR.Value = Npc(EditorIndex).STR
frmNpcEditor.scrlDEF.Value = Npc(EditorIndex).DEF
frmNpcEditor.scrlSPEED.Value = Npc(EditorIndex).SPEED
frmNpcEditor.scrlMAGI.Value = Npc(EditorIndex).MAGI
frmNpcEditor.Show vbModal
The first thing you want to do is at the top, below the "On Error Resume Next", add
Code:
dim i as long
you may also want to remove the On Error Resume Next (it's problematic when trying to debug, but unrelated to what we're doing, you can leave it if you like). Now, below the line
Code:
frmNpcEditor.scrlMAGI.Value = Npc(EditorIndex).MAGI
we need to add
Code:
frmNpcEditor.chkAchilles.Value = Npc(EditorIndex).IsAchilles
frmNpcEditor.cmbAchilles.clear
for i = 1 to max_items
If item(i).type = ITEM_TYPE_WEAPON Then
frmnpceditor.cmbachilles.additem i & ": " & Trim$(Item(i).Name)
Else
frmnpceitor.cmbachilles.additem i & ":"
end if
next i
frmNpcEditor.cmbAchilles.ListIndex = Npc(EditorIndex).Achilles
If Npc(EditorIndex).IsAchilles = 1 then
frmNpcEditor.cmbAchilles.Enabled = True
Else
frmNpcEditor.cmbAchilles.Enabled = False
End if
Let Me Break This Down Line by Line, The First Line, will either Check, or Uncheck the CheckBox we created Earlier, if the enemy was already saved, and that box had been checked.
Next, the Combo Box we created needed to be cleared, so we created the line to empty the box.
The Next 3 Lines are what's called a For Loop. This loop (which starts at 1), will go through, and add everything contained in it, until it reaches its max value, in this case, the value for MAX_ITEMS, which is by default, 255. (i.e., It will start at #1, and then it will start going until it finds the "next", once it finds the next, it goes back to the beginning, and then does the same thing for #2, all of the way up until the maximum value that the user specifies. If you have trouble understanding the concept of For Loops, i'm sure there are several members here who are more qualified than i am to explain it to you.)
The Line Within The For Loop, frmnpceditor.cmbachilles.additem i & ": " & Trim$(Item(i).Name), simply adds the number that the loop is currently on, a semicolon and a space, and then the name of the item that the loop is on (e.g., if we're on loop number one, it would add this to the combo box.... 1: ItemOneName) Now, all of that will happen when the editor loads, but what about after we're done?
The Sub Below our Current Sub Should Be
Code:
Public Sub NpcEditorOk()
If it is not, you can search for it. In The Sub, Just before the line that reads
Code:
Call SendSaveNpc(EditorIndex)
Add these two new lines
Code:
Npc(EditorIndex).IsAchilles = frmNpcEditor.chkAchilles.Value
Npc(EditorIndex).Achilles = frmNpcEditor.cmbAchilles.listindex + 1
Your New Sub Should Look Liek This
Code:
Public Sub NpcEditorOk()
Npc(EditorIndex).Name = frmNpcEditor.txtName.Text
Npc(EditorIndex).AttackSay = frmNpcEditor.txtAttackSay.Text
Npc(EditorIndex).Sprite = frmNpcEditor.scrlSprite.Value
Npc(EditorIndex).SpawnSecs = Val(frmNpcEditor.txtSpawnSecs.Text)
Npc(EditorIndex).Behavior = frmNpcEditor.cmbBehavior.ListIndex
Npc(EditorIndex).Range = frmNpcEditor.scrlRange.Value
Npc(EditorIndex).DropChance = Val(frmNpcEditor.txtChance.Text)
Npc(EditorIndex).DropItem = frmNpcEditor.scrlNum.Value
Npc(EditorIndex).DropItemValue = frmNpcEditor.scrlValue.Value
Npc(EditorIndex).STR = frmNpcEditor.scrlSTR.Value
Npc(EditorIndex).DEF = frmNpcEditor.scrlDEF.Value
Npc(EditorIndex).SPEED = frmNpcEditor.scrlSPEED.Value
Npc(EditorIndex).MAGI = frmNpcEditor.scrlMAGI.Value
Npc(EditorIndex).IsAchilles = frmNpcEditor.chkAchilles.Value
Npc(EditorIndex).Achilles = frmNpcEditor.cmbAchilles.listindex + 1
Call SendSaveNpc(EditorIndex)
InNpcEditor = False
Unload frmNpcEditor
End Sub
That sets up the tone for our next stanza. Right now that NPC according to the client has that information, but it isn't being sent to the server to be stored, so we need to do that so find Sub SendSaveNpc(ByVal NpcNum As Long).
When you've located it, you'll see a long line of code that's preceded by a "Packet =", this whole sub is the code that sends all of your NPC information to the server to be saved!
*Brief Explanation of Mirage's Packet System*, each packet is sent as a string. When the packet is recieved, it is divided up, based on the location of the "SEPERATOR", and then it continues to the next portion of the packet, until it reaches the "ENDING". This are defined in Mirage as a Single Character (Char), and Look like the following:
SEPERATOR:
SEP_CHAR
ENDING:
END_CHAR
If you do not seperate each value, when your packet is recieved by the server, it will "slur" it all together, so it is vital that you seperate each value, and have a seperator, just before the end of the packet.
Now That We Understand how Mirage uses packets, we can knock this out easily, right?
our original packet looks similar to this:
Code:
Packet = "SAVENPC" & SEP_CHAR & NpcNum & SEP_CHAR & Trim(Npc(NpcNum).Name) & SEP_CHAR &
Trim(Npc(NpcNum).AttackSay) & SEP_CHAR & Npc(NpcNum).Sprite & SEP_CHAR & Npc(NpcNum).SpawnSecs & SEP_CHAR &
Npc(NpcNum).Behavior & SEP_CHAR & Npc(NpcNum).Range & SEP_CHAR & Npc(NpcNum).DropChance & SEP_CHAR &
Npc(NpcNum).DropItem & SEP_CHAR & Npc(NpcNum).DropItemValue & SEP_CHAR & Npc(NpcNum).STR & SEP_CHAR &
Npc(NpcNum).DEF & SEP_CHAR & Npc(NpcNum).SPEED & SEP_CHAR & Npc(NpcNum).MAGI & SEP_CHAR & END_CHAR
all we have to do, is before the packet is ended, add our two new variables (IsAchilles, and Achilles)!
So the new packet should look similar to this:
Code:
Packet = "SAVENPC" & SEP_CHAR & NpcNum & SEP_CHAR & Trim(Npc(NpcNum).Name) & SEP_CHAR &
Trim(Npc(NpcNum).AttackSay) & SEP_CHAR & Npc(NpcNum).Sprite & SEP_CHAR & Npc(NpcNum).SpawnSecs & SEP_CHAR &
Npc(NpcNum).Behavior & SEP_CHAR & Npc(NpcNum).Range & SEP_CHAR & Npc(NpcNum).DropChance & SEP_CHAR &
Npc(NpcNum).DropItem & SEP_CHAR & Npc(NpcNum).DropItemValue & SEP_CHAR & Npc(NpcNum).STR & SEP_CHAR &
Npc(NpcNum).DEF & SEP_CHAR & Npc(NpcNum).SPEED & SEP_CHAR & Npc(NpcNum).MAGI & SEP_CHAR & Npc(NpcNum).IsAchilles &
SEP_CHAR & Npc(NpcNum).Achilles & SEP_CHAR & END_CHAR
Now, we have the packet actually being sent by the client, but the server has no idea how to handle it correctly since we added new variables to it!
Code:
:::::::::::::::::
:: Server Side ::
:::::::::::::::::
Lets update that packet and make sure it works!!!
*Another Brief Mirage Packet Explanation*
When a packet is recieved, the only way that it can be understood is to read the "name" of the packet and seperate them out. If you look on your client, the name of the packet was "savenpc" (including quotes). When the packets are divided up as mentioned earlier, it starts at 0 (e.g., packet = "savenpc" & sep_char ......... the first thing to show up, is the packet name, and since it starts at 0, this is part 0 of the packet).
Well that's all well and fine, but why was that relevant? Because now we have to update our "savenpc" on the server.
so do a search for "savenpc", you're looking for the line of code that looks like:
if lcase(parse(0)) = "savenpc" then
once you've found that line you'll be looking at a code similar to this:
Code:
If LCase(Parse(0)) = "savenpc" Then
' Prevent hacking
If GetPlayerAccess(Index) < ADMIN_DEVELOPER Then
Call HackingAttempt(Index, "Admin Cloning")
Exit Sub
End If
n = Val(Parse(1))
' Prevent hacking
If n < 0 Or n > MAX_NPCS Then
Call HackingAttempt(Index, "Invalid NPC Index")
Exit Sub
End If
' Update the npc
Npc(n).Name = Parse(2)
Npc(n).AttackSay = Parse(3)
Npc(n).Sprite = Val(Parse(4))
Npc(n).SpawnSecs = Val(Parse(5))
Npc(n).Behavior = Val(Parse(6))
Npc(n).Range = Val(Parse(7))
Npc(n).DropChance = Val(Parse(8))
Npc(n).DropItem = Val(Parse(9))
Npc(n).DropItemValue = Val(Parse(10))
Npc(n).STR = Val(Parse(11))
Npc(n).DEF = Val(Parse(12))
Npc(n).SPEED = Val(Parse(13))
Npc(n).MAGI = Val(Parse(14))
' Save it
Call SendUpdateNpcToAll(n)
Call SaveNpc(n)
Call AddLog(GetPlayerName(Index) & " saved npc #" & n & ".", ADMIN_LOG)
Exit Sub
End If
now, we added our new pieces to the packet after MAGI, remember? So all we have to do now is add these below magi
Code:
npc(n).IsAchilles = Val(Parse(15))
Npc(n).Achilles = Val(Parse(16))
So your result should be
Code:
If LCase(Parse(0)) = "savenpc" Then
' Prevent hacking
If GetPlayerAccess(Index) < ADMIN_DEVELOPER Then
Call HackingAttempt(Index, "Admin Cloning")
Exit Sub
End If
n = Val(Parse(1))
' Prevent hacking
If n < 0 Or n > MAX_NPCS Then
Call HackingAttempt(Index, "Invalid NPC Index")
Exit Sub
End If
' Update the npc
Npc(n).Name = Parse(2)
Npc(n).AttackSay = Parse(3)
Npc(n).Sprite = Val(Parse(4))
Npc(n).SpawnSecs = Val(Parse(5))
Npc(n).Behavior = Val(Parse(6))
Npc(n).Range = Val(Parse(7))
Npc(n).DropChance = Val(Parse(8))
Npc(n).DropItem = Val(Parse(9))
Npc(n).DropItemValue = Val(Parse(10))
Npc(n).STR = Val(Parse(11))
Npc(n).DEF = Val(Parse(12))
Npc(n).SPEED = Val(Parse(13))
Npc(n).MAGI = Val(Parse(14))
Npc(n).IsAchilles = Val(Parse(15))
Npc(n).Achilles = Val(Parse(16))
' Save it
Call SendUpdateNpcToAll(n)
Call SaveNpc(n)
Call AddLog(GetPlayerName(Index) & " saved npc #" & n & ".", ADMIN_LOG)
Exit Sub
End If
Now the server recieved the data, but it wasn't saved, yet. So find
Code:
Sub SaveNpc(ByVal NpcNum As Long)
And we have to add our new information again. Can you guess where?
If you said, below magi, that is correct. The Sub (after you add the new code) should look like this:
Code:
Sub SaveNpc(ByVal NpcNum As Long)
Dim FileName As String
FileName = App.Path & "\npcs.ini"
Call PutVar(FileName, "NPC" & NpcNum, "Name", Trim(Npc(NpcNum).Name))
Call PutVar(FileName, "NPC" & NpcNum, "AttackSay", Trim(Npc(NpcNum).AttackSay))
Call PutVar(FileName, "NPC" & NpcNum, "Sprite", Trim(Npc(NpcNum).Sprite))
Call PutVar(FileName, "NPC" & NpcNum, "SpawnSecs", Trim(Npc(NpcNum).SpawnSecs))
Call PutVar(FileName, "NPC" & NpcNum, "Behavior", Trim(Npc(NpcNum).Behavior))
Call PutVar(FileName, "NPC" & NpcNum, "Range", Trim(Npc(NpcNum).Range))
Call PutVar(FileName, "NPC" & NpcNum, "DropChance", Trim(Npc(NpcNum).DropChance))
Call PutVar(FileName, "NPC" & NpcNum, "DropItem", Trim(Npc(NpcNum).DropItem))
Call PutVar(FileName, "NPC" & NpcNum, "DropItemValue", Trim(Npc(NpcNum).DropItemValue))
Call PutVar(FileName, "NPC" & NpcNum, "STR", Trim(Npc(NpcNum).STR))
Call PutVar(FileName, "NPC" & NpcNum, "DEF", Trim(Npc(NpcNum).DEF))
Call PutVar(FileName, "NPC" & NpcNum, "SPEED", Trim(Npc(NpcNum).SPEED))
Call PutVar(FileName, "NPC" & NpcNum, "MAGI", Trim(Npc(NpcNum).MAGI))
Call PutVar(FileName, "NPC" & NpcNum, "ISACHILLES", Trim(Npc(NpcNum).IsAchilles))
Call PutVar(FileName, "NPC" & NpcNum, "ACHILLES", Trim(Npc(NpcNum).Achilles))
End Sub
So what we have so far is...
It's Loaded On The Editor
Sent From The Editor
Recieved By The Server
Saved By The Server
There are three more things we need to do before we are done. Load it on the server, send it to the client, and then write the actual code to keep the npc from being killed.
First let's load it, that's pretty simple.Still on the server, find this sub
Code:
Sub LoadNpcs()
yes... this sub also has an on error resume next, you can remove it if you'd like, it may be problematic if you have to debug later. Again, that part is your choice. now we have to tell it to load our variables... so add it below magi again!
the result (after you add the variables) should look like this:
Code:
Sub LoadNpcs()
On Error Resume Next
Dim FileName As String
Dim i As Long
Call CheckNpcs
FileName = App.Path & "\npcs.ini"
For i = 1 To MAX_NPCS
Npc(i).Name = GetVar(FileName, "NPC" & i, "Name")
Npc(i).AttackSay = GetVar(FileName, "NPC" & i, "AttackSay")
Npc(i).Sprite = GetVar(FileName, "NPC" & i, "Sprite")
Npc(i).SpawnSecs = GetVar(FileName, "NPC" & i, "SpawnSecs")
Npc(i).Behavior = GetVar(FileName, "NPC" & i, "Behavior")
Npc(i).Range = GetVar(FileName, "NPC" & i, "Range")
Npc(i).DropChance = GetVar(FileName, "NPC" & i, "DropChance")
Npc(i).DropItem = GetVar(FileName, "NPC" & i, "DropItem")
Npc(i).DropItemValue = GetVar(FileName, "NPC" & i, "DropItemValue")
Npc(i).STR = GetVar(FileName, "NPC" & i, "STR")
Npc(i).DEF = GetVar(FileName, "NPC" & i, "DEF")
Npc(i).SPEED = GetVar(FileName, "NPC" & i, "SPEED")
Npc(i).MAGI = GetVar(FileName, "NPC" & i, "MAGI")
Npc(i).IsAchilles = GetVar(FileName, "NPC" & i, "ISACHILLES")
Npc(i).Achilles = GetVar(FileName, "NPC" & i, "ACHILLES")
DoEvents
Next i
End Sub
Now, let's add the code to tell the server to send the NPC Information to the client, and the client understand it.
So Find this Sub
Code:
Sub SendEditNpcTo(ByVal Index As Long, ByVal NpcNum As Long)
Remember how we managed the packet earlier? Same concept here, at the end, before the end_char, we need to add our new variables accordingly.
The Final Result after adding the variables should look like this:
Code:
Sub SendEditNpcTo(ByVal Index As Long, ByVal NpcNum As Long)
Dim Packet As String
Packet = "EDITNPC" & SEP_CHAR & NpcNum & SEP_CHAR & Trim(Npc(NpcNum).Name) & SEP_CHAR &
Trim(Npc(NpcNum).AttackSay) & SEP_CHAR & Npc(NpcNum).Sprite & SEP_CHAR & Npc(NpcNum).SpawnSecs & SEP_CHAR &
Npc(NpcNum).Behavior & SEP_CHAR & Npc(NpcNum).Range & SEP_CHAR & Npc(NpcNum).DropChance & SEP_CHAR &
Npc(NpcNum).DropItem & SEP_CHAR & Npc(NpcNum).DropItemValue & SEP_CHAR & Npc(NpcNum).STR & SEP_CHAR &
Npc(NpcNum).DEF & SEP_CHAR & Npc(NpcNum).SPEED & SEP_CHAR & Npc(NpcNum).MAGI & & SEP_CHAR & Npc(NpcNum).IsAchilles &
SEP_CHAR & Npc(NpcNum).Achilles & SEP_CHAR & END_CHAR
Call SendDataTo(Index, Packet)
End Sub
Now it's sent to the client, but the client doesn't manage it correctly yet, so lets find it and fix it for the client.
Code:
:::::::::::::::::
:: Client Side ::
:::::::::::::::::
Search for the line of code (remember, the packet name) that looks like this:
Code:
if lcase(parse(0)) = "editnpc"
Now all we have to do is update that packet to work correctly, the final result should look like this:
[code]
' :::::::::::::::::::::
' :: Edit npc packet ::