O Slide da engine quase que teleporta o jogador, sem contar que não tem senso de colisão nem imperatividade.
Vamos colocar isso!
Efeitos:
- Um slide mais demorado e melhor visualmente;
- Opção de deixar o jogador se mover enquanto escorrega ou não;
- Slide PARA, quando tem a frente: TileBlock, TileResource, Limites de X e Y do mapa, quando não há mais TileSlide, em Warp do jogador;
- Slide continua: se houver mais slides a frente, logar/deslogar caso esteja em cima do TileSlide continuará o slide.
Vamos lá então, abra seu 'client.vbp', e na parte física da "frmEditor_Map" , dentro do "FraSlide" crie:
1x CheckBox, Nome: chkSlide / Caption: Can Walk while Sliding
Agora, vamos à parte lógica, procure por:
E abaixo disto, adicione isso:
Agora, em "ModGlobals" , procure por:
E abaixo disto, adicione isso:
Agora, em "ModGameEditors", na "Public Sub MapEditorMouseDown" procure por :
E substitua isto por isso:
Agora, em "ModTypes" , na "Private Type PlayerRec" , declare um TIPO: descendo, antes do primeiro "End Type" , declare isso:
Agora, em "ModEnumerations", procure por:
E acima disto, adicione isso:
Agora, em "ModHandleData" , em "Public Sub InitMessages()" , procure por:
E acima disto, adicione isso:
Agora, no final de "ModHandlePlayerData" , adicione isso:
Agora, em "ModGameLogic", na "Function CanMove" , procure por:
E abaixo disto, adicione isso:
E a parte do Cliente finalizou. Vamos ao server agora.
Primeiramente, abra seu 'server.vbp'.
Agora, em "ModTypes" , na "Private Type TempPlayerRec" , declare um TIPO: descendo, antes do primeiro "End Type" , declare isso:
Agora, em "ModEnumerations", procure por:
E acima disto, adicione isso:
Agora, no final de "ModServerTCP" , adicione isso:
Agora, em "Sub ServerLoop()" , bem no início, procure por:
E abaixo disto, adicione isso:
Ainda em "Sub ServerLoop()", procure por:
E abaixo disto, adicione isso:
Agora, em "ModPlayer", na "Sub JoinGame" , procure por:
E abaixo disto, adicione isso:
Ainda em "ModPlayer" na "Sub PlayerWarp", procure por:
E abaixo disto, adicione isso:
Ainda em "ModPlayer" , na "Sub PlayerMove", procure por:
E abaixo disto, adicione isso:
Ainda em "Sub PlayerMove" , quase no fim procure por isso:
E substitua por isso:
Agora, em "ModPlayer" , procure pela sua "Sub ForcePlayerMove" , e substitua ela por essa:
Agora, abaixo desta Sub ou no final de "ModPlayer" , adicione isso:
E pronto!
ATENÇÃO: para as pessoas que utilizam "Magia Expelir/Puxar" , "Npc Puxando por script" , ou quaisquer scripts que não passem pelo "PlayerWarp" ou "PlayerMove" , lembrem de colocar um "ClearSliding Index" , caso os scripts de posição peguem o jogador durante um slide.
Vamos colocar isso!
Efeitos:
- Um slide mais demorado e melhor visualmente;
- Opção de deixar o jogador se mover enquanto escorrega ou não;
- Slide PARA, quando tem a frente: TileBlock, TileResource, Limites de X e Y do mapa, quando não há mais TileSlide, em Warp do jogador;
- Slide continua: se houver mais slides a frente, logar/deslogar caso esteja em cima do TileSlide continuará o slide.
Vamos lá então, abra seu 'client.vbp', e na parte física da "frmEditor_Map" , dentro do "FraSlide" crie:
1x CheckBox, Nome: chkSlide / Caption: Can Walk while Sliding
Agora, vamos à parte lógica, procure por:
- Spoiler:
MapEditorSlideDir = cmbSlide.ListIndex
E abaixo disto, adicione isso:
- Spoiler:
MapEditorSlideCanMove = chkSlide.Value
Agora, em "ModGlobals" , procure por:
- Spoiler:
Public MapEditorSlideDir As Long
E abaixo disto, adicione isso:
- Spoiler:
Public MapEditorSlideCanMove As Long
Agora, em "ModGameEditors", na "Public Sub MapEditorMouseDown" procure por :
- Spoiler:
' slide
If frmEditor_Map.optSlide.Value Then
.Type = TILE_TYPE_SLIDE
.Data1 = MapEditorSlideDir
.Data2 = 0
.Data3 = 0
End If
E substitua isto por isso:
- Spoiler:
' slide
If frmEditor_Map.optSlide.Value Then
.Type = TILE_TYPE_SLIDE
.Data1 = MapEditorSlideDir
.Data2 = MapEditorSlideCanMove
.Data3 = 0
End If
Agora, em "ModTypes" , na "Private Type PlayerRec" , declare um TIPO: descendo, antes do primeiro "End Type" , declare isso:
- Spoiler:
IsSliding As Boolean
Agora, em "ModEnumerations", procure por:
- Spoiler:
' Make sure SMSG_COUNT is below everything else
SMSG_COUNT
End Enum
E acima disto, adicione isso:
- Spoiler:
SPlayerSlide
Agora, em "ModHandleData" , em "Public Sub InitMessages()" , procure por:
- Spoiler:
' Error handler
E acima disto, adicione isso:
- Spoiler:
HandleDataSub(SPlayerSlide) = GetAddress(AddressOf HandlePlayerSlide)
Agora, no final de "ModHandlePlayerData" , adicione isso:
- Spoiler:
Private Sub HandlePlayerSlide(ByVal Index As Long, ByRef data() As Byte, ByVal StartAddr As Long, ByVal ExtraVar As Long)
Dim buffer As clsBuffer
' If debug mode, handle error then exit out
If Options.Debug = 1 Then On Error GoTo errorhandler
Set buffer = New clsBuffer
buffer.WriteBytes data()
Player(MyIndex).IsSliding = buffer.ReadLong
Set buffer = Nothing
' Error handler
Exit Sub
errorhandler:
HandleError "HandlePlayerSlide", "modHandleData", Err.Number, Err.Description, Err.Source, Err.HelpContext
Err.Clear
Exit Sub
End Sub
Agora, em "ModGameLogic", na "Function CanMove" , procure por:
- Spoiler:
' Make sure they aren't trying to move when they are already moving
If Player(MyIndex).Moving <> 0 Then
CanMove = False
Exit Function
End If
E abaixo disto, adicione isso:
- Spoiler:
'Check for slide
If Player(MyIndex).IsSliding = True Then
CanMove = False
Exit Function
End If
E a parte do Cliente finalizou. Vamos ao server agora.
Primeiramente, abra seu 'server.vbp'.
Agora, em "ModTypes" , na "Private Type TempPlayerRec" , declare um TIPO: descendo, antes do primeiro "End Type" , declare isso:
- Spoiler:
IsSliding As Boolean
SlidingDir As Long
SlidingCanMove As Boolean
Agora, em "ModEnumerations", procure por:
- Spoiler:
' Make sure SMSG_COUNT is below everything else
SMSG_COUNT
End Enum
E acima disto, adicione isso:
- Spoiler:
SPlayerSlide
Agora, no final de "ModServerTCP" , adicione isso:
- Spoiler:
Sub SendPlayerSlide(ByVal Index As Long)
Dim Buffer As clsBuffer
Dim i As Long
If Index <= 0 Or Index > MAX_PLAYERS Then Exit Sub
Set Buffer = New clsBuffer
Buffer.WriteLong SPlayerSlide
Buffer.WriteLong TempPlayer(Index).IsSliding
SendDataTo Index, Buffer.ToArray()
Set Buffer = Nothing
End Sub
Agora, em "Sub ServerLoop()" , bem no início, procure por:
- Spoiler:
Dim LastUpdateSavePlayers, LastUpdateMapSpawnItems As Long, LastUpdatePlayerVitals As Long
E abaixo disto, adicione isso:
- Spoiler:
- Dim tmrSlide As Long
Ainda em "Sub ServerLoop()", procure por:
- Spoiler:
' HoT and DoT logic
For X = 1 To MAX_DOTS
HandleDoT_Player i, X
HandleHoT_Player i, X
Next
E abaixo disto, adicione isso:
- Spoiler:
If Tick > tmrSlide Then
If TempPlayer(i).IsSliding = True Then
ForcePlayerMove i, MOVING_WALKING, TempPlayer(i).SlidingDir
End If
tmrSlide = GetTickCount + 150
End If
Agora, em "ModPlayer", na "Sub JoinGame" , procure por:
- Spoiler:
' Send Resource cache
For i = 0 To ResourceCache(GetPlayerMap(Index)).Resource_Count
SendResourceCacheTo Index, i
Next
E abaixo disto, adicione isso:
- Spoiler:
'Check for floor
With Map(GetPlayerMap(Index)).Tile(GetPlayerX(Index), GetPlayerY(Index))
' Slide
If .Type = TILE_TYPE_SLIDE Then
TempPlayer(Index).IsSliding = True
TempPlayer(Index).SlidingDir = .Data1
TempPlayer(Index).SlidingCanMove = .Data2
SendPlayerSlide Index
End If
'Quit them from sliding
If .Type <> TILE_TYPE_SLIDE Then
ClearSliding Index
End If
End With
Ainda em "ModPlayer" na "Sub PlayerWarp", procure por:
- Spoiler:
' send player's equipment to new map
SendMapEquipment Index
E abaixo disto, adicione isso:
- Spoiler:
'Warped then clear slide action
If TempPlayer(Index).IsSliding = True Then
ClearSliding Index
End If
Ainda em "ModPlayer" , na "Sub PlayerMove", procure por:
- Spoiler:
' Check for subscript out of range
If IsPlaying(Index) = False Or Dir < DIR_UP Or Dir > DIR_RIGHT Or Movement < 1 Or Movement > 2 Then
Exit Sub
End If
E abaixo disto, adicione isso:
- Spoiler:
If TempPlayer(Index).IsSliding = True And TempPlayer(Index).SlidingCanMove = False Then Exit Sub
Ainda em "Sub PlayerMove" , quase no fim procure por isso:
- Spoiler:
' Slide
If .Type = TILE_TYPE_SLIDE Then
ForcePlayerMove index, MOVING_WALKING, GetPlayerDir(index)
Moved = YES
End If
E substitua por isso:
- Spoiler:
' Slide
If .Type = TILE_TYPE_SLIDE Then
TempPlayer(Index).IsSliding = True
TempPlayer(Index).SlidingDir = .Data1
TempPlayer(Index).SlidingCanMove = .Data2
Moved = YES
SendPlayerSlide Index
End If
'Quit them from sliding
If .Type <> TILE_TYPE_SLIDE Then
ClearSliding Index
Moved = YES
End If
Agora, em "ModPlayer" , procure pela sua "Sub ForcePlayerMove" , e substitua ela por essa:
- Spoiler:
Sub ForcePlayerMove(ByVal Index As Long, ByVal Movement As Long, ByVal Direction As Long)
Dim MapNum As Long, NpcNum as Long
Dim i As Long, npcX As Long, npcY As Long
'Check for errors
If Index <= 0 Or Index > MAX_PLAYERS Then Exit Sub
If TempPlayer(Index).InGame = False Then Exit Sub
If Direction < DIR_UP Or Direction > DIR_RIGHT Then Exit Sub
If Movement < 1 Or Movement > 2 Then Exit Sub
If TempPlayer(Index).IsSliding = False Then Exit Sub
If TempPlayer(Index).SlidingDir < DIR_UP Or TempPlayer(Index).SlidingDir > DIR_RIGHT Then Exit Sub
MapNum = GetPlayerMap(Index)
Call SetPlayerDir(Index, Direction)
' Check to see if a npc is already on that tile
For i = 1 To MAX_MAP_NPCS
If MapNpc(MapNum).Npc(i).Num > 0 Then
NpcNum = MapNpc(MapNum).Npc(i).Num
With MapNpc(MapNum).Npc(i)
' Check if at same coordinates
Select Case GetPlayerDir(Index)
Case DIR_UP
npcX = .X
npcY = .Y + 1
Case DIR_DOWN
npcX = .X
npcY = .Y - 1
Case DIR_LEFT
npcX = .X + 1
npcY = .Y
Case DIR_RIGHT
npcX = .X - 1
npcY = .Y
End Select
End With
If npcX = GetPlayerX(Index) Then
If npcY = GetPlayerY(Index) Then
ClearSliding Index
Exit Sub
End If
End If
End If
Next
Select Case Direction
Case DIR_UP
' Check to make sure not outside of boundries
If GetPlayerY(Index) > 0 Then
'Dir Block
If isDirBlocked(Map(GetPlayerMap(Index)).Tile(GetPlayerX(Index), GetPlayerY(Index)).DirBlock, DIR_UP + 1) Then
ClearSliding Index
Exit Sub
End If
'Tile Blocked
If Map(GetPlayerMap(Index)).Tile(GetPlayerX(Index), GetPlayerY(Index) - 1).Type = TILE_TYPE_BLOCKED Then
ClearSliding Index
Exit Sub
End If
If Map(GetPlayerMap(Index)).Tile(GetPlayerX(Index), GetPlayerY(Index) - 1).Type = TILE_TYPE_RESOURCE Then
ClearSliding Index
Exit Sub
End If
' Check to see if the tile is a key and if it is check if its opened
If Map(GetPlayerMap(Index)).Tile(GetPlayerX(Index), GetPlayerY(Index) - 1).Type = TILE_TYPE_KEY Or (Map(GetPlayerMap(Index)).Tile(GetPlayerX(Index), GetPlayerY(Index) - 1).Type = TILE_TYPE_KEY And TempTile(GetPlayerMap(Index)).DoorOpen(GetPlayerX(Index), GetPlayerY(Index) - 1) = NO) Then
ClearSliding Index
Exit Sub
End If
'Ok, we can keep sliding
Call SetPlayerY(Index, GetPlayerY(Index) - 1)
SendPlayerMove Index, Movement, True
Else
'make them change map? nah maybe later
ClearSliding Index
Exit Sub
End If
Case DIR_DOWN
' Check to make sure not outside of boundries
If GetPlayerY(Index) < Map(MapNum).MaxY Then
' Check to make sure that the tile is walkable
If isDirBlocked(Map(GetPlayerMap(Index)).Tile(GetPlayerX(Index), GetPlayerY(Index)).DirBlock, DIR_DOWN + 1) Then
ClearSliding Index
Exit Sub
End If
If Map(GetPlayerMap(Index)).Tile(GetPlayerX(Index), GetPlayerY(Index) + 1).Type = TILE_TYPE_BLOCKED Then
ClearSliding Index
Exit Sub
End If
If Map(GetPlayerMap(Index)).Tile(GetPlayerX(Index), GetPlayerY(Index) + 1).Type = TILE_TYPE_RESOURCE Then
ClearSliding Index
Exit Sub
End If
' Check to see if the tile is a key and if it is check if its opened
If Map(GetPlayerMap(Index)).Tile(GetPlayerX(Index), GetPlayerY(Index) + 1).Type = TILE_TYPE_KEY Or (Map(GetPlayerMap(Index)).Tile(GetPlayerX(Index), GetPlayerY(Index) + 1).Type = TILE_TYPE_KEY And TempTile(GetPlayerMap(Index)).DoorOpen(GetPlayerX(Index), GetPlayerY(Index) + 1) = NO) Then
ClearSliding Index
Exit Sub
End If
Call SetPlayerY(Index, GetPlayerY(Index) + 1)
SendPlayerMove Index, Movement, True
'Moved = YES
Else
ClearSliding Index
Exit Sub
End If
Case DIR_LEFT
' Check to make sure not outside of boundries
If GetPlayerX(Index) > 0 Then
' Check to make sure that the tile is walkable
If isDirBlocked(Map(GetPlayerMap(Index)).Tile(GetPlayerX(Index), GetPlayerY(Index)).DirBlock, DIR_LEFT + 1) Then
ClearSliding Index
Exit Sub
End If
If Map(GetPlayerMap(Index)).Tile(GetPlayerX(Index) - 1, GetPlayerY(Index)).Type = TILE_TYPE_BLOCKED Then
ClearSliding Index
Exit Sub
End If
If Map(GetPlayerMap(Index)).Tile(GetPlayerX(Index) - 1, GetPlayerY(Index)).Type = TILE_TYPE_RESOURCE Then
ClearSliding Index
Exit Sub
End If
' Check to see if the tile is a key and if it is check if its opened
If Map(GetPlayerMap(Index)).Tile(GetPlayerX(Index) - 1, GetPlayerY(Index)).Type = TILE_TYPE_KEY Or (Map(GetPlayerMap(Index)).Tile(GetPlayerX(Index) - 1, GetPlayerY(Index)).Type = TILE_TYPE_KEY And TempTile(GetPlayerMap(Index)).DoorOpen(GetPlayerX(Index) - 1, GetPlayerY(Index)) = NO) Then
ClearSliding Index
Exit Sub
End If
Call SetPlayerX(Index, GetPlayerX(Index) - 1)
SendPlayerMove Index, Movement, True
Else
ClearSliding Index
Exit Sub
End If
Case DIR_RIGHT
' Check to make sure not outside of boundries
If GetPlayerX(Index) < Map(MapNum).MaxX Then
' Check to make sure that the tile is walkable
If isDirBlocked(Map(GetPlayerMap(Index)).Tile(GetPlayerX(Index), GetPlayerY(Index)).DirBlock, DIR_RIGHT + 1) Then
ClearSliding Index
Exit Sub
End If
If Map(GetPlayerMap(Index)).Tile(GetPlayerX(Index) + 1, GetPlayerY(Index)).Type = TILE_TYPE_BLOCKED Then
ClearSliding Index
Exit Sub
End If
If Map(GetPlayerMap(Index)).Tile(GetPlayerX(Index) + 1, GetPlayerY(Index)).Type = TILE_TYPE_RESOURCE Then
ClearSliding Index
Exit Sub
End If
' Check to see if the tile is a key and if it is check if its opened
If Map(GetPlayerMap(Index)).Tile(GetPlayerX(Index) + 1, GetPlayerY(Index)).Type = TILE_TYPE_KEY Or (Map(GetPlayerMap(Index)).Tile(GetPlayerX(Index) + 1, GetPlayerY(Index)).Type = TILE_TYPE_KEY And TempTile(GetPlayerMap(Index)).DoorOpen(GetPlayerX(Index) + 1, GetPlayerY(Index)) = NO) Then
ClearSliding Index
Exit Sub
End If
Call SetPlayerX(Index, GetPlayerX(Index) + 1)
SendPlayerMove Index, Movement, True
Else
ClearSliding Index
Exit Sub
End If
End Select
'Check for floor
With Map(GetPlayerMap(Index)).Tile(GetPlayerX(Index), GetPlayerY(Index))
' Slide
If .Type = TILE_TYPE_SLIDE Then
TempPlayer(Index).IsSliding = True
TempPlayer(Index).SlidingDir = .Data1
TempPlayer(Index).SlidingCanMove = .Data2
SendPlayerSlide Index
End If
'Quit them from sliding
If .Type <> TILE_TYPE_SLIDE Then
ClearSliding Index
End If
End With
End Sub
Agora, abaixo desta Sub ou no final de "ModPlayer" , adicione isso:
- Spoiler:
Sub ClearSliding(ByVal Index As Long)
'Check for errors
If Index <= 0 Or Index > MAX_PLAYERS Then Exit Sub
If TempPlayer(Index).InGame = False Then Exit Sub
TempPlayer(Index).IsSliding = False
TempPlayer(Index).SlidingDir = 0
TempPlayer(Index).SlidingCanMove = False
SendPlayerSlide Index
End Sub
E pronto!
ATENÇÃO: para as pessoas que utilizam "Magia Expelir/Puxar" , "Npc Puxando por script" , ou quaisquer scripts que não passem pelo "PlayerWarp" ou "PlayerMove" , lembrem de colocar um "ClearSliding Index" , caso os scripts de posição peguem o jogador durante um slide.
~Créditos~
Kotol