Non-Playable Character Chat
This was %100 done by Pando.
Features
NPC Say
Player Response
NPC Response
Visual NPCS
This system will work when you press enter next to an NPC.
Tested on MS 3.03 and should work on 3.03 and mse v-x.
After This, your attacksay will not work.
First Serverside ::
Add this to the bottom of
modGameLogic
Code:
Public Sub TalkToNpc(ByVal Player As Long, ByVal MapNpcNum As Long)
Dim MapNum As Long, NpcNum As Long
' Check for subscript out of range
If IsPlaying(Player) = False Or MapNpcNum <= 0 Or MapNpcNum > MAX_MAP_NPCS Then
Exit Sub
End If
' Check for subscript out of range
If MapNpc(GetPlayerMap(Player), MapNpcNum).Num <= 0 Then
Exit Sub
End If
MapNum = GetPlayerMap(Player)
NpcNum = MapNpc(MapNum, MapNpcNum).Num
' Make sure they are on the same map
If IsPlaying(Player) Then
If NpcNum > 0 Then
' Check if at same coordinates
Select Case GetPlayerDir(Player)
Case DIR_UP
If (MapNpc(MapNum, MapNpcNum).y + 1 = GetPlayerY(Player)) And (MapNpc(MapNum, MapNpcNum).x = GetPlayerX(Player)) Then
If Npc(NpcNum).Behavior = NPC_BEHAVIOR_FRIENDLY Then
Call SendNPCTalk(Player, MapNpcNum)
End If
End If
Case DIR_DOWN
If (MapNpc(MapNum, MapNpcNum).y - 1 = GetPlayerY(Player)) And (MapNpc(MapNum, MapNpcNum).x = GetPlayerX(Player)) Then
If Npc(NpcNum).Behavior = NPC_BEHAVIOR_FRIENDLY Then
Call SendNPCTalk(Player, MapNpcNum)
End If
End If
Case DIR_LEFT
If (MapNpc(MapNum, MapNpcNum).y = GetPlayerY(Player)) And (MapNpc(MapNum, MapNpcNum).x + 1 = GetPlayerX(Player)) Then
If Npc(NpcNum).Behavior = NPC_BEHAVIOR_FRIENDLY Then
Call SendNPCTalk(Player, MapNpcNum)
End If
End If
Case DIR_RIGHT
If (MapNpc(MapNum, MapNpcNum).y = GetPlayerY(Player)) And (MapNpc(MapNum, MapNpcNum).x - 1 = GetPlayerX(Player)) Then
If Npc(NpcNum).Behavior = NPC_BEHAVIOR_FRIENDLY Then
Call SendNPCTalk(Player, MapNpcNum)
End If
End If
End Select
End If
End If
End Sub
Add this to the bottom of
Sub HandleDataCode:
' ::::::::::::::::::::::::::
' :: Talk To NPC packet ::
' ::::::::::::::::::::::::::
If LCase(Parse(0)) = "npctalk" Then
' Try to talk to npc
For i = 1 To MAX_MAP_NPCS
Call TalkToNpc(Index, i)
Next i
Exit Sub
End If
Add this to the bottom of
modServerTCPCode:
Sub SendNPCTalk(ByVal Index As Long, ByVal NpcNum As Long)
Dim Packet As String
Packet = "NPCTALK" & SEP_CHAR & NpcNum & SEP_CHAR & Trim(Npc(NpcNum).Name) & SEP_CHAR & Trim(Npc(NpcNum).Say) & SEP_CHAR & Trim(Npc(NpcNum).PlayerResponse) & SEP_CHAR & Trim(Npc(NpcNum).NpcResponse) & SEP_CHAR & Npc(NpcNum).Sprite & SEP_CHAR & END_CHAR
Call SendDataTo(Index, Packet)
End Sub
Find
Code:
' Update the npc
Replace all with
Code:
' Update the npc
Npc(n).Name = Parse(2)
Npc(n).Say = Parse(3)
Npc(n).PlayerResponse = Parse(4)
Npc(n).NpcResponse = Parse(5)
Npc(n).Sprite = Val(Parse(6))
Npc(n).SpawnSecs = Val(Parse(7))
Npc(n).Behavior = Val(Parse(8))
Npc(n).Range = Val(Parse(9))
Npc(n).DropChance = Val(Parse(10))
Npc(n).DropItem = Val(Parse(11))
Npc(n).DropItemValue = Val(Parse(12))
Npc(n).STR = Val(Parse(13))
Npc(n).DEF = Val(Parse(14))
Npc(n).SPEED = Val(Parse(15))
Npc(n).MAGI = Val(Parse(16))
In Type NpcRec Replace AttackSay with
Code:
Say As String * 200
PlayerResponse As String * 100
NpcResponse As String * 200
Now ClientSide::Replace Sub NpcEditorInit with
Code:
Public Sub NpcEditorInit()
On Error Resume Next
frmNpcEditor.picSprites.Picture = LoadPicture(App.Path & "\sprites.bmp")
frmNpcEditor.txtName.Text = Trim(Npc(EditorIndex).Name)
frmNpcEditor.txtSay.Text = Trim(Npc(EditorIndex).Say)
frmNpcEditor.txtPlayerResponse.Text = Trim(Npc(EditorIndex).PlayerResponse)
frmNpcEditor.txtNPCResponse.Text = Trim(Npc(EditorIndex).NpcResponse)
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
End Sub
Public Sub NpcEditorOk()
Npc(EditorIndex).Name = frmNpcEditor.txtName.Text
Npc(EditorIndex).Say = frmNpcEditor.txtSay.Text
Npc(EditorIndex).PlayerResponse = frmNpcEditor.txtPlayerResponse.Text
Npc(EditorIndex).NpcResponse = frmNpcEditor.txtNPCResponse.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
Call SendSaveNpc(EditorIndex)
InNpcEditor = False
Unload frmNpcEditor
End Sub
Now setup 2 textboxes, 1 as txtPlayerResponse and the other NPCResponse. Set NPCResponse's multiline = true in properties. Now Rename txtAttackSay with txtSay. Change to multiline = true and then enlargen size of textbox.
Find the sub
Sub CheckAttack(), Above that add
Code:
Sub CheckNPCTalk()
If Trim(MyText) = "" Then
Call SendData("npctalk" & SEP_CHAR & END_CHAR)
End If
End Sub
Now Find
Code:
If GetKeyState(VK_RETURN) < 0 Then
Call CheckMapGetItem
below that add
Code:
Call CheckNPCTalk
Now Find
Code:
If KeyState = 1 Then
If KeyCode = vbKeyReturn Then
Call CheckMapGetItem
Below Add
Code:
Call CheckNPCTalk
Replace Sub SendSaveNpc with
Code:
Sub SendSaveNpc(ByVal NpcNum As Long)
Dim Packet As String
Packet = "SAVENPC" & SEP_CHAR & NpcNum & SEP_CHAR & Trim(Npc(NpcNum).Name) & SEP_CHAR & Trim(Npc(NpcNum).Say) & SEP_CHAR & Trim(Npc(NpcNum).PlayerResponse) & SEP_CHAR & Trim(Npc(NpcNum).NpcResponse) & 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
Call SendData(Packet)
End Sub
Add this to Sub HandleData
Code:
' ::::::::::::::
' :: NPC TALK ::
' ::::::::::::::
If LCase(Parse(0)) = "npctalk" Then
frmChatNPC.Visible = True
frmChatNPC.txtNPCResponse.Visible = False
frmChatNPC.txtNPCSay.Visible = True
'put all the data into the correct area
frmChatNPC.Caption = "Talking With " & Trim(Parse(2))
frmChatNPC.txtNPCSay.Text = Trim(Parse(3))
frmChatNPC.lblPlayerResponse.Caption = Trim(Parse(4))
frmChatNPC.txtNPCResponse.Text = Trim(Parse(5))
frmChatNPC.txtSprite.Text = Trim(Parse(6))
Exit Sub
End If
Create a new form called frmChatNPC and Setup textboxes. Name a textbox txtNPCSay, one txtNPCResponse, and txtSprite(Visible = false). Make the all visible = false. Now create a label called lblPlayerResponse. Create a picturebox called picSpriteLoader (Set AutoRedraw and AutoSize = true) and picNPC(
DO NOT make AutoReDraw and AutoSize = true). Now add a timer and call it tmrNPC and set the interval to 50 Enabled = true. Double click the form and replace everything with
Code:
Private Sub Form_Load()
picSpriteLoader.Picture = LoadPicture(App.Path & "\sprites.bmp")
End Sub
Private Sub lblPlayerResponse_Click()
If txtNPCResponse.Visible = True Then
frmChatNPC.Visible = False
End If
txtNPCSay.Visible = False
txtNPCResponse.Visible = True
lblPlayerResponse.Caption = "Farewell."
End Sub
Private Sub tmrNPC_Timer()
Dim Cap As Integer
Cap = txtSprite.Text
Call TransparentBlt(picNPC.hdc, 0, 0, 32, 64, picSpriteLoader.hdc, 128, Cap * PIC_Y, 32, 64, RGB(0, 0, 0))
End Sub
CHALLENGE! - Do the saving and Loading on your own :]
Tutorial Complete.
:: Pando