23-06-2009, 12:51 AM
Well, NPC spawning is a bit fucked...NPCs can spawn on other NPCs and even other players. Also if an NPC doesn't spawn, it's still created...and won't spawn until you /respawn it. This fix will only spawn an NPC if it's able to and when an open slot becomes available it will spawn there.
Replace:
With:
Then under that sub add this:
And that should be it.
Replace:
Code:
Public Sub SpawnNpc(ByVal MapNpcNum As Long, ByVal MapNum As Long)
With:
Code:
Public Sub SpawnNpc(ByVal MapNpcNum As Long, ByVal MapNum As Long)
Dim Packet As String
Dim NpcNum As Long
Dim i As Long
Dim X As Long
Dim Y As Long
Dim Spawned As Boolean
' Check for subscript out of range
If MapNpcNum MAX_MAP_NPCS Or MapNum MAX_MAPS Then Exit Sub
NpcNum = Map(MapNum).Npc(MapNpcNum)
If NpcNum > 0 Then
' Well try 100 times to randomly place the sprite
For i = 1 To 100
X = Random(0, MAX_MAPX)
Y = Random(0, MAX_MAPY)
' Check if the tile is walkable
If NpcTileIsOpen(MapNum, X, Y) Then
MapNpc(MapNum, MapNpcNum).X = X
MapNpc(MapNum, MapNpcNum).Y = Y
Spawned = True
Exit For
End If
Next
' Didn't spawn, so now we'll just try to find a free tile
If Not Spawned Then
For X = 0 To MAX_MAPX
For Y = 0 To MAX_MAPY
If NpcTileIsOpen(MapNum, X, Y) Then
MapNpc(MapNum, MapNpcNum).X = X
MapNpc(MapNum, MapNpcNum).Y = Y
Spawned = True
End If
Next
Next
End If
' If we suceeded in spawning then send it to everyone
If Spawned Then
MapNpc(MapNum, MapNpcNum).Num = NpcNum
MapNpc(MapNum, MapNpcNum).Target = 0
MapNpc(MapNum, MapNpcNum).Vital(Vitals.HP) = GetNpcMaxVital(NpcNum, Vitals.HP)
MapNpc(MapNum, MapNpcNum).Vital(Vitals.MP) = GetNpcMaxVital(NpcNum, Vitals.MP)
MapNpc(MapNum, MapNpcNum).Vital(Vitals.SP) = GetNpcMaxVital(NpcNum, Vitals.SP)
MapNpc(MapNum, MapNpcNum).Dir = DIR_DOWN
Packet = SSpawnNpc & SEP_CHAR & MapNpcNum & SEP_CHAR & MapNpc(MapNum, MapNpcNum).Num & SEP_CHAR & MapNpc(MapNum, MapNpcNum).X & SEP_CHAR & MapNpc(MapNum, MapNpcNum).Y & SEP_CHAR & MapNpc(MapNum, MapNpcNum).Dir & END_CHAR
Call SendDataToMap(MapNum, Packet)
End If
End If
End Sub
Then under that sub add this:
Code:
Public Function NpcTileIsOpen(ByVal MapNum As Long, ByVal X As Long, ByVal Y As Long) As Boolean
Dim LoopI As Long
NpcTileIsOpen = True
If PlayersOnMap(MapNum) Then
For LoopI = 1 To MAX_PLAYERS
If GetPlayerMap(LoopI) = MapNum Then
If GetPlayerX(LoopI) = X Then
If GetPlayerY(LoopI) = Y Then
NpcTileIsOpen = False
Exit Function
End If
End If
End If
Next
End If
For LoopI = 1 To MAX_MAP_NPCS
If MapNpc(MapNum, LoopI).Num > 0 Then
If MapNpc(MapNum, LoopI).X = X Then
If MapNpc(MapNum, LoopI).Y = Y Then
NpcTileIsOpen = False
Exit Function
End If
End If
End If
Next
If Map(MapNum).Tile(X, Y).Type TILE_TYPE_NONE Then NpcTileIsOpen = False
End Function
And that should be it.