Skip to content

Commit

Permalink
Fix seguro NPC
Browse files Browse the repository at this point in the history
Fixes #514

Se elimina el chequeo de distancia para ser "dueño" de un NPC. Tenía un bug fácil de arreglar pero charlando con los game master pensamos que sería mejor otra estrategia.
Ahora es por tiempo: 10 segundos (por defecto) desde el último ataque. Esto es configurable desde intervalos.ini
Igualmente al irte del rango de visión del NPC dejás de ser el dueño.
Arreglé otro errorcito que si pasabas por al lado de un NPC que tenía dueño, ignoraba todas las validaciones y te golpeaba igual.
  • Loading branch information
Alexis Caraballo committed Mar 3, 2024
1 parent 0e84b46 commit ace1a82
Show file tree
Hide file tree
Showing 13 changed files with 84 additions and 46 deletions.
16 changes: 9 additions & 7 deletions Codigo/AI_NPC.bas
Original file line number Diff line number Diff line change
Expand Up @@ -600,9 +600,7 @@ Private Sub AI_AtacarUsuarioObjetivo(ByVal AtackerNpcIndex As Integer)
Call AnimacionIdle(AtackerNpcIndex, True)
If UserIndexFront > 0 Then
If UserList(UserIndexFront).flags.Muerto = 0 Then
If UserList(UserIndexFront).Faccion.Status = 1 And (.NPCtype = e_NPCType.GuardiaReal) Then

Else
If EsEnemigo(AtackerNpcIndex, UserIndexFront) Then
Call NpcAtacaUser(AtackerNpcIndex, UserIndexFront, tHeading)
End If
End If
Expand Down Expand Up @@ -1281,22 +1279,26 @@ Private Function EsEnemigo(ByVal NpcIndex As Integer, ByVal UserIndex As Integer

100 If NpcIndex = 0 Or UserIndex = 0 Then Exit Function

102 With NpcList(NpcIndex)
EsEnemigo = True

102 With NpcList(NpcIndex)
' Si el NPC tiene un atacante
104 If .flags.AttackedBy <> vbNullString Then
' Si el usuario actual es el atacante
106 EsEnemigo = (UserIndex = NameIndex(.flags.AttackedBy).ArrayIndex)
108 If EsEnemigo Then Exit Function
' Si no es el atacante, preguntamos si el NPC puede atacarlo
109 EsEnemigo = CanAttackNotOwner(NpcIndex, UserIndex)
End If

110 Select Case .flags.AIAlineacion
Case e_Alineacion.Real
112 EsEnemigo = (Status(UserIndex) Mod 2) <> 1
112 EsEnemigo = EsEnemigo And (Status(UserIndex) Mod 2) <> 1

114 Case e_Alineacion.Caos
116 EsEnemigo = (Status(UserIndex) Mod 2) <> 0
116 EsEnemigo = EsEnemigo And (Status(UserIndex) Mod 2) <> 0

118 Case e_Alineacion.ninguna
120 EsEnemigo = True
' Ok. No hay nada especial para hacer, cualquiera puede ser enemigo!

End Select
Expand Down
1 change: 1 addition & 0 deletions Codigo/Admin.bas
Original file line number Diff line number Diff line change
Expand Up @@ -93,6 +93,7 @@ Public IntervaloMagiaGolpe As Long
Public IntervaloGolpeMagia As Long
Public IntervaloUserPuedeCastear As Long
Public IntervaloTrabajarExtraer As Long
Public IntervaloNpcOwner As Long

Public IntervaloTrabajarConstruir As Long

Expand Down
1 change: 1 addition & 0 deletions Codigo/Declares.bas
Original file line number Diff line number Diff line change
Expand Up @@ -2553,6 +2553,7 @@ Public Type t_NPCFlags
' UseAINow As Boolean No se usa, borrar de la DB!!!!
Sound As Integer
AttackedBy As String
AttackedTime As Long
AttackedFirstBy As String
backup As Byte
RespawnOrigPos As Byte
Expand Down
1 change: 1 addition & 0 deletions Codigo/EffectProvoked.cls
Original file line number Diff line number Diff line change
Expand Up @@ -68,6 +68,7 @@ Public Sub Setup(ByVal SourceIndex As Integer, ByVal SourceType As e_ReferenceTy
If SourceType = eUser Then
Call SetUserRef(NpcList(TargetIndex).TargetUser, SourceIndex)
NpcList(TargetIndex).flags.AttackedBy = UserList(SourceIndex).name
NpcList(TargetIndex).flags.AttackedTime = GetTickCount
Else
Call SetNpcRef(NpcList(TargetIndex).TargetNPC, SourceIndex)
End If
Expand Down
3 changes: 2 additions & 1 deletion Codigo/FileIO.bas
Original file line number Diff line number Diff line change
Expand Up @@ -2094,7 +2094,7 @@ Public Sub CargarMapaFormatoCSM(ByVal map As Long, ByVal MAPFl As String)
End If
Else
' Lo guardo en los logs + aparece en el Debug.Print
310 Call TraceError(404, "NPC no existe en los .DAT's o está mal dateado. Posicion: " & Map & "-" & NPCs(i).x & "-" & NPCs(i).y, "ES.CargarMapaFormatoCSM")
310 Call TraceError(404, "NPC no existe en los .DAT's o está mal dateado. Posicion: " & map & "-" & NPCs(i).X & "-" & NPCs(i).Y, "ES.CargarMapaFormatoCSM")
End If
End If
312 Next i
Expand Down Expand Up @@ -2701,6 +2701,7 @@ Sub LoadIntervalos()
'TODO : Agregar estos intervalos al form!!!
206 IntervaloMagiaGolpe = val(Lector.GetValue("INTERVALOS", "IntervaloMagiaGolpe"))
208 IntervaloGolpeMagia = val(Lector.GetValue("INTERVALOS", "IntervaloGolpeMagia"))
209 IntervaloNpcOwner = val(Lector.GetValue("INTERVALOS", "IntervaloNpcOwner", "10000"))

'frmMain.tLluvia.Interval = val(Lector.GetValue("INTERVALOS", "IntervaloPerdidaStaminaLluvia"))
'FrmInterv.txtIntervaloPerdidaStaminaLluvia.Text = frmMain.tLluvia.Interval
Expand Down
1 change: 1 addition & 0 deletions Codigo/FrmInterv.frm
Original file line number Diff line number Diff line change
Expand Up @@ -896,6 +896,7 @@ Private Sub Command2_Click()
140 Call WriteVar(IniPath & "intervalo.ini", "INTERVALOS", "IntervaloTrabajarExtraer", CStr(IntervaloTrabajarExtraer))
142 Call WriteVar(IniPath & "intervalo.ini", "INTERVALOS", "IntervaloTrabajarConstruir", CStr(IntervaloTrabajarConstruir))
144 Call WriteVar(IniPath & "intervalo.ini", "INTERVALOS", "IntervaloUserPuedeAtacar", CStr(IntervaloUserPuedeAtacar))
145 Call WriteVar(IniPath & "intervalo.ini", "INTERVALOS", "IntervaloNpcOwner", CStr(IntervaloNpcOwner))
'Call WriteVar(IniPath & "intervalo.ini", "INTERVALOS", "IntervaloPerdidaStaminaLluvia", frmMain.tLluvia.Interval)

146 MsgBox "Los intervalos se han guardado sin problemas"
Expand Down
6 changes: 5 additions & 1 deletion Codigo/GameLogic.bas
Original file line number Diff line number Diff line change
Expand Up @@ -324,7 +324,7 @@ Private Function CheckMapRestrictions(ByVal UserIndex As Integer, ByVal Map As I

146 If MapInfo(Map).MaxLevel <> 0 And .Stats.ELV >= MapInfo(Map).MaxLevel Then
148 If .flags.UltimoMensaje <> 106 Then
150 Call WriteConsoleMsg(UserIndex, "Sólo los personajes inferiores a nivel " & MapInfo(Map).MaxLevel & " pueden entrar a este mapa.", e_FontTypeNames.FONTTYPE_INFO)
150 Call WriteConsoleMsg(UserIndex, "Sólo los personajes inferiores a nivel " & MapInfo(map).MaxLevel & " pueden entrar a este mapa.", e_FontTypeNames.FONTTYPE_INFO)
152 .flags.UltimoMensaje = 106
End If
Exit Function
Expand Down Expand Up @@ -1587,6 +1587,10 @@ Sub LookatTile(ByVal UserIndex As Integer, ByVal Map As Integer, ByVal X As Inte
End If

End If

If EsGM(UserIndex) And GetOwnedBy(TempCharIndex) <> 0 Then
estatus = estatus & " | Owned by " & NpcList(TempCharIndex).flags.AttackedBy
End If

456 estatus = estatus & ">"

Expand Down
79 changes: 49 additions & 30 deletions Codigo/MODULO_NPCs.bas
Original file line number Diff line number Diff line change
Expand Up @@ -319,6 +319,7 @@ Sub ResetNpcFlags(ByVal NpcIndex As Integer)
102 .AfectaParalisis = 0
104 .AguaValida = 0
106 .AttackedBy = vbNullString
107 .AttackedTime = 0
108 .AttackedFirstBy = vbNullString
112 .backup = 0
116 .Domable = 0
Expand Down Expand Up @@ -1674,6 +1675,7 @@ Sub DoFollow(ByVal NpcIndex As Integer, ByVal UserName As String)
player = NameIndex(username)
If IsValidUserRef(player) Then
114 .flags.AttackedBy = username
115 .flags.AttackedTime = GetTickCount
116 .targetUser = player
118 .flags.Follow = True
120 Call SetMovement(NpcIndex, e_TipoAI.NpcDefensa)
Expand Down Expand Up @@ -2134,36 +2136,26 @@ UserCanAttackNpc.TurnPK = False
End If

If NpcList(NpcIndex).flags.team = 0 Then
If NpcList(NpcIndex).flags.AttackedBy <> "" Then
Dim CurrentOwner As t_UserReference
Dim CurrentOwnerIndex As Integer
Dim AttackedNpcIndex As Integer

CurrentOwner = NameIndex(NpcList(NpcIndex).flags.AttackedBy)
If IsValidUserRef(CurrentOwner) Then
CurrentOwnerIndex = CurrentOwner.ArrayIndex

If CurrentOwnerIndex <> UserIndex And IsValidNpcRef(UserList(CurrentOwnerIndex).flags.NPCAtacado) Then
If UserList(CurrentOwnerIndex).flags.NPCAtacado.ArrayIndex = NpcIndex And _
UserList(CurrentOwnerIndex).flags.Muerto = 0 And _
(Status(CurrentOwnerIndex) = Ciudadano Or Status(CurrentOwnerIndex) = Armada Or Status(CurrentOwnerIndex) = Consejo) And _
Distancia(UserList(CurrentOwnerIndex).pos, UserList(UserIndex).pos) <= 12 And _
(UserList(UserIndex).GuildIndex = 0 Or UserList(UserIndex).GuildIndex <> UserList(CurrentOwnerIndex).GuildIndex) And _
(UserList(UserIndex).Grupo.EnGrupo = False Or UserList(UserIndex).Grupo.id <> UserList(CurrentOwnerIndex).Grupo.id) Then


If UserList(UserIndex).flags.Seguro Then
UserCanAttackNpc.result = eRemoveSafeCitizenNpc
Exit Function
Else
UserCanAttackNpc.TurnPK = True
UserCanAttackNpc.CanAttack = True
UserCanAttackNpc.result = eAttackCitizenNpc
Exit Function
End If
End If
End If
End If
Dim CurrentOwnerIndex As Integer: CurrentOwnerIndex = GetOwnedBy(NpcIndex)
If CurrentOwnerIndex <> 0 Then
If CurrentOwnerIndex <> UserIndex And IsValidNpcRef(UserList(CurrentOwnerIndex).flags.NPCAtacado) Then
If UserList(CurrentOwnerIndex).flags.NPCAtacado.ArrayIndex = NpcIndex And _
UserList(CurrentOwnerIndex).flags.Muerto = 0 And _
(Status(CurrentOwnerIndex) = Ciudadano Or Status(CurrentOwnerIndex) = Armada Or Status(CurrentOwnerIndex) = consejo) And _
(UserList(UserIndex).GuildIndex = 0 Or UserList(UserIndex).GuildIndex <> UserList(CurrentOwnerIndex).GuildIndex) And _
(UserList(UserIndex).Grupo.EnGrupo = False Or UserList(UserIndex).Grupo.Id <> UserList(CurrentOwnerIndex).Grupo.Id) Then

If UserList(UserIndex).flags.Seguro Then
UserCanAttackNpc.Result = eRemoveSafeCitizenNpc
Exit Function
Else
UserCanAttackNpc.TurnPK = True
UserCanAttackNpc.CanAttack = True
UserCanAttackNpc.Result = eAttackCitizenNpc
Exit Function
End If
End If
End If
End If
End If
End If
Expand Down Expand Up @@ -2386,3 +2378,30 @@ Public Function GetDefenseBonus(ByVal NpcIndex As Integer) As Integer
GetDefenseBonus = NpcList(NpcIndex).Modifiers.DefenseBonus
End Function

' Retorna el usuario que esta atacando al NPC actualmente (medido con tiempo)
Public Function GetOwnedBy(ByVal NpcIndex As Integer) As Integer
GetOwnedBy = 0
With NpcList(NpcIndex).flags
If .AttackedBy = vbNullString Then Exit Function
If GetTickCount - .AttackedTime > IntervaloNpcOwner Then Exit Function
Dim Attacker As t_UserReference: Attacker = NameIndex(.AttackedBy)
If Not IsValidUserRef(Attacker) Then Exit Function
GetOwnedBy = Attacker.ArrayIndex
End With
End Function

' Retorna si un NPC puede atacar un usuario diferente al que lo esta atacando
Public Function CanAttackNotOwner(ByVal NpcIndex As Integer, ByVal UserIndex As Integer) As Boolean
Dim AttackResult As t_AttackInteractionResult
AttackResult = UserCanAttackNpc(UserIndex, NpcIndex)

' Si el usuario puede atacar al NPC
If AttackResult.CanAttack Then
' Lo atacamos solo si puede atacar sin hacerse PK (no lo forzamos a hacerse PK)
CanAttackNotOwner = AttackResult.TurnPK
Else
' En caso que el usuario no pueda atacar al NPC, este debe ignorarlo a el
' Excepto que no pueda atacar por los siguientes motivos: esta montado, esta fuera de su campo de vision
CanAttackNotOwner = AttackResult.Result = eMounted Or AttackResult.Result = eOutOfRange
End If
End Function
5 changes: 4 additions & 1 deletion Codigo/Modulo_UsUaRiOs.bas
Original file line number Diff line number Diff line change
Expand Up @@ -1934,7 +1934,10 @@ Sub NPCAtacado(ByVal NpcIndex As Integer, ByVal UserIndex As Integer, Optional B
104 If Not IsSet(NpcList(npcIndex).flags.StatusMask, eTaunted) And NpcList(npcIndex).Movement <> Estatico And NpcList(npcIndex).flags.AttackedFirstBy = vbNullString Then
106 Call SetUserRef(NpcList(npcIndex).TargetUser, UserIndex)
108 NpcList(NpcIndex).Hostile = 1
110 If AffectsOwner Then NpcList(NpcIndex).flags.AttackedBy = UserList(UserIndex).name
110 If AffectsOwner Then
NpcList(NpcIndex).flags.AttackedBy = UserList(UserIndex).name
NpcList(NpcIndex).flags.AttackedTime = GetTickCount
End If
End If

'Guarda el NPC que estas atacando ahora.
Expand Down
2 changes: 1 addition & 1 deletion Codigo/Protocol.bas
Original file line number Diff line number Diff line change
Expand Up @@ -3294,7 +3294,7 @@ Private Sub HandleWorkLeftClick(ByVal UserIndex As Integer)
Exit Sub
End If

564 If LenB(NpcList(tN).flags.AttackedBy) <> 0 Then
564 If GetOwnedBy(tN) <> 0 Then
566 Call WriteConsoleMsg(UserIndex, "No puedes domar una criatura que esta luchando con un jugador.", e_FontTypeNames.FONTTYPE_INFO)
Exit Sub
End If
Expand Down
2 changes: 2 additions & 0 deletions Codigo/SistemaCombate.bas
Original file line number Diff line number Diff line change
Expand Up @@ -2081,6 +2081,7 @@ Sub AllMascotasAtacanUser(ByVal victim As Integer, ByVal Maestro As Integer)
If IsValidNpcRef(.MascotasIndex(iCount)) Then
108 If IsSet(NpcList(mascotaIndex).flags.BehaviorFlags, e_BehaviorFlags.eAttackUsers) Then
110 NpcList(mascotaIndex).flags.AttackedBy = UserList(victim).Name
111 NpcList(mascotaIndex).flags.AttackedTime = GetTickCount
112 Call SetUserRef(NpcList(mascotaIndex).TargetUser, victim)
114 Call SetMovement(mascotaIndex, e_TipoAI.NpcDefensa)
116 NpcList(mascotaIndex).Hostile = 0
Expand Down Expand Up @@ -2126,6 +2127,7 @@ Public Sub AllMascotasAtacanNPC(ByVal NpcIndex As Integer, ByVal UserIndex As In
110 Call SetNpcRef(.TargetNPC, NpcIndex)
112 Call SetMovement(mascotaIdx, e_TipoAI.NpcAtacaNpc)
NpcList(NpcIndex).flags.AttackedBy = UserList(UserIndex).name
NpcList(NpcIndex).flags.AttackedTime = GetTickCount
Call SetNpcRef(UserList(UserIndex).flags.NPCAtacado, NpcIndex)
End If
End With
Expand Down
12 changes: 7 additions & 5 deletions Codigo/clsIniManager.cls
Original file line number Diff line number Diff line change
Expand Up @@ -371,9 +371,10 @@ End Sub
'
' @param Main The name of the main section in which we will be searching.
' @param key The key of the value we are looking for.
' @param DefaultValue Default value if key is not found.
' @returns The value asociated with the given key under the requeted main section of the INI file or a null string if it's not found.

Public Function GetValue(ByVal Main As String, ByVal Key As String)
Public Function GetValue(ByVal Main As String, ByVal key As String, Optional ByVal DefaultValue As String = "") As String

On Error GoTo GetValue_Err

Expand All @@ -385,7 +386,6 @@ Public Function GetValue(ByVal Main As String, ByVal Key As String)
'**************************************************************
Dim i As Long
Dim j As Long
Dim retval As String

'Search for the main node
i = FindMain(UCase$(Main))
Expand All @@ -396,9 +396,11 @@ Public Function GetValue(ByVal Main As String, ByVal Key As String)
j = FindKey(fileData(i), UCase$(Key))

'If we found it we return it
If j >= 0 Then retval = fileData(i).values(j).Value

GetValue = retval
If j >= 0 Then
GetValue = fileData(i).values(j).Value
Else
GetValue = DefaultValue
End If

End If

Expand Down
1 change: 1 addition & 0 deletions intervalos.ini
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@ IntervaloFrio=75
IntervaloWAVFX=190
IntervaloMover=200
IntervaloNpcAI=150
IntervaloNpcOwner=10000
IntervaloTrabajarExtraer=3000
IntervaloTrabajarConstruir=500
IntervaloWS=180 'Cantidad de minutos
Expand Down

0 comments on commit ace1a82

Please sign in to comment.