Move git root from Client/ to src/ to track all source code: - Client: Game client source (moved to Client/Client/) - Server: Game server source - GameTools: Development tools - CryptoSource: Encryption utilities - database: Database scripts - Script: Game scripts - rylCoder_16.02.2008_src: Legacy coder tools - GMFont, Game: Additional resources 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude <noreply@anthropic.com>
344 lines
12 KiB
VB.net
344 lines
12 KiB
VB.net
'################################################
|
|
'## ##
|
|
'## RYL mcf & gsf file editor ##
|
|
'## ##
|
|
'## (C) 2006 & 2007 AlphA ##
|
|
'## ##
|
|
'## This source is for private development. ##
|
|
'## You can have this source only with the ##
|
|
'## owners permission. ##
|
|
'## ##
|
|
'################################################
|
|
|
|
Public Class CNpcParser
|
|
Public NPCs As npcStruct() = {}
|
|
Private notFoundNPCLines As New ArrayList 'LineWithPos() = {}
|
|
Private Functions As CMcfBase.SFunction() = {}
|
|
Public loadedNPC As npcStruct = Nothing
|
|
Public RYLVersion As Integer = 0
|
|
Public Structure NPCline
|
|
Dim NPCID As Long
|
|
Dim Params As CMcfBase.SParamElem()
|
|
Dim Type As knownType
|
|
Dim pos As Long
|
|
Dim ownerFunc As Integer
|
|
Public Enum knownType
|
|
EAddItem = 1
|
|
ESetPosition = 2
|
|
EAddPopup = 3
|
|
EAddWords = 4
|
|
EAddDialog = 5
|
|
ESetNPC = 6
|
|
EAddQuestWords = 7
|
|
EAddZoneMove = 8
|
|
EAddQuest = 9
|
|
ESetDropBase = 10
|
|
ESetDropGrade = 11
|
|
ESetNPCAttribute = 12
|
|
End Enum
|
|
Public Shared TypesStrings As String() = { _
|
|
"", _
|
|
"AddItem", _
|
|
"SetPosition", _
|
|
"AddPopup", _
|
|
"AddWords", _
|
|
"AddDialog", _
|
|
"SetNPC", _
|
|
"AddQuestWords", _
|
|
"AddZoneMove", _
|
|
"AddQuest", _
|
|
"SetDropBase", _
|
|
"SetDropGrade", _
|
|
"SetNPCAttribute" _
|
|
}
|
|
End Structure
|
|
Public Class npcStruct
|
|
Public id As Long
|
|
Public iLines As New ArrayList 'NPCLine
|
|
Public RYLversion As Integer = 0
|
|
Public Sub New()
|
|
End Sub
|
|
Public Sub New(ByVal aId As Long, ByVal version As Integer)
|
|
id = aId
|
|
RYLversion = version
|
|
End Sub
|
|
Public Sub AddLine(ByVal com As NPCline)
|
|
If iLines.Count > 0 Then com.ownerFunc = CType(iLines(0), NPCline).ownerFunc
|
|
iLines.Add(com)
|
|
End Sub
|
|
Public Sub DeleteLine(ByVal line As NPCline)
|
|
iLines.Remove(line)
|
|
End Sub
|
|
Public ReadOnly Property Name() As String
|
|
Get
|
|
For Each l As NPCline In iLines
|
|
If l.Type = NPCline.knownType.ESetNPC Then
|
|
If RYLversion = 1 Then
|
|
Return l.Params(4).value
|
|
Else
|
|
Return l.Params(5).value
|
|
End If
|
|
|
|
End If
|
|
Next
|
|
Return ""
|
|
End Get
|
|
End Property
|
|
Public ReadOnly Property Map() As Long
|
|
Get
|
|
For Each l As NPCline In iLines
|
|
If l.Type = NPCline.knownType.ESetNPC Then
|
|
Return l.Params(0).value
|
|
End If
|
|
Next
|
|
Return "??"
|
|
End Get
|
|
End Property
|
|
Public Property Lines(Optional ByVal type As NPCline.knownType = Nothing) As NPCline()
|
|
Get
|
|
Dim tLines As New ArrayList
|
|
For Each l As NPCline In iLines
|
|
If type = Nothing OrElse l.Type = type Then
|
|
tLines.Add(l)
|
|
End If
|
|
Next
|
|
Return tLines.ToArray(GetType(NPCline))
|
|
End Get
|
|
Set(ByVal value As NPCline())
|
|
Dim tLines As New ArrayList
|
|
For Each l As NPCline In iLines
|
|
If Not type = Nothing AndAlso l.Type <> type Then
|
|
tLines.Add(l)
|
|
End If
|
|
Next
|
|
For Each v As NPCline In value
|
|
tLines.Add(v)
|
|
Next
|
|
iLines = tLines
|
|
End Set
|
|
End Property
|
|
Default Public Property Item(ByVal index As Integer) As NPCline
|
|
Get
|
|
Return iLines(index)
|
|
End Get
|
|
Set(ByVal value As NPCline)
|
|
iLines(index) = value
|
|
End Set
|
|
End Property
|
|
Public Function indexOfPos(ByVal pos As Long)
|
|
Dim i As Long = 0
|
|
For Each l As NPCline In iLines
|
|
If l.pos = pos Then
|
|
Return i
|
|
End If
|
|
i += 1
|
|
Next
|
|
Return -1
|
|
End Function
|
|
Public Sub SwitchPositions(ByVal pos1 As Long, ByVal pos2 As Long)
|
|
Dim index1 As Long = indexOfPos(pos1)
|
|
Dim index2 As Long = indexOfPos(pos2)
|
|
If index1 >= 0 AndAlso index2 >= 0 AndAlso index1 <> index2 Then
|
|
Dim item1 As NPCline = iLines(index1)
|
|
Dim item2 As NPCline = iLines(index2)
|
|
item1.pos = pos2
|
|
item2.pos = pos1
|
|
iLines(index1) = item2
|
|
iLines(index2) = item1
|
|
End If
|
|
End Sub
|
|
Public Sub setParameter(ByVal pos As Long, ByVal paramIndex As Integer, ByVal value As Object)
|
|
Dim index As Long = indexOfPos(pos)
|
|
If index >= 0 Then
|
|
Dim item As NPCline = iLines(index)
|
|
item.Params(paramIndex).value = value
|
|
iLines(index) = item
|
|
End If
|
|
End Sub
|
|
Public Sub setPos(ByVal pos As Long, ByVal newPos As Long)
|
|
Dim index As Long = indexOfPos(pos)
|
|
If index >= 0 Then
|
|
Dim item As NPCline = iLines(index)
|
|
item.pos = newPos
|
|
iLines(index) = item
|
|
End If
|
|
End Sub
|
|
End Class
|
|
Private Structure LineWithPos
|
|
Dim line As CMcfBase.SScriptLine
|
|
Dim pos As Long
|
|
Dim ownerFunction As Integer
|
|
End Structure
|
|
Private Function indexOfNPCinLines(ByVal NPCid As Long) As Long
|
|
Dim i As Long = 0
|
|
For Each npc As npcStruct In NPCs
|
|
If npc.id = NPCid Then Return i
|
|
i += 1
|
|
Next
|
|
Return -1
|
|
End Function
|
|
Public Sub Parse(ByVal funcs As CMcfBase.SFunction())
|
|
Array.Resize(NPCs, 0)
|
|
Functions = funcs
|
|
Dim npclines As New ArrayList
|
|
Dim i As Long = 0
|
|
For Each f As CMcfBase.SFunction In funcs
|
|
For Each v As CMcfBase.SScriptLine In f.data
|
|
Dim l As Integer = Array.IndexOf(NPCline.TypesStrings, funcs(v.callTo).name)
|
|
If l >= 0 Then
|
|
Dim nLine As New NPCline
|
|
nLine.Type = l
|
|
nLine.Params = v.parameters
|
|
nLine.pos = i
|
|
nLine.ownerFunc = f.id
|
|
npclines.Add(nLine)
|
|
|
|
If nLine.Type = NPCline.knownType.ESetNPC Then
|
|
If RYLVersion < 1 Then RYLVersion = IIf(nLine.Params.Length > 5, 2, 1)
|
|
ReDim Preserve NPCs(UBound(NPCs) + 1)
|
|
NPCs(UBound(NPCs)) = New npcStruct(nLine.Params(1).value, RYLVersion)
|
|
nLine.NPCID = nLine.Params(1).value
|
|
NPCs(UBound(NPCs)).AddLine(nLine)
|
|
Else
|
|
Dim npcI As Long = indexOfNPCinLines(nLine.Params(0).value)
|
|
If npcI >= 0 Then
|
|
nLine.NPCID = nLine.Params(0).value
|
|
NPCs(npcI).AddLine(nLine)
|
|
Else
|
|
Dim vv As New LineWithPos
|
|
vv.line = v
|
|
vv.pos = i
|
|
vv.ownerFunction = f.id
|
|
notFoundNPCLines.Add(vv)
|
|
End If
|
|
End If
|
|
Else
|
|
Dim vv As New LineWithPos
|
|
vv.line = v
|
|
vv.pos = i
|
|
vv.ownerFunction = f.id
|
|
notFoundNPCLines.Add(vv)
|
|
End If
|
|
i += 1
|
|
Next
|
|
Next
|
|
End Sub
|
|
Public Function GetFunctions() As CMcfBase.SFunction()
|
|
Dim lines As New ArrayList 'linewith pos
|
|
Dim ucnt As Long = 0
|
|
For i As Long = 0 To NPCs.Length - 1
|
|
Dim ls As NPCline() = NPCs(i).Lines()
|
|
For Each l As NPCline In ls
|
|
Dim ln As New CMcfBase.SScriptLine
|
|
Dim lp As New LineWithPos
|
|
ln.parameters = l.Params
|
|
For Each f As CMcfBase.SFunction In Functions
|
|
If f.name = NPCline.TypesStrings(l.Type) Then
|
|
ln.callTo = f.id
|
|
Exit For
|
|
End If
|
|
Next
|
|
lp.ownerFunction = l.ownerFunc
|
|
lp.line = ln
|
|
lp.pos = l.pos
|
|
lines.Add(lp)
|
|
ucnt += 1
|
|
Next
|
|
Next
|
|
For Each l As LineWithPos In notFoundNPCLines
|
|
lines.Add(l)
|
|
ucnt += 1
|
|
Next
|
|
lines.Sort(New linePosComparer)
|
|
Dim ki As Long = 0
|
|
For i As Integer = 0 To Functions.Length - 1
|
|
Functions(i).data = New CMcfBase.SScriptLine() {}
|
|
Next
|
|
For Each l As LineWithPos In lines
|
|
Dim f As CMcfBase.SFunction = Functions(l.ownerFunction)
|
|
ReDim Preserve f.data(UBound(f.data) + 1)
|
|
f.data(UBound(f.data)) = l.line
|
|
Functions(l.ownerFunction) = f
|
|
Next
|
|
Return Functions
|
|
End Function
|
|
Public Class linePosComparer
|
|
Implements IComparer
|
|
Function Compare(ByVal x As Object, ByVal y As Object) As Integer _
|
|
Implements IComparer.Compare
|
|
Dim lX As LineWithPos = CType(x, LineWithPos)
|
|
Dim lY As LineWithPos = CType(y, LineWithPos)
|
|
Return New CaseInsensitiveComparer().Compare(lX.pos, lY.pos)
|
|
End Function
|
|
End Class
|
|
Public Class NPClinePosComparer
|
|
Implements IComparer
|
|
Function Compare(ByVal x As Object, ByVal y As Object) As Integer _
|
|
Implements IComparer.Compare
|
|
Dim lX As NPCline = CType(x, NPCline)
|
|
Dim lY As NPCline = CType(y, NPCline)
|
|
Return New CaseInsensitiveComparer().Compare(lX.pos, lY.pos)
|
|
End Function
|
|
End Class
|
|
Public Class FreePoslinePosComparer
|
|
Implements IComparer
|
|
Function Compare(ByVal x As Object, ByVal y As Object) As Integer _
|
|
Implements IComparer.Compare
|
|
Dim lX As freePosItem = CType(x, freePosItem)
|
|
Dim lY As freePosItem = CType(y, freePosItem)
|
|
Return New CaseInsensitiveComparer().Compare(lX.pos, lY.pos)
|
|
End Function
|
|
End Class
|
|
Public Structure NPCTextItem
|
|
Dim line As NPCline
|
|
Dim text As String
|
|
Dim paraIndex As Integer
|
|
Dim Tag As Object
|
|
End Structure
|
|
Private Structure freePosItem
|
|
Dim npcL As NPCline
|
|
Dim sLine As CMcfBase.SScriptLine
|
|
Dim pos As Long
|
|
Dim isNPCLine As Boolean
|
|
End Structure
|
|
Public Sub FreePosition(ByVal pos As Long, Optional ByVal length As Integer = 1)
|
|
Dim lines As New ArrayList
|
|
For Each npc As npcStruct In NPCs
|
|
For Each l As NPCline In npc.iLines
|
|
Dim nFPitem As New freePosItem
|
|
nFPitem.pos = l.pos
|
|
nFPitem.isNPCLine = True
|
|
nFPitem.npcL = l
|
|
lines.Add(nFPitem)
|
|
Next
|
|
npc.iLines.Clear()
|
|
Next
|
|
If notFoundNPCLines.Count > 0 Then
|
|
For Each l As LineWithPos In notFoundNPCLines
|
|
Dim nFPitem As New freePosItem
|
|
nFPitem.pos = l.pos
|
|
nFPitem.isNPCLine = False
|
|
nFPitem.sLine = l.line
|
|
lines.Add(nFPitem)
|
|
Next
|
|
notFoundNPCLines.Clear()
|
|
End If
|
|
lines.Sort(New FreePoslinePosComparer)
|
|
Dim nPos As Long = 0
|
|
For Each l As freePosItem In lines
|
|
If nPos = pos Then nPos += length
|
|
If l.isNPCLine Then
|
|
Dim nL As NPCline = l.npcL
|
|
nL.pos = nPos
|
|
NPCs(indexOfNPCinLines(nL.NPCID)).AddLine(nL)
|
|
Else
|
|
Dim nL As New LineWithPos
|
|
nL.line = l.sLine
|
|
nL.pos = nPos
|
|
notFoundNPCLines.Add(nL)
|
|
End If
|
|
nPos += 1
|
|
Next
|
|
End Sub
|
|
End Class
|